Skip to content

Instantly share code, notes, and snippets.

@yuriy77k
Forked from RideSolo/ETH_USDT_report.md
Created July 6, 2019 12:42
Show Gist options
  • Select an option

  • Save yuriy77k/49b74a164bccac9b2554de9b25ffae8b to your computer and use it in GitHub Desktop.

Select an option

Save yuriy77k/49b74a164bccac9b2554de9b25ffae8b to your computer and use it in GitHub Desktop.

USDT Token Audit Report.

1. Summary

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

2. In scope

3. Findings

4 issues were reported:

  • 3 low severity issues.
  • 1 owner privileges.

3.1. Owner Privileges

Severity: Owner Privileges

Description

3.2. Transfer to Address(0)

Severity: low

Description

transfer and transferFrom allow the destination address to be equal to zero, meaning that users fund can be lost if sent to it by mistake.

Code snippet

    function transfer(address _to, uint _value) public onlyPayloadSize(2 * 32) {
        uint fee = (_value.mul(basisPointsRate)).div(10000);
        if (fee > maximumFee) {
            fee = maximumFee;
        }
        uint sendAmount = _value.sub(fee);
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(sendAmount);
        if (fee > 0) {
            balances[owner] = balances[owner].add(fee);
            Transfer(msg.sender, owner, fee);
        }
        Transfer(msg.sender, _to, sendAmount);
    }

    function transferFrom(address _from, address _to, uint _value) public onlyPayloadSize(3 * 32) {
        var _allowance = allowed[_from][msg.sender];

        uint fee = (_value.mul(basisPointsRate)).div(10000);
        if (fee > maximumFee) {
            fee = maximumFee;
        }
        if (_allowance < MAX_UINT) {
            allowed[_from][msg.sender] = _allowance.sub(_value);
        }
        uint sendAmount = _value.sub(fee);
        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(sendAmount);
        if (fee > 0) {
            balances[owner] = balances[owner].add(fee);
            Transfer(_from, owner, fee);
        }
        Transfer(_from, _to, sendAmount);
    }

3.3. Not Emitted Transfer Event

Severity: low

Description

When issuing or redeeming tokens a transfer event should be emitted back and forth to address(0). ERC20 standard: "A token contract which creates new tokens SHOULD trigger a Transfer event with the _from address set to 0x0 when tokens are created". the same can be deducted when redeeming or burning tokens.

Same isssue is applicable for TetherToken constructor.

Code snippet

https://gist.github.com/RideSolo/24c79eb34b565ade477ec89c2af49a5b#file-usdt-sol-L406

https://gist.github.com/RideSolo/24c79eb34b565ade477ec89c2af49a5b#file-usdt-sol-L420

3.4. 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

Recommendation

Add into the function transfer(address _to, ... ) and transferFrom the following code, to avoid transfers to the contract address:

   require( _to != address(this) );

Conclusion

The audited code is safe, but etherem USDT holders should be aware of the owner privileges described in issue 3.1.

@sanjulaonline
Copy link

nice

@Lamarman
Copy link

done

@Elenore23
Copy link

Nice

@Elenore23
Copy link

require( _to != address(this) );

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