Skip to content

Instantly share code, notes, and snippets.

@RideSolo
Created January 14, 2020 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RideSolo/6ecbd3224e5d808e40338746a252f2c9 to your computer and use it in GitHub Desktop.
Save RideSolo/6ecbd3224e5d808e40338746a252f2c9 to your computer and use it in GitHub Desktop.

EZO Token Audit Report.

1. Summary

This document is a security audit report performed by RideSolo, where EZO Token has been reviewed.

2. In scope

  • CurrrencyPrices.sol github commit hash f4fa76fa25f4bbfedfd278ea8569045f2d89622f.
  • EZOToken.sol github commit hash ab7d1527e3ef6e45d005166311661972ab7eafb8.
  • SmartSwap.sol github commit hash ab7d1527e3ef6e45d005166311661972ab7eafb8.

3. Findings

** 14 issues** were reported including:

  • 3 high severity issues.
  • 3 medium severity issues.
  • 2 low severity issues.
  • 4 Owner privileges.
  • 2 notes.

3.1 Transfer

severity: high

Description

When a user call tranfer function to take an order deposited through sendToken:

  • The computed _valueCal of EZO tokens to be sent to the order maker is wrong since the value should be equal to the amount of the currency sent multiplied by the currency price then divided by the price of EZO in usd. Multiple errors can be seen,
    • safeDivv is used instead of safeDiv which will divide the result of the multiplication by 1 ether instead of the ezo price in USD.
    • Supposing if the division operation is correct the value used to divide is 100 but the price of EZO tokens can be changed by the owner using setEZOTokenPriceUSD, meaning that 100 should be replaced by ezoTokenPriceUSD.
  • The condition used to check if the value requested by the function caller is uncorrect, the condition should be as follow if(_valueCal > _value) { /* do processing */} to avoid extra computation if both values are equal.
  • The returnAmount computation is incorrect it should be the difference in USD multiplied by the 10 power the currency decimals then divided by the currency price in USD.
  • sentAmount should be the _valueCal in EZO multiplied by EZO token price in USD devided by the currency price in usd, while taking the decimals into account, node of the described steps where taken into account.

3.2 EZO Deposit

severity: high

Description

When cancelling an order generalFundAssign is used to refund the user tokens or ether, if the deposited tokens through sendToken are EZOs, instead of sending the tokens back to the user using assignTokens with the sender address equal to the EZO contract address, the developers used mint function which will create new tokens. The deposited EZO tokens will be frozen inside the contract making the token supply higher, an attacker can repeatedly deposit/cancel to make the total supply higher just to hurt the project. Please note that no max cap is setting when minting.

3.3 Smart Swap Deposit

severity: high

Description

When using smart swap contract deposit through sendEther or sendToken an order is automatically added (addOrder) and fullfilled (generalFundAssign, generalFundAssignEZO)if the wanted currency balance in the smartswap contract is higher than what the user is requesting and the deposited currency is ezo tokens, check [here]](https://github.com/ridesoloAudit/ezo-token/blob/e1284e5f8dd773ae9973b0fad3244efac9180513/ezotoken/contracts/SmartSwap.sol#L220#L225).

A user that deposited tokens or ether previously might not be able to withdraw his deposit since it can be swapped with other users deposit that deposited ezo tokens even if his wanted currency and sent currency are different than ezo tokens, check here

Users that deposit tokens to swap them agains EZO will be automatically accredited newly minted tokens to their account, the deposited tokens will be kept inside the contract, check here

This logic need a balanced deposit between all tokens otherwise some users orders might not be fullfilled and and their deposit might be spent, blocking them from using cancelOrder.

3.4 Rate Conversion & Multiplication Overflow

severity: medium

Description

The following conversion operation might be wrong, since the token decimals are not taken into account directly inside the code, the token decimals value can be integrated with the price in usd however we cannot confirm (this issue should be confirmed with the developers)

3.5 Unset Tokens

severity: medium

Description

The owner is responsible of setting the tokens prices using setCurrencyPriceUSD however it is not possible to set all the tokens that exist on the blockchain, meaning that the tokens addresses not set by the owner should not be allowed for deposit using sendToken. This will just constrain the users to cancel their order or give a bad user experience to other users if they want to take that order using transfer since the transaction will just throw because of deviding by zero.

3.6 ERC 20 Compliance

severity: medium

Description

Depending on the intention of the developers, the transfer function is not ERC20 compatible and users won't be able to transfer EZO tokens following the normal ERC20 rules.

Recommendation

To create the uniqueId needed in the contract logic, the developers can use a hashing function with a pack of some unique variables that cannot be recreated twice and save the value and sender variables in a mapping.

3.7 Price Setting

severity: low

Description

setCurrencyPriceUSD function role is to set the tokes reference value, _currency and _price arrays should be of equal length, a require must be added to check that condition.

3.8 Naming Erros

severity: note

Description

Naming on SafeMath library is leading to confusion when using safeMull, safeMul, safeDiv and safeDivv making the code readability more complex and prone to errors.

Code snippet

https://github.com/ridesoloAudit/ezo-token/blob/e1284e5f8dd773ae9973b0fad3244efac9180513/ezotoken/contracts/EZOToken.sol#L19#L49

https://github.com/ridesoloAudit/ezo-token/blob/e1284e5f8dd773ae9973b0fad3244efac9180513/ezotoken/contracts/SmartSwap.sol#L8#L38

3.9 Gas Consumption

severity: note

Description

When depositing ether or tokens a new PurchaseData contract is deployed making the transaction cost more expensive and not optimized.

3.10. Known vulnerabilities of ERC-20 token

Severity: low

Description

  1. It is possible to double withdrawal attack. More details here
  2. Lack of transaction handling mechanism issue. WARNING! This is a very common issue and it already caused millions of dollars losses for lots of token users! More details here

3.11 Owner Privileges

severity: high

Description

Please note that most function marked with "onlyOwner" can either remove trust that the blockchain technology enforce between users and developers or can be hacked in case if the private key is stolen.

4. Conclusion

The audited contract are unsafe and should not be deployed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment