You are on page 1of 50

Security Assessment

MXSamurai
Oct 5th, 2021
MXSamurai Security Assessment

Table of Contents
Summary

Overview
Project Summary
Audit Summary
Vulnerability Summary
Audit Scope

Findings
MXS-01 : Centralization Risk
MXS-02 : Anti-bot Never Enabled
MXS-03 : Incorrect Error Message
MXS-04 : Third Party Dependencies
MXS-05 : Lack of Input Validation
MXS-06 : Redundant `receive` Method
MXS-07 : Variable Could Be Declared as Constant
MXS-08 : Variable Could Be Declared as Immutable
MXS-09 : Redundant Code
MXS-10 : Unbounded Loop
MXS-11 : Proper Usage of `public` And `external` Type
MXS-12 : Lack of Event Emitting
VCK-01 : Incorrect Vested Amount Calculation
VCK-02 : Centralization Risk
VCK-03 : Potential Reentrancy Risk
VCK-04 : Lack of Return Value Handling
VCK-05 : Inefficient `import`
VCK-06 : Lack of Error Messages
VCK-07 : Variable Could Be Declared as Immutable
VCK-08 : Proper Usage of `public` And `external` Type
VCK-09 : Unused State Variable
VCK-10 : Unused Modifier
VRC-01 : Centralization Risk
VRC-02 : Potential Reentrancy Risk
VRC-03 : Lack of Return Value Handling
VRC-04 : Inefficient `import`
VRC-05 : Event Optimization
MXSamurai Security Assessment

VRC-06 : Variable Could Be Declared as Immutable


VRC-07 : Proper Usage of `public` And `external` Type

Appendix

Disclaimer

About
MXSamurai Security Assessment

Summary
This report has been prepared for MXSamurai to discover issues and vulnerabilities in the source code of
the MXSamurai project as well as any contract dependencies that were not part of an officially recognized
library. A comprehensive examination has been performed, utilizing Static Analysis and Manual Review
techniques.

The auditing process pays special attention to the following considerations:

Testing the smart contracts against both common and uncommon attack vectors.
Assessing the codebase to ensure compliance with current best practices and industry standards.
Ensuring contract logic meets the specifications and intentions of the client.
Cross referencing contract structure and implementation against similar smart contracts produced
by industry leaders.
Thorough line-by-line manual review of the entire codebase by industry experts.

The security assessment resulted in findings that ranged from critical to informational. We recommend
addressing these findings to ensure a high level of security standards and industry practices.
We suggest
recommendations that could better serve the project from the security perspective:

Enhance general coding practices for better structures of source codes;


Add enough unit tests to cover the possible use cases;
Provide more comments per each function for readability, especially contracts that are verified in
public;
Provide more transparency on privileged activities once the protocol is live.
MXSamurai Security Assessment

Overview
Project Summary

Project Name MXSamurai

Platform Ethereum

Language Solidity

Codebase https://github.com/mx-samurai/mx-samurai-token

-710b149e5577a44679807ad3432f139cc8ed292a
Commit
-15918b08ca04c1447b2173ae6cd4949120e6f0e4

Audit Summary

Delivery Date Oct 05, 2021

Audit Methodology Static Analysis, Manual Review

Key Components MXSToken.sol, Vesting.sol, VestingRouter.sol

Vulnerability Summary

Vulnerability Level Total Pending Declined Acknowledged Partially Resolved Resolved

Critical 1 0 0 0 0 1

Major 3 0 0 3 0 0

Medium 0 0 0 0 0 0

Minor 9 0 0 0 0 9

Informational 16 0 0 1 2 13

Discussion 0 0 0 0 0 0
MXSamurai Security Assessment

Audit Scope

ID File SHA256 Checksum


MXSamurai Security Assessment

Review Notes

Dependencies

There are a few depending injection contracts or addresses in the current project:

IUniswapV2Router02 for the contract MXSToken ;

mxsToken for the contract Vesting ;

mxsToken for the contract VestingRouter ;

We assume these contracts or addresses are valid and non-vulnerable actors and implementing proper
logic to collaborate with the current project.

Privileged Roles

In the contract MXSToken , the role owner has authority over the following functions:

MXSToken.excludeFromReward() to exclude an account from receiving rewards;

MXSToken.includeInReward() to allow an account to receive rewards;

MXSToken.excludedFromFee() to exclude an account from paying fees;

MXSToken.includeInFee() to require an account to pay fees;

MXSToken.excludeFromBlockLimit() (the functionality of _isExcludedFromBlockLimit is not

shown within the contract);


MXSToken.includeInBlockLimit() (the functionality of _isExcludedFromBlockLimit is not shown

within the contract);


MXSToken.setTaxFeePercent() to set the fee percentage of the tax;

MXSToken.setCommunityFeePercent() to set the fee percentage of the community;

MXSToken.setMaxTxAmount() to set the maximum transaction amount;

MXSToken.setCommunityWallet(address) to set a new community wallet address;

MXSToken.setTradingStartTime() to set a new trading start time;

MXSToken.allowPreTrading(address, bool) to determine if an account can do presale trading.

In the contract Vesting , the role owner has the authority over the following functions:

Vesting.release() to release vested tokens;

Vesting.revoke() to release vested tokens the revoke the vesting contract.

In the contract VestingRouter , the role owner has the authority over the following function:

VestingRouter.createVesting() to create a new vesting contract using tokens in the

VestingRouter contract;
MXSamurai Security Assessment

VestingRouter.revoke() to revoke a vesting contract.

To improve the trustworthiness of the project, dynamic runtime updates in


the project should be notified to
the community. Any plan to implement
aforementioned functions must be also considered to adopt
Timelock with reasonable delay to allow the user to withdraw their funds, Multisig
with community-selected
3-party independent co-signers, and/or DAO with
transparent governance with the project's community in
the project to manage
sensitive role accesses.
MXSamurai Security Assessment

Findings

Critical 1 (3.45%)
Major 3 (10.34%)

29 Medium
Minor
0 (0.00%)
9 (31.03%)
Total Issues
Informational 16 (55.17%)
Discussion 0 (0.00%)

ID Title Category Severity Status

Centralization /
MXS-01 Centralization Risk Major Acknowledged
Privilege

MXS-02 Anti-bot Never Enabled Logical Issue Minor Resolved

MXS-03 Incorrect Error Message Logical Issue Minor Resolved

MXS-04 Third Party Dependencies Control Flow Minor Resolved

MXS-05 Lack of Input Validation Volatile Code Minor Resolved

MXS-06 Redundant receive Method Logical Issue Minor Resolved

MXS-07 Variable Could Be Declared as Constant Gas Optimization Informational Resolved

Variable Could Be Declared as


MXS-08 Gas Optimization Informational Resolved
Immutable

MXS-09 Redundant Code Logical Issue Informational Resolved

MXS-10 Unbounded Loop Logical Issue Informational Acknowledged

Proper Usage of public And


MXS-11 Coding Style Informational Resolved
external Type

MXS-12 Lack of Event Emitting Gas Optimization Informational Resolved

VCK-01 Incorrect Vested Amount Calculation Logical Issue Critical Resolved

Centralization /
VCK-02 Centralization Risk Major Acknowledged
Privilege
MXSamurai Security Assessment

ID Title Category Severity Status

VCK-03 Potential Reentrancy Risk Logical Issue Minor Resolved

VCK-04 Lack of Return Value Handling Volatile Code Minor Resolved

VCK-05 Inefficient import Gas Optimization Informational Partially Resolved

VCK-06 Lack of Error Messages Coding Style Informational Resolved

Variable Could Be Declared as


VCK-07 Gas Optimization Informational Resolved
Immutable

Proper Usage of public And


VCK-08 Coding Style Informational Resolved
external Type

VCK-09 Unused State Variable Coding Style Informational Resolved

VCK-10 Unused Modifier Coding Style Informational Resolved

Centralization /
VRC-01 Centralization Risk Major Acknowledged
Privilege

VRC-02 Potential Reentrancy Risk Logical Issue Minor Resolved

VRC-03 Lack of Return Value Handling Volatile Code Minor Resolved

VRC-04 Inefficient import Gas Optimization Informational Partially Resolved

VRC-05 Event Optimization Language Specific Informational Resolved

Variable Could Be Declared as


VRC-06 Gas Optimization Informational Resolved
Immutable

Proper Usage of public And


VRC-07 Coding Style Informational Resolved
external Type
MXSamurai Security Assessment

MXS-01 | Centralization Risk

Category Severity Location Status

Centralization / MXSToken.sol: 401, 405, 409, 413, 417, 421, 425, 429, 433, 437,
Major Acknowledged
Privilege 443, 180, 189, 233

Description
With the modifier onlyOwner , the owner role has the authority over the following functions:

MXSToken.excludeFromReward(address) to exclude an account from receiving rewards;

MXSToken.includeInReward(address) to allow an account to receive rewards;

MXSToken.excludedFromFee(address) to exclude an account from paying fees;

MXSToken.includeInFee(address) to require an account to pay fees;

MXSToken.excludeFromBlockLimit(address) (the functionality of _isExcludedFromBlockLimit is

not shown within the contract);


MXSToken.includeInBlockLimit(address) (the functionality of _isExcludedFromBlockLimit is not

shown within the contract);


MXSToken.setTaxFeePercent(uint256) to set the fee percentage of the tax;

MXSToken.setCommunityFeePercent(uint256) to set the fee percentage of the community;

MXSToken.setMaxTxAmount(uint256) to set the maximum transaction amount;

MXSToken.setCommunityWallet(address) to set a new community wallet address;

MXSToken.setTradingStartTime(uint256) to set a new trading start time;

MXSToken.allowPreTrading(address, bool) to determine if an account can do pre sale trading.

Also, the amount of transfers related to the owner address (transfer from owner or to owner ) is not
restricted by _maxTxAmount .

Any compromise to the owner account may allow the hacker to take advantage of this and manipulate the
project.

Recommendation
We advise the client to carefully manage the owner account's private key to avoid any potential risks of
being hacked. Additionally, we recommend the client to enforce proper thresholds for the aforementioned
quantities.

In general, we strongly recommend centralized privileges or roles in the protocol to be improved via a
decentralized mechanism or smart-contract-based accounts with enhanced security practices, e.g.,
MXSamurai Security Assessment

Multisignature wallets.

Indicatively, here is some feasible suggestions that would also mitigate the potential risk at the different
level in term of short-term and long-term:

Time-lock with reasonable latency, e.g., 48 hours, for awareness on privileged operations;
Assignment of privileged roles to multi-signature wallets to prevent a single point of failure due to the
private key;
Introduction of a DAO/governance/voting module to increase transparency and user involvement.

Alleviation
N/A
MXSamurai Security Assessment

MXS-02 | Anti-bot Never Enabled

Category Severity Location Status

Logical Issue Minor MXSToken.sol: 60 Resolved

Description
The variable antibotEnabled is initialized as false and there is no method that can change it, so it will
always be false . The contract antiBot will never be used.

Recommendation
We advise the team to consider if this feature should be enabled.

Alleviation
The client heeded our advice and resolved this issue by adding the function toggleAntiBot() to change
the status of antibotEnabled with onlyOwner() . The changes are reflected in the commit
710b149e5577a44679807ad3432f139cc8ed292a .

[Update on Oct 5, 2021]: In the contract MXSToken , the client removed all the code snippets related to
IFTPAntiBot. For example,

12 interface IFTPAntiBot {

13 function scanAddress(address _address, address _safeAddress, address _origin)


external returns (bool);

14 function registerBlock(address _recipient, address _sender) external;

15 }

59 IFTPAntiBot private antiBot;

60 bool public antibotEnabled = false;

The changes are reflected in the commit 15918b08ca04c1447b2173ae6cd4949120e6f0e4 .


MXSamurai Security Assessment

MXS-03 | Incorrect Error Message

Category Severity Location Status

Logical Issue Minor MXSToken.sol: 190 Resolved

Description
The error message in require(_isExcludedFromReward[account], "Account is already excluded")
does not describe the error correctly.

Recommendation
The message "Account is already excluded" should be changed to "Account is not excluded" .

Alleviation
The client heeded our advice and resolved the issue by changing the error message to "Account is not
excluded". The changes are reflected in the commit c76eaa2c715a9e629df5d9752027e0fe7e5c2bdc .
MXSamurai Security Assessment

MXS-04 | Third Party Dependencies

Category Severity Location Status

Control Flow Minor MXSToken.sol: 72, 226, 229, 258 Resolved

Description
The contract interacts with the third-party protocols UniswapV2 and antiBot
(0x590C2B20f7920A2D21eD32A21B616906b4209A43).

For example,

72 uniswapV2Pair =
IUniswapV2Factory(_uniswapV2Router.factory()).createPair(address(this),
_uniswapV2Router.WETH());

224 if(antibotEnabled) {

225 if(from == address(uniswapV2Router)){

226 require(!antiBot.scanAddress(to, from, tx.origin), "Beep Beep Boop,


You're a piece of poop");

227 }

228 if(to == address(uniswapV2Router)){

229 require(!antiBot.scanAddress(from, to, tx.origin), "Beep Beep Boop,


You're a piece of poop");

230 }

231 }

257 if(antibotEnabled) {

258 try antiBot.registerBlock(from, to) {} catch {}

259 }

The scope of the audit would treat these third-party entities as black boxes and assume their functional
correctness. However, the third parties may be compromised, which would lead to assets loss or stolen.

Recommendation
We advise the team to constantly monitor the statuses of third parties to mitigate the side effects when
unexpected activities are observed.

Alleviation
MXSamurai Security Assessment

The client added try/catch statements for error handling of external calls.
These changes are reflected in
the commit 9e347b0cf4612933ea7bf0be63084fcf8f493c10 .

The client removed all the code snippets related to the IFTPAntiBot. The changes are reflected in the
commit 15918b08ca04c1447b2173ae6cd4949120e6f0e4 . The findings of the aforementioned L226, L229
and L258 should be ignored.
MXSamurai Security Assessment

MXS-05 | Lack of Input Validation

Category Severity Location Status

Volatile Code Minor MXSToken.sol: 421, 425, 429 Resolved

Description
The functions MXSToken.setTaxFeePercent() , MXSToken.setCommunityFeePercent() and
MXSToken.setMaxTxAmount() update important parameters in the project. The input value should be

validated before updates are made for them. For example, _taxFee should never be greater than 100.

Recommendation
We recommend adding input validations for the aforementioned functions to avoid human mistakes.

Alleviation
The client heeded our advice and resolved the issue by setting taxFee < 20 , communityFee < 20 and
maxTxAmount > 0 . These changes are reflected in the commit

963bfb7f9f3c0dbf29d68d56328ea93d9424a02e .
MXSamurai Security Assessment

MXS-06 | Redundant receive Method

Category Severity Location Status

Logical Issue Minor MXSToken.sol: 450 Resolved

Description
The contract MXSToken does not have any explicitly implemented method to ask other contracts to send
ETH to this contract, nor does it provide a method to withdraw ETH from the contract account, so it should
not provide the receive() method to receive ETH from other accounts.

Recommendation
We recommend removing the function receive() if the contract does not need to receive ETH from other
accounts.

Alleviation
The client heeded our advice and resolved the issue by removing the function receive() . The changes are
reflected in the commit 963bfb7f9f3c0dbf29d68d56328ea93d9424a02e .
MXSamurai Security Assessment

MXS-07 | Variable Could Be Declared as Constant

Category Severity Location Status

Gas Optimization Informational MXSToken.sol: 34, 39~41, 60 Resolved

Description
Variables _tTotal , _name , _symbol , _decimals and antiBot could be declared as constant since these
state variables are never to be changed.

Recommendation
We recommend declaring the aforementioned variables as constant .

Alleviation
The client heeded our advice and resolved this issue by declaring aforementioned variables as constant .
The changes are reflected in the commit 8cf938e22fc01cee00eb2dc48de67c68c9fc4a7e .
MXSamurai Security Assessment

MXS-08 | Variable Could Be Declared as Immutable

Category Severity Location Status

Gas Optimization Informational MXSToken.sol: 59 Resolved

Description
The variable antiBot assigned in the constructor can be declared as immutable . Immutable state
variables can be assigned during contract creation but will remain constant throughout the lifetime of a
deployed contract. A big advantage of immutable variables is that reading them is significantly cheaper
than reading from regular state variables since will not be stored in storage. Still, values will directly insert
the values into the runtime code.

Recommendation
We recommend declaring the aforementioned variable as immutable .

Alleviation
The client added the function MXSToken.assignAntiBot() to update the value of antiBot in the commit
33a4eb835e36c0e9103ffe3d0906e14166e86271 , so it should not be declared as immutable now.
MXSamurai Security Assessment

MXS-09 | Redundant Code

Category Severity Location Status

Logical Issue Informational MXSToken.sol: 270~271 Resolved

Description
The condition !_isExcludedFromReward[sender] && !_isExcludedFromReward[recipient] , which can be
included in else , is redundant.

Recommendation
The following code can be removed:

270 ... else if (!_isExcludedFromReward[sender] && !_isExcludedFromReward[recipient]) {

271 _transferStandard(sender, recipient, amount);

272 } ...

Alleviation
The client heeded our advice and resolved the issue by removing the aforementioned code. The changes
are reflected in the commit 6ba5ba080cb12008ef1990bc637d2b68187239a5 .
MXSamurai Security Assessment

MXS-10 | Unbounded Loop

Category Severity Location Status

Logical Issue Informational MXSToken.sol: 191, 356 Acknowledged

Description
The for loop within the functions MXSToken.includeInReward(address) and
MXSToken._getCurrentSupply() takes _excluded.length as the maximal iteration times. If the size of the

_excluded array is very large, it could exceed the gas limit to execute

MXSToken.includeInReward(address) and MXSToken._getCurrentSupply() . In this case, the contract

might suffer from DoS (Denial of Service).

Recommendation
We recommend the team review the design and ensure this would not cause loss to the project.

Alleviation
N/A
MXSamurai Security Assessment

MXS-11 | Proper Usage of public And external Type

Category Severity Location Status

Coding MXSToken.sol: 91, 95, 99, 103, 107, 112, 117, 121, 126, 132, 137, 142, 14
Informational Resolved
Style 6, 150, 154, 163, 180, 397, 401, 405, 409, 413, 417, 433, 437, 443

Description
The functions which are never called internally within the contract should have external visibility. For
example,:

MXSToken.name()

MXSToken.symbol()

MXSToken.decimals()

MXSToken.totalSupply()

MXSToken.balanceOf(address)

MXSToken.transfer(address, uint256)

MXSToken.allowance(address, address)

MXSToken.approve(address, uint256)

MXSToken.transferFrom(address, address, uint256)

MXSToken.increaseAllowance(address, uint256)

MXSToken.decreaseAllowance(address, uint256)

MXSToken.isExcludedFromReward(address)

MXSToken.totalFees()

MXSToken.totalCommunityRewards()

MXSToken.deliver(uint256)

MXSToken.reflectionFromToken(uint256, bool)

MXSToken.excludeFromReward(address)

MXSToken.isExcludedFromFee(address)

MXSToken.excludeFromFee(address)

MXSToken.includeInFee(address)

MXSToken.isExcludedFromBlockLimit(address)

MXSToken.excludeFromBlockLimit(address)

MXSToken.includeInBlockLimit(address)

MXSToken.setCommunityWallet(address)

MXSToken.setTradingStartTime(uint256)

MXSToken.allowPreTrading(address, bool)
MXSamurai Security Assessment

Recommendation
We advise changing the visibility of the aforementioned functions to external .

Alleviation
The client heeded our advice and resolved the issues by changing the visibilities of functions at the
aforementioned lines to external . These changes are reflected in the commit
e6563341d1ec49daeb006614e45cf446f9b48431 .
MXSamurai Security Assessment

MXS-12 | Lack of Event Emitting

Category Severity Location Status

Gas Optimization Informational MXSToken.sol: 421, 425, 429, 433, 437, 443, 180, 189, 401~405 Resolved

Description
The functions that affect the status of sensitive variables should emit events for better tracking contract
status. For example:

MXSToken.excludeFromReward(address)

MXSToken.includeInReward(address)

MXSToken.excludeFromFee(address)

MXSToken.includeInFee(address)

MXSToken.setTaxFeePercent(uint256)

MXSToken.setCommunityFeePercent(uint256)

MXSToken.setMaxTxAmount(uint256)

MXSToken.setCommunityWallet(address)

MXSToken.setTradingStartTime(uint256)

MXSToken.allowPreTrading(address, bool)

Recommendation
We advise adding events for the aforementioned sensitive actions, and emitting the events within the
functions.

Alleviation
The client heeded our advice and resolved the issue by emitting aforementioned events. The change is
reflected in the commit 737f6681c634dea7e01f0632386cfdab78339e7b .
MXSamurai Security Assessment

VCK-01 | Incorrect Vested Amount Calculation

Category Severity Location Status

Logical Issue Critical Vesting.sol: 132 Resolved

Description
In the function Vesting.vestedAmount() , when block.timestamp >= start + duration the vested
amount is given by mxsToken.balanceOf(address(this)) :

128 function vestedAmount() public view returns (uint256) {

129 if (block.timestamp < cliff) {

130 return 0;

131 } else if (block.timestamp >= start + duration || revoked) {

132 uint256 vested = mxsToken.balanceOf(address(this));

133 // vesting is complete, allocate all tokens

134 return vested;


135 } else {

136 uint256 vested = initialAllocation * (block.timestamp - start) / duration;

137 return vested;


138 }

139 }

It is incorrect because mxsToken.balanceOf(address(this)) is the amount of token that can be released.

For example, if the initial allocation is 100 MXS with 50 MXS released and 50 MXS remaining in the
contract, then after the time start + duration the vested amount shows 50 and the releasable amount is
50 - 50 = 0:

121 function releasableAmount() public view returns (uint256) {

122 return vestedAmount() - released;

123 }

which means there is no releasable token. This is incorrect because only 50 out of 100 MXS has been
released.

Recommendation
We recommend correcting the calculation of the vested amount.

Alleviation
MXSamurai Security Assessment

The client heeded our advice and resolved the issues by adding the released to the
mxsToken.balanceOf(address(this)) to obtain the vested amount. The change is reflected in the commit

70f07ff66670521560d42145d92c8cfe3854460e .
MXSamurai Security Assessment

VCK-02 | Centralization Risk

Category Severity Location Status

Centralization / Privilege Major Vesting.sol: 79, 102 Acknowledged

Description
In the contract Vesting , the role owner has the authority over the following functions:

Vesting.release() to release vested tokens;

Vesting.revoke() to release vested tokens the revoke the vesting contract.

Any compromise to the owner account may allow the hacker to take advantage of this and manipulate the
vesting contract.

Recommendation
We advise the client to carefully manage the owner account's private key to avoid any potential risks of
being hacked.
In general, we strongly recommend centralized privileges or roles in the protocol to be
improved via a decentralized mechanism or smart-contract-based accounts with enhanced security
practices, e.g., Multisignature wallets.

Indicatively, here is some feasible suggestions that would also mitigate the potential risk at the different
level in term of short-term and long-term:

Time-lock with reasonable latency, e.g., 48 hours, for awareness on privileged operations;
Assignment of privileged roles to multi-signature wallets to prevent a single point of failure due to the
private key;
Introduction of a DAO/governance/voting module to increase transparency and user involvement.

Alleviation
N/A
MXSamurai Security Assessment

VCK-03 | Potential Reentrancy Risk

Category Severity Location Status

Logical Issue Minor Vesting.sol: 87, 102 Resolved

Description
The functions listed below contain state updates and event emissions after the external call, and
consequentially is vulnerable to potential reentrancy attacks:

_releaseTo(address target)

revoke()

Recommendation
We advise applying OpenZeppelin ReentrancyGuard library - nonReentrant modifier for the
aforementioned function to prevent reentrancy attacks.

Alleviation
The client heeded our advice and resolved the issues by importing and applying openzeppelin-
contracts/contracts/security/ReentrancyGuard.sol to prevent reentrancy attacks. The changes are

reflected in the commit e4c1285647b574cb512255ae212650ae4d99e0b2 .


MXSamurai Security Assessment

VCK-04 | Lack of Return Value Handling

Category Severity Location Status

Volatile Code Minor Vesting.sol: 90, 110, 160, 65 Resolved

Description
The function mxsToken.approve(address, uint256) and mxsToken.transfer(address, uint256) are not
void-returning functions. Ignore their return values, especially when their return value represent the status
of the transaction executions, might cause unexpected exceptions.

Recommendation
We recommend handling the return values of the aforementioned functions before continuing processing.

Alleviation
The client heeded our advice and resolved the issue by handling the return values of the aforementioned
functions before continuing processing. These changes are reflected in the commit
0fff2f5f4b7805254ad1250907b656cb6a5d5d0f .
MXSamurai Security Assessment

VCK-05 | Inefficient import

Category Severity Location Status

Gas Optimization Informational Vesting.sol: 3, 5 Partially Resolved

Description
The file Vesting.sol imports the ERC20 implementation by

3 import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

However, importing its interface IERC20 or implementing the necessary interface within the contract would
be good enough to make external calls.

Moreover, the imported file hardhat/console.sol is never used within the file Vesting.sol, so it can be
removed.

Recommendation
We recommend importing or implementing the aforementioned interface and removing the redundant
import statement to reduce the bytecode.

Alleviation
The client opted to consider our references and imported the interface instead. The change is reflected in
the commit e195134d2a3012038be3b37c38bc72310736572f .
MXSamurai Security Assessment

VCK-06 | Lack of Error Messages

Category Severity Location Status

Coding Style Informational Vesting.sol: 53, 54, 72, 80, 103, 104, 159 Resolved

Description
The require statement can be used to check for conditions and throw an exception if the condition is not
met. It is better to provide a string message containing details about the error that will be passed back to
the caller.

Recommendation
We advise refactoring the linked codes as below:

53 require(_beneficiary != address(0), "The beneficiary address is zero address");

54 require(_cliff <= _duration, "The cliff is larger than duration");

71 modifier onlyBeneficiary() {

72 require(msg.sender == beneficiary, "Sender must be beneficiary");

73 _;

74 }

79 function release() onlyOwner public returns(uint256 tokenAmount) {

80 require(block.timestamp >= cliff, "Cliff has not been reached yet");

81 tokenAmount = _releaseTo(beneficiary);

82 }

103 function revoke() onlyOwner public {

104 require(revokable, "It's not revokable");

105 require(!revoked, "It's already revoked");

158 function releaseForeignToken(ERC20 _token, uint256 amount) public onlyOwner {

159 require(_token != mxsToken, "The token is mxsToken");

160 _token.transfer(owner(), amount);

161 }

Alleviation
MXSamurai Security Assessment

The client heeded our advice and resolved the issue by adding the aforementioned error messages. These
changes are reflected in the commit 6c519f9d2885b7c67ce6bf4be00474ecc8bd1237 .
MXSamurai Security Assessment

VCK-07 | Variable Could Be Declared as Immutable

Category Severity Location Status

Gas Optimization Informational Vesting.sol: 19, 21, 23~25, 27, 32 Resolved

Description
The variables beneficiary , cliff , duration , lastTierChange , initialAllocation , revokable and
mxsToken assigned in the constructor can be declared as Immutable . Immutable state variables can be

assigned during contract creation but will remain constant throughout the lifetime of a deployed contract.
A big advantage of immutable variables is that reading them is significantly cheaper than reading from
regular state variables since will not be stored in storage. Still, values will directly insert the values into the
runtime code.

Recommendation
We recommend declaring the aforementioned variables as immutable .

Alleviation
The client heeded our advice and resolved this issue by declaring the aforementioned variables as
immutable . The change is reflected in the commit e5026b865847ac6e9365bff93889f3fb0c01d58d .
MXSamurai Security Assessment

VCK-08 | Proper Usage of public And external Type

Category Severity Location Status

Coding Style Informational Vesting.sol: 79, 102, 144, 151, 158 Resolved

Description
The functions which are never called internally within the contract should have external visibility. For
example,

Vesting.release()

Vesting.revoke()

Vesting.reflections()

Vesting.timeRemaining()

Vesting.releaseForeignToken(ERC20 _token, uint256 amount)

Recommendation
We advise changing the visibility of the aforementioned functions to external .

Alleviation
The client heeded our advice and resolved the issues by changing the visibilities of functions at the
aforementioned lines to external . These changes are reflected in the commit
8cbcc7f2ba00256b78996c90779bb334b91f7224 .
MXSamurai Security Assessment

VCK-09 | Unused State Variable

Category Severity Location Status

Coding Style Informational Vesting.sol: 61 Resolved

Description
The state variable lastTierChange is never used within the contract Vesting after the assignment.

Recommendation
We recommend removing the unused state variable if it is never needed.

Alleviation
The client heeded our advice and resolved the issue by removing the unused state variable
lastTierChange . The change is reflected in the commit 8174b90a257f3aa24b1cebc54b3d3d8e21b1ce53 .
MXSamurai Security Assessment

VCK-10 | Unused Modifier

Category Severity Location Status

Coding Style Informational Vesting.sol: 71 Resolved

Description
The modifier onlyBeneficiary is never used within the contract Vesting .

Recommendation
We recommend removing the unused modifier if it is never needed.

Alleviation
The client heeded our advice and resolved the issue by removing the modifier onlyBeneficiary . The
change is reflected in the commit 6c519f9d2885b7c67ce6bf4be00474ecc8bd1237 .
MXSamurai Security Assessment

VRC-01 | Centralization Risk

Category Severity Location Status

Centralization / Privilege Major VestingRouter.sol: 26, 72 Acknowledged

Description
In the contract VestingRouter , the role owner has the authority over the following function:

VestingRouter.createVesting() to create a new vesting contract using tokens in the

VestingRouter contract;

VestingRouter.revoke() to revoke a vesting contract.

Any compromise to the owner account may allow the hacker to take advantage of this and manipulate the
project.

Recommendation
We advise the client to carefully manage the owner account's private key to avoid any potential risks of
being hacked.
In general, we strongly recommend centralized privileges or roles in the protocol to be
improved via a decentralized mechanism or smart-contract-based accounts with enhanced security
practices, e.g., Multisignature wallets.

Indicatively, here is some feasible suggestions that would also mitigate the potential risk at the different
level in term of short-term and long-term:

Time-lock with reasonable latency, e.g. 48 hours, for awareness on privileged operations;
Assignment of privileged roles to multi-signature wallets to prevent a single point of failure due to the
private key;
Introduction of a DAO/governance/voting module to increase transparency and user involvement.

Alleviation
N/A
MXSamurai Security Assessment

VRC-02 | Potential Reentrancy Risk

Category Severity Location Status

Logical Issue Minor VestingRouter.sol: 26 Resolved

Description
The function VestingRouter.createVesting(address, uint256, uint256, uint256, bool) contains
state updates and event emission after the external call, and consequentially is vulnerable to potential
reentrancy attacks.

Recommendation
We advise applying OpenZeppelin ReentrancyGuard library - nonReentrant modifier for the
aforementioned function to prevent reentrancy attacks.

Alleviation
The client heeded our advice and resolved the issues by importing and applying openzeppelin-
contracts/contracts/security/ReentrancyGuard.sol to prevent reentrancy attacks. The changes are

reflected in the commit 248a3599c549716656ac4527cb60d400c25a6879 .


MXSamurai Security Assessment

VRC-03 | Lack of Return Value Handling

Category Severity Location Status

Volatile Code Minor VestingRouter.sol: 29 Resolved

Description
The function mxsToken.transfer(address, uint256) is not a void-returning function. Ignore its return
value, especially when its return value represents the status of the transaction execution, might cause
unexpected exceptions.

Recommendation
We recommend handling the return value of the aforementioned function before continuing processing.

Alleviation
The client heeded our advice and resolved the issue by handling the return values of the aforementioned
functions before continuing processing. These changes are reflected in the commit
5c07296dc0ff749246efb6d5b3459e0e01f9ae95 .
MXSamurai Security Assessment

VRC-04 | Inefficient import

Category Severity Location Status

Gas Optimization Informational VestingRouter.sol: 3, 5, 6 Partially Resolved

Description
The file VestingRouter.sol imports the ERC20 and Vesting implementations by

3 import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

4 ...

5 import "./Vesting.sol";

However, importing their interfaces or implementing the necessary interfaces within the contract would be
good enough to make external calls.

Moreover, the imported file hardhat/console.sol is never used within the file VestingRouter.sol, so it can be
removed.

Recommendation
We recommend importing or implementing the aforementioned interfaces and removing the redundant
import statement to reduce the bytecode.

Alleviation
The client opted to consider our references and imported the interface instead. The change is reflected in
the commit ea6eab07293bb12ef348476be348af5b255bebe0 .
MXSamurai Security Assessment

VRC-05 | Event Optimization

Category Severity Location Status

Language Specific Informational VestingRouter.sol: 9~11 Resolved

Description
The linked event declarations can add their address parameters on the topics data structure by adding
the attribute indexed , hence allowing for easier off-chain monitoring.

For example,

9 event VestingCreated(address beneficiary, address vestingAddress, uint256


tokenAmount);

can be changed to

9 event VestingCreated(address indexed beneficiary, address indexed vestingAddress,


uint256 tokenAmount);

References: https://docs.soliditylang.org/en/latest/contracts.html#events

Recommendation
We advise to use the indexed attribute on the linked event arguments.

Alleviation
The client heeded our advice and resolved the issues by adding the indexed attribute to the
aforementioned event arguments. These changes are reflected in the commit
09ed2aca27333e3fbc3d956ce377f7ff20130342 .
MXSamurai Security Assessment

VRC-06 | Variable Could Be Declared as Immutable

Category Severity Location Status

Gas Optimization Informational VestingRouter.sol: 18 Resolved

Description
The variable mxsToken assigned in the constructor can be declared as immutable . Immutable state
variables can be assigned during contract creation but will remain constant throughout the lifetime of a
deployed contract. A big advantage of immutable variables is that reading them is significantly cheaper
than reading from regular state variables since will not be stored in storage. Still, values will directly insert
the values into the runtime code.

Recommendation
We recommend declaring the aforementioned variable as immutable .

Alleviation
The client heeded our advice and resolved the issue by declaring the mxsToken as immutable . The change
is reflected in the commit fc3cb587f371134c75a37c577a40af55aa0864d9 .
MXSamurai Security Assessment

VRC-07 | Proper Usage of public And external Type

Category Severity Location Status

VestingRouter.sol: 26, 36, 41, 82


Coding Style Informational Resolved
MXSToken.sol: 72

Description
The functions which are never called internally within the contract should have external visibility. For
example,

VestingRouter.createVesting(address, uint256, uint256, uint256, bool)

VestingRouter.userInfo(address)

VestingRouter.userVestingInfo(address)

VestingRouter.revoke(address)

VestingRouter.release(address)

Recommendation
We recommend changing the visibility of the aforementioned functions to external .

Alleviation
The client heeded our advice and resolved the issues by changing the visibilities of functions at the
aforementioned lines to external . These changes are reflected in the commit
c6f7eabf3f405086be8b0e32e84beecc70910f3e .
MXSamurai Security Assessment

Appendix
Finding Categories

Centralization / Privilege
Centralization / Privilege findings refer to either feature logic or implementation of components that act
against the nature of decentralization, such as explicit ownership or specialized access roles in
combination with a mechanism to relocate funds.

Gas Optimization
Gas Optimization findings do not affect the functionality of the code but generate different, more optimal
EVM opcodes resulting in a reduction on the total gas cost of a transaction.

Logical Issue
Logical Issue findings detail a fault in the logic of the linked code, such as an incorrect notion on how
block.timestamp works.

Control Flow
Control Flow findings concern the access control imposed on functions, such as owner-only functions
being invoke-able by anyone under certain circumstances.

Volatile Code
Volatile Code findings refer to segments of code that behave unexpectedly on certain edge cases that may
result in a vulnerability.

Language Specific
Language Specific findings are issues that would only arise within Solidity, i.e. incorrect usage of private or
delete.

Coding Style
Coding Style findings usually do not affect the generated byte-code but rather comment on how to make
the codebase more legible and, as a result, easily maintainable.

Checksum Calculation Method


MXSamurai Security Assessment

The "Checksum" field in the "Audit Scope" section is calculated as the SHA-256 (Secure Hash Algorithm 2
with digest size of 256 bits) digest of the content of each file hosted in the listed source repository under
the specified commit.

The result is hexadecimal encoded and is the same as the output of the Linux "sha256sum" command
against the target file.
MXSamurai Security Assessment

Disclaimer
This report is subject to the terms and conditions (including without limitation, description of services,
confidentiality, disclaimer and limitation of liability) set forth in the Services Agreement, or the scope of
services, and terms and conditions provided to you (“Customer” or the “Company”) in connection with the
Agreement. This report provided in connection with the Services set forth in the Agreement shall be used
by the Company only to the extent permitted under the terms and conditions set forth in the Agreement.
This report may not be transmitted, disclosed, referred to or relied upon by any person for any purposes,
nor may copies be delivered to any other person other than the Company, without CertiK’s prior written
consent in each instance.

This report is not, nor should be considered, an “endorsement” or “disapproval” of any particular project or
team. This report is not, nor should be considered, an indication of the economics or value of any
“product” or “asset” created by any team or project that contracts CertiK to perform a security
assessment. This report does not provide any warranty or guarantee regarding the absolute bug-free
nature of the technology analyzed, nor do they provide any indication of the technologies proprietors,
business, business model or legal compliance.

This report should not be used in any way to make decisions around investment or involvement with any
particular project. This report in no way provides investment advice, nor should be leveraged as investment
advice of any sort. This report represents an extensive assessing process intending to help our customers
increase the quality of their code while reducing the high level of risk presented by cryptographic tokens
and blockchain technology.

Blockchain technology and cryptographic assets present a high level of ongoing risk. CertiK’s position is
that each company and individual are responsible for their own due diligence and continuous security.
CertiK’s goal is to help reduce the attack vectors and the high level of variance associated with utilizing
new and consistently changing technologies, and in no way claims any guarantee of security or
functionality of the technology we agree to analyze.

The assessment services provided by CertiK is subject to dependencies and under continuing
development. You agree that your access and/or use, including but not limited to any services, reports,
and materials, will be at your sole risk on an as-is, where-is, and as-available basis. Cryptographic tokens
are emergent technologies and carry with them high levels of technical risk and uncertainty. The
assessment reports could include false positives, false negatives, and other unpredictable results. The
services may access, and depend upon, multiple layers of third-parties.

ALL SERVICES, THE LABELS, THE ASSESSMENT REPORT, WORK PRODUCT, OR OTHER MATERIALS,
OR ANY PRODUCTS OR RESULTS OF THE USE THEREOF ARE PROVIDED “AS IS” AND “AS
MXSamurai Security Assessment

AVAILABLE” AND WITH ALL FAULTS AND DEFECTS WITHOUT WARRANTY OF ANY KIND. TO THE
MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, CERTIK HEREBY DISCLAIMS ALL
WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO THE
SERVICES, ASSESSMENT REPORT, OR OTHER MATERIALS. WITHOUT LIMITING THE FOREGOING,
CERTIK SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT, AND ALL WARRANTIES ARISING FROM
COURSE OF DEALING, USAGE, OR TRADE PRACTICE. WITHOUT LIMITING THE FOREGOING, CERTIK
MAKES NO WARRANTY OF ANY KIND THAT THE SERVICES, THE LABELS, THE ASSESSMENT REPORT,
WORK PRODUCT, OR OTHER MATERIALS, OR ANY PRODUCTS OR RESULTS OF THE USE THEREOF,
WILL MEET CUSTOMER’S OR ANY OTHER PERSON’S REQUIREMENTS, ACHIEVE ANY INTENDED
RESULT, BE COMPATIBLE OR WORK WITH ANY SOFTWARE, SYSTEM, OR OTHER SERVICES, OR BE
SECURE, ACCURATE, COMPLETE, FREE OF HARMFUL CODE, OR ERROR-FREE. WITHOUT LIMITATION
TO THE FOREGOING, CERTIK PROVIDES NO WARRANTY OR UNDERTAKING, AND MAKES NO
REPRESENTATION OF ANY KIND THAT THE SERVICE WILL MEET CUSTOMER’S REQUIREMENTS,
ACHIEVE ANY INTENDED RESULTS, BE COMPATIBLE OR WORK WITH ANY OTHER SOFTWARE,
APPLICATIONS, SYSTEMS OR SERVICES, OPERATE WITHOUT INTERRUPTION, MEET ANY
PERFORMANCE OR RELIABILITY STANDARDS OR BE ERROR FREE OR THAT ANY ERRORS OR
DEFECTS CAN OR WILL BE CORRECTED.

WITHOUT LIMITING THE FOREGOING, NEITHER CERTIK NOR ANY OF CERTIK’S AGENTS MAKES ANY
REPRESENTATION OR WARRANTY OF ANY KIND, EXPRESS OR IMPLIED AS TO THE ACCURACY,
RELIABILITY, OR CURRENCY OF ANY INFORMATION OR CONTENT PROVIDED THROUGH THE
SERVICE. CERTIK WILL ASSUME NO LIABILITY OR RESPONSIBILITY FOR (I) ANY ERRORS, MISTAKES,
OR INACCURACIES OF CONTENT AND MATERIALS OR FOR ANY LOSS OR DAMAGE OF ANY KIND
INCURRED AS A RESULT OF THE USE OF ANY CONTENT, OR (II) ANY PERSONAL INJURY OR
PROPERTY DAMAGE, OF ANY NATURE WHATSOEVER, RESULTING FROM CUSTOMER’S ACCESS TO
OR USE OF THE SERVICES, ASSESSMENT REPORT, OR OTHER MATERIALS.

ALL THIRD-PARTY MATERIALS ARE PROVIDED “AS IS” AND ANY REPRESENTATION OR WARRANTY
OF OR CONCERNING ANY THIRD-PARTY MATERIALS IS STRICTLY BETWEEN CUSTOMER AND THE
THIRD-PARTY OWNER OR DISTRIBUTOR OF THE THIRD-PARTY MATERIALS.

THE SERVICES, ASSESSMENT REPORT, AND ANY OTHER MATERIALS HEREUNDER ARE SOLELY
PROVIDED TO CUSTOMER AND MAY NOT BE RELIED ON BY ANY OTHER PERSON OR FOR ANY
PURPOSE NOT SPECIFICALLY IDENTIFIED IN THIS AGREEMENT, NOR MAY COPIES BE DELIVERED TO,
ANY OTHER PERSON WITHOUT CERTIK’S PRIOR WRITTEN CONSENT IN EACH INSTANCE.

NO THIRD PARTY OR ANYONE ACTING ON BEHALF OF ANY THEREOF, SHALL BE A THIRD PARTY OR
OTHER BENEFICIARY OF SUCH SERVICES, ASSESSMENT REPORT, AND ANY ACCOMPANYING
MXSamurai Security Assessment

MATERIALS AND NO SUCH THIRD PARTY SHALL HAVE ANY RIGHTS OF CONTRIBUTION AGAINST
CERTIK WITH RESPECT TO SUCH SERVICES, ASSESSMENT REPORT, AND ANY ACCOMPANYING
MATERIALS.

THE REPRESENTATIONS AND WARRANTIES OF CERTIK CONTAINED IN THIS AGREEMENT ARE


SOLELY FOR THE BENEFIT OF CUSTOMER. ACCORDINGLY, NO THIRD PARTY OR ANYONE ACTING
ON BEHALF OF ANY THEREOF, SHALL BE A THIRD PARTY OR OTHER BENEFICIARY OF SUCH
REPRESENTATIONS AND WARRANTIES AND NO SUCH THIRD PARTY SHALL HAVE ANY RIGHTS OF
CONTRIBUTION AGAINST CERTIK WITH RESPECT TO SUCH REPRESENTATIONS OR WARRANTIES OR
ANY MATTER SUBJECT TO OR RESULTING IN INDEMNIFICATION UNDER THIS AGREEMENT OR
OTHERWISE.

FOR AVOIDANCE OF DOUBT, THE SERVICES, INCLUDING ANY ASSOCIATED ASSESSMENT REPORTS
OR MATERIALS, SHALL NOT BE CONSIDERED OR RELIED UPON AS ANY FORM OF FINANCIAL, TAX,
LEGAL, REGULATORY, OR OTHER ADVICE.
MXSamurai Security Assessment

About
Founded in 2017 by leading academics in the field of Computer Science from both Yale and Columbia
University, CertiK is a leading blockchain security company that serves to verify the security and
correctness of smart contracts and blockchain-based protocols. Through the utilization of our world-class
technical expertise, alongside our proprietary, innovative tech, we’re able to support the success of our
clients with best-in-class security, all whilst realizing our overarching vision; provable trust for all
throughout all facets of blockchain.

You might also like