[USDT] ERC20 Token Smart Contract Technical Assessment

Tether ERC20 Token SC Domain Team Assessment

General Information

Risk Summary

  • Does the contract implement the ERC20 token standards? Yes, the contract implements all the required ERC20 functions.
  • Risk analysis: MEDIUM.

Technical Information

  • Compiler version: v0.4.18+commit.9cf6e910
  • Decimals: 6
  • Overflow checks: Yes, the contract uses a SafeMath library.
  • Mitigation against allowance race-condition: Yes.
  • Upgradeable contract patterns: Yes.
  • Access control or restriction lists: Yes.
  • Non-standard features or behaviors?
    • The contract is pausable, via the Pausable inherited contract, and this functionality is only allowed by the contract owner (currently a 3 of 5 Gnosis MultisigWallet).

Formal Verification Considerations

  • Does transfer have simple semantics? Yes.
  • Does transferFrom have simple semantics? Yes.
  • Can balances be arbitrarily modified by some actor? Yes, the owner can blacklist and zero out the funds of addresses.
  • Are there any external calls? No.

Testnet Information

Contract Logic Summary

The contract is a vanilla ERC20 contract. It uses contract inheritance patterns standard for development practices at time of deployed.

Upgrading the Contract

The contract is upgraded via the deprecate(address) function in the TetherToken child contract. This function is protected by the onlyOwner modifier and changes the upgradedAddress variable. The contract has not been deprecated, but if that were to happen, all calls would be forwarded to the upgradedAddress.

Administrative Addresses

Contract Risk Summary

This is a medium risk contract. The ERC20 functions are implemented to the industry standard. The contract uses an upgradeable smart contract pattern that is controlled by a Gnosis MultiSigWallet requiring 3 of 5 signatures. The ERC20 allowance race condition is mitigated and noted in their code. The contract makes use of a SafeMath library to prevent overflows & underflows.

Supporting Materials

Will update these with hosted images soon.

Contract Inheritance Graph (tool: Surya)

Contract Call Graph (tool: Surya)

Contract Report (tool: Surya)

Sūrya’s Description Report

Files Description Table

File Name SHA-1 Hash
TetherToken.sol 754b793da622bdd9641ea1d21e0804c2b06cdbaf

Contracts Description Table

Contract Type Bases
└ Function Name Visibility Mutability Modifiers
SafeMath Library
└ mul Internal :lock:
└ div Internal :lock:
└ sub Internal :lock:
└ add Internal :lock:
Ownable Implementation
└ Public :exclamation: :stop_sign: NO❗️
└ transferOwnership Public :exclamation: :stop_sign: onlyOwner
ERC20Basic Implementation
└ totalSupply Public :exclamation: NO❗️
└ balanceOf Public :exclamation: NO❗️
└ transfer Public :exclamation: :stop_sign: NO❗️
ERC20 Implementation ERC20Basic
└ allowance Public :exclamation: NO❗️
└ transferFrom Public :exclamation: :stop_sign: NO❗️
└ approve Public :exclamation: :stop_sign: NO❗️
BasicToken Implementation Ownable, ERC20Basic
└ transfer Public :exclamation: :stop_sign: onlyPayloadSize
└ balanceOf Public :exclamation: NO❗️
StandardToken Implementation BasicToken, ERC20
└ transferFrom Public :exclamation: :stop_sign: onlyPayloadSize
└ approve Public :exclamation: :stop_sign: onlyPayloadSize
└ allowance Public :exclamation: NO❗️
Pausable Implementation Ownable
└ pause Public :exclamation: :stop_sign: onlyOwner whenNotPaused
└ unpause Public :exclamation: :stop_sign: onlyOwner whenPaused
BlackList Implementation Ownable, BasicToken
└ getBlackListStatus External :exclamation: NO❗️
└ getOwner External :exclamation: NO❗️
└ addBlackList Public :exclamation: :stop_sign: onlyOwner
└ removeBlackList Public :exclamation: :stop_sign: onlyOwner
└ destroyBlackFunds Public :exclamation: :stop_sign: onlyOwner
UpgradedStandardToken Implementation StandardToken
└ transferByLegacy Public :exclamation: :stop_sign: NO❗️
└ transferFromByLegacy Public :exclamation: :stop_sign: NO❗️
└ approveByLegacy Public :exclamation: :stop_sign: NO❗️
TetherToken Implementation Pausable, StandardToken, BlackList
└ Public :exclamation: :stop_sign: NO❗️
└ transfer Public :exclamation: :stop_sign: whenNotPaused
└ transferFrom Public :exclamation: :stop_sign: whenNotPaused
└ balanceOf Public :exclamation: NO❗️
└ approve Public :exclamation: :stop_sign: onlyPayloadSize
└ allowance Public :exclamation: NO❗️
└ deprecate Public :exclamation: :stop_sign: onlyOwner
└ totalSupply Public :exclamation: NO❗️
└ issue Public :exclamation: :stop_sign: onlyOwner
└ redeem Public :exclamation: :stop_sign: onlyOwner
└ setParams Public :exclamation: :stop_sign: onlyOwner


Symbol Meaning
:stop_sign: Function can modify state
:dollar: Function is payable

Can use existing MCD collateral type adapter: Yes, a GemJoin5 adapter.

Are you sure? The implementation of USDT that is currently deployed does not return true on transfer or transferFrom, so it seems like GemJoin5 would likely fail. It looks like we would need a new adapter that combines the balance handling of GemJoin2 and the decimals handling of GemJoin5? Alternatively, we could just not handle return values at all since (I think) USDT is supposed to throw or revert on any failure.


Yeah, really good point. To be honest, I gave it just a cursory thought to get this posted publicly before starting to put the code together for the Kovan deploy. I also think we should also consider some GemJoin6 like functionality. I will do some experimentation with what you proposed.