[HUSD] ERC20 Token Smart Contract Domain Community Assessment

[HUSD] ERC20 Token SC Assessment

Under @befitsandpiper guidance, I reviewed HUSD token smart contract. @wil would you be kind enough to review it when you have some time? Thanks.

The MIP6 submission is here. CC @Claude

General Information

Risk Summary

  • Does the contract implement the ERC20 token standards? Yes.
  • Risk analysis: MEDIUM.

Technical Information

  • Compiler version: v0.5.8+commit.23d335f2
  • Decimals: 8
  • Overflow checks: Yes, the contract uses a SafeMath uint256 library.
  • Mitigation against allowance race-condition: No
  • Upgradeable contract patterns: Not upgradable
  • Access control or restriction lists: Yes, using a role library for Pause, Blacklist, CoinFactory (see below)
  • Non-standard features or behaviors: Yes.
    • Transfers can be paused by anyone having PauserRole.
    • Coin can be added or removed to anyone by anyone having CoinFactoryAdminRole
    • Accounts can be frozen by anyone having BlacklistAdminRole.
    • Owner can be changed by the owner

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 contract can freeze/unfreeze any on-chain address and/or change their balance.
  • Are there any external calls? No.

Testnet Information

  • N/A

Contract Logic Summary

Administrative Addresses

Inheritance Structure

The inheritance structure is relatively complex. There is one inheritance lineage that goes from IERC20 (interface) to ERC20 (basic ERC20 implementation) to HUSDToken that overload some methods using some non standard feature in methods or modifiers from other inheritance lineages. Each non standard feature inherit from Owner (to have the contract owner) then a Role contract that manage who can use the non standard feature then an implementation of the non standard feature (like BlackList)

HUSDToken: ERC20, ERC20Pausable, CoinFactory, Blacklist
Blacklist: ERC20, BlacklistAdminRole
BlacklistAdminRole: Ownable
CoinFactory: ERC20, CoinFactoryAdminRole
CoinFactoryAdminRole: Ownable
ERC20Pausable: ERC20, Pausable
ERC20: IERC20 (interface), Ownable
Pausable: PauserRole
PauserRole: Ownable

Contract Risk Summary

This is a medium risk contract. The ERC20 functions are implemented to industry standard, it uses a SafeMath library to prevent over/underflows. However, the non-standard features can freeze, change balance of some accounts and pause the contract which introduces additional risk. Control over accounts balances and transfers is usual in stablecoin contracts.

Contracts Description Table

Contract Type Bases
└ Function Name Visibility Mutability Modifiers
SafeMath Library
└ add Internal :lock:
└ sub Internal :lock:
└ mul Internal :lock:
└ div Internal :lock:
└ mod Internal :lock:
Ownable Implementation
└ Internal :lock: :stop_sign:
└ owner Public :exclamation: NO❗️
└ isOwner Public :exclamation: NO❗️
└ transferOwnership Public :exclamation: :stop_sign: onlyOwner
└ _transferOwnership Internal :lock: :stop_sign:
Roles Library
└ add Internal :lock: :stop_sign:
└ remove Internal :lock: :stop_sign:
└ has Internal :lock:
PauserRole Implementation Ownable
└ Internal :lock: :stop_sign:
└ isPauser Public :exclamation: NO❗️
└ addPauser Public :exclamation: :stop_sign: onlyOwner
└ removePauser Public :exclamation: :stop_sign: onlyOwner
└ renouncePauser Public :exclamation: :stop_sign: NO❗️
└ _addPauser Internal :lock: :stop_sign:
└ _removePauser Internal :lock: :stop_sign:
Pausable Implementation PauserRole
└ Internal :lock: :stop_sign:
└ paused Public :exclamation: NO❗️
└ pause Public :exclamation: :stop_sign: onlyPauser whenNotPaused
└ unpause Public :exclamation: :stop_sign: onlyPauser whenPaused
IERC20 Interface
└ totalSupply External :exclamation: NO❗️
└ balanceOf External :exclamation: NO❗️
└ transfer External :exclamation: :stop_sign: NO❗️
└ allowance External :exclamation: NO❗️
└ approve External :exclamation: :stop_sign: NO❗️
└ transferFrom External :exclamation: :stop_sign: NO❗️
ERC20 Implementation IERC20, Ownable
└ totalSupply Public :exclamation: NO❗️
└ balanceOf Public :exclamation: NO❗️
└ transfer Public :exclamation: :stop_sign: NO❗️
└ allowance Public :exclamation: NO❗️
└ approve Public :exclamation: :stop_sign: NO❗️
└ transferFrom Public :exclamation: :stop_sign: NO❗️
└ increaseAllowance Public :exclamation: :stop_sign: NO❗️
└ decreaseAllowance Public :exclamation: :stop_sign: NO❗️
└ _transfer Internal :lock: :stop_sign:
└ _approve Internal :lock: :stop_sign:
└ _issue Internal :lock: :stop_sign:
└ _redeem Internal :lock: :stop_sign:
ERC20Pausable Implementation ERC20, Pausable
└ transfer Public :exclamation: :stop_sign: whenNotPaused
└ transferFrom Public :exclamation: :stop_sign: whenNotPaused
└ approve Public :exclamation: :stop_sign: whenNotPaused
└ increaseAllowance Public :exclamation: :stop_sign: whenNotPaused
└ decreaseAllowance Public :exclamation: :stop_sign: whenNotPaused
CoinFactoryAdminRole Implementation Ownable
└ Internal :lock: :stop_sign:
└ isCoinFactoryAdmin Public :exclamation: NO❗️
└ addCoinFactoryAdmin Public :exclamation: :stop_sign: onlyOwner
└ removeCoinFactoryAdmin Public :exclamation: :stop_sign: onlyOwner
└ renounceCoinFactoryAdmin Public :exclamation: :stop_sign: NO❗️
└ _addCoinFactoryAdmin Internal :lock: :stop_sign:
└ _removeCoinFactoryAdmin Internal :lock: :stop_sign:
CoinFactory Implementation ERC20, CoinFactoryAdminRole
└ issue Public :exclamation: :stop_sign: onlyCoinFactoryAdmin
└ redeem Public :exclamation: :stop_sign: onlyCoinFactoryAdmin
BlacklistAdminRole Implementation Ownable
└ Internal :lock: :stop_sign:
└ isBlacklistAdmin Public :exclamation: NO❗️
└ addBlacklistAdmin Public :exclamation: :stop_sign: onlyOwner
└ removeBlacklistAdmin Public :exclamation: :stop_sign: onlyOwner
└ renounceBlacklistAdmin Public :exclamation: :stop_sign: NO❗️
└ _addBlacklistAdmin Internal :lock: :stop_sign:
└ _removeBlacklistAdmin Internal :lock: :stop_sign:
Blacklist Implementation ERC20, BlacklistAdminRole
└ isBlacklist Public :exclamation: NO❗️
└ addBlacklist Public :exclamation: :stop_sign: onlyBlacklistAdmin
└ removeBlacklist Public :exclamation: :stop_sign: onlyBlacklistAdmin
└ _addBlacklist Internal :lock: :stop_sign:
└ _removeBlacklist Internal :lock: :stop_sign:
HUSDToken Implementation ERC20, ERC20Pausable, CoinFactory, Blacklist
└ Public :exclamation: :stop_sign: NO❗️
└ transfer Public :exclamation: :stop_sign: whenNotPaused
└ transferFrom Public :exclamation: :stop_sign: whenNotPaused


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

Thank you team, just want to know how to push things forward, since the risk is medium, and the situation is similiar with all other centralized stablecoins like USDC, TUSD, GUSD or PAX.

Maybe the nest step is HUSD oracle Assessment?Please share your ideas.

Thank you.