Thirm Protocol - Smart Contract Audit Report

Summary

Thirm Protocol Token and DEX Thirm Protocol is building a platform that allows users to access cryptocurrency assets between multiple blockchains.

We reviewed Thirm Protocol's swap router and their controller and mapping contracts at the following addresses on the Binance Smart Chain mainnet:

  • Thirm Protocol Router: 0x4a9b79F317a69712139DfDA4a8f08029980Bd3D8
  • Controller: 0x8295d5Ce50640900e8208879e4892D6FAa8D3f98
  • Mapping: 0xE47924aDc1F8530Ae34E67431D3a13AbCF5f95cF
  • Please note we have not reviewed other contracs by the team.

    Notes on the Thirm Protocol AMM:
  • The Thirm Protocol decentralized exchange is based on the battle-tested Uniswap V2 codebase.
  • The Router contract routes orders to the user-determined pair contract to swap assets.
  • Each time a user utilizes the router contract, they will earn a reward point.
  • Users can claim reward points for THIRM tokens held the the router contract.
  • Rewards are funded using another contract by the team which we have not reviewed in detail.
  • When dealing with tokens that have a fee-on-transfer, the estimated output does not properly subtract the fee. As a result, users of fee-on-transfer tokens must set a slippage percentage prior to executing trades.
  • SafeMath is utilized to prevent overflow issues and TransferHelper to ensure safe transfers.

  • Notes on the Mapping and Controller Contracts:
  • The mapping contract allows users to burn a number of THIRM tokens, equal to 0.0002% of the token's supply, in order to associate themselves with a coin address.
  • The mapping contract is deployed behind an upgradable proxy, allowing the team to alter the contract used at any time.
  • The getBurnAmount() performs a multiplication on the result of a division, leading to less accurate results. It is always best to perform all multiplications before divisions.
  • The controller contract allows users to redeem tokens owed to them, as determined by the team.
  • Tokens are minted to users when they make a claim.
  • The owner of the controller contract can set the commission fee to any value and can update the tokens used in the contract at any time.

  • A number of functions across all contracts can be declared external instead of public to save gas on each call. These details have been provided to the team.
  • Utilization of SafeMath (or similarily safe functions) across all contracts to prevent overflows.


  • Audit Findings Summary
    • No vulnerabilities from external attackers were identified.
    • Ensure trust in the team as they have notable control in the ecosystem.
    • Date: June 14th, 2021

    External Threat Results

    Vulnerability CategoryNotesResult
    Arbitrary Storage WriteN/APASS
    Arbitrary JumpN/APASS
    Delegate Call to Untrusted ContractN/APASS
    Dependence on Predictable VariablesN/APASS
    Deprecated OpcodesN/APASS
    Ether ThiefN/APASS
    ExceptionsN/APASS
    External CallsN/APASS
    Integer Over/UnderflowN/APASS
    Multiple SendsN/APASS
    SuicideN/APASS
    State Change External CallsN/APASS
    Unchecked RetvalN/APASS
    User Supplied AssertionN/APASS
    Critical Solidity CompilerN/APASS
    Overall Contract Safety PASS


    Thirm Protocol Router Contract - Details

    Contract Graph

    Multi-file Token

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
     
     + [Int] IUniswapV2Pair 
        - [Ext] name
        - [Ext] symbol
        - [Ext] decimals
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transfer #
        - [Ext] transferFrom #
        - [Ext] DOMAIN_SEPARATOR
        - [Ext] PERMIT_TYPEHASH
        - [Ext] nonces
        - [Ext] permit #
        - [Ext] MINIMUM_LIQUIDITY
        - [Ext] factory
        - [Ext] token0
        - [Ext] token1
        - [Ext] getReserves
        - [Ext] price0CumulativeLast
        - [Ext] price1CumulativeLast
        - [Ext] kLast
        - [Ext] mint #
        - [Ext] burn #
        - [Ext] swap #
        - [Ext] skim #
        - [Ext] sync #
        - [Ext] initialize #
    
     + [Int] IUniswapV2Router01 
        - [Ext] factory
        - [Ext] WETH
        - [Ext] addLiquidity #
        - [Ext] addLiquidityETH ($)
        - [Ext] removeLiquidity #
        - [Ext] removeLiquidityETH #
        - [Ext] removeLiquidityWithPermit #
        - [Ext] removeLiquidityETHWithPermit #
        - [Ext] swapExactTokensForTokens #
        - [Ext] swapTokensForExactTokens #
        - [Ext] swapExactETHForTokens ($)
        - [Ext] swapTokensForExactETH #
        - [Ext] swapExactTokensForETH #
        - [Ext] swapETHForExactTokens ($)
        - [Ext] quote
        - [Ext] getAmountOut
        - [Ext] getAmountIn
        - [Ext] getAmountsOut
        - [Ext] getAmountsIn
    
     + [Int] IWETH 
        - [Ext] deposit ($)
        - [Ext] transfer #
        - [Ext] withdraw #
    
     + [Int] IERC20 
        - [Ext] name
        - [Ext] symbol
        - [Ext] decimals
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transfer #
        - [Ext] transferFrom #
    
     + [Lib] SafeMath 
        - [Int] add
        - [Int] sub
        - [Int] mul
        - [Int] div
    
     + [Lib] UniswapV2Library 
        - [Int] sortTokens
        - [Int] pairFor
        - [Int] getReserves
        - [Int] quote
        - [Int] getAmountOut
        - [Int] getAmountIn
        - [Int] getAmountsOut
        - [Int] getAmountsIn
    
     + [Int] IUniswapV2Router02 (IUniswapV2Router01)
        - [Ext] removeLiquidityETHSupportingFeeOnTransferTokens #
        - [Ext] removeLiquidityETHWithPermitSupportingFeeOnTransferTokens #
        - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
        - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
        - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #
    
     + [Lib] TransferHelper 
        - [Int] safeApprove #
        - [Int] safeTransfer #
        - [Int] safeTransferFrom #
        - [Int] safeTransferETH #
    
     + [Int] IUniswapV2Factory 
        - [Ext] feeTo
        - [Ext] feeToSetter
        - [Ext] getPair
        - [Ext] allPairs
        - [Ext] allPairsLength
        - [Ext] createPair #
        - [Ext] setFeeTo #
        - [Ext] setFeeToSetter #
    
     +  UniswapV2Router02 (IUniswapV2Router02)
        - [Pub]  #
        - [Int] job #
        - [Int] tokenBalance
        - [Pub] claimBalance #
        - [Ext]  ($)
        - [Int] _addLiquidity #
        - [Ext] addLiquidity #
           - modifiers: ensure
        - [Ext] addLiquidityETH ($)
           - modifiers: ensure
        - [Pub] removeLiquidity #
           - modifiers: ensure
        - [Pub] removeLiquidityETH #
           - modifiers: ensure
        - [Ext] removeLiquidityWithPermit #
        - [Ext] removeLiquidityETHWithPermit #
        - [Pub] removeLiquidityETHSupportingFeeOnTransferTokens #
           - modifiers: ensure
        - [Ext] removeLiquidityETHWithPermitSupportingFeeOnTransferTokens #
        - [Int] _swap #
        - [Ext] swapExactTokensForTokens #
           - modifiers: ensure
        - [Ext] swapTokensForExactTokens #
           - modifiers: ensure
        - [Ext] swapExactETHForTokens ($)
           - modifiers: ensure
        - [Ext] swapTokensForExactETH #
           - modifiers: ensure
        - [Ext] swapExactTokensForETH #
           - modifiers: ensure
        - [Ext] swapETHForExactTokens ($)
           - modifiers: ensure
        - [Int] _swapSupportingFeeOnTransferTokens #
        - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
           - modifiers: ensure
        - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
           - modifiers: ensure
        - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #
           - modifiers: ensure
        - [Pub] quote
        - [Pub] getAmountOut
        - [Pub] getAmountIn
        - [Pub] getAmountsOut
        - [Pub] getAmountsIn


    Controller - Details

    Contract Graph

    Multi-file Token

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
     
     + [Lib] SafeMath 
        - [Int] tryAdd
        - [Int] trySub
        - [Int] tryMul
        - [Int] tryDiv
        - [Int] tryMod
        - [Int] add
        - [Int] sub
        - [Int] mul
        - [Int] div
        - [Int] mod
        - [Int] sub
        - [Int] div
        - [Int] mod
    
     +  Ownable 
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
        - [Pub]  #
    
     + [Int] ERC20 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
        - [Ext] mint #
        - [Ext] burnFrom #
    
     +  Controller (Ownable)
        - [Pub] setComissionFee #
           - modifiers: onlyOwner
        - [Pub] tTokenInit #
           - modifiers: onlyOwner
        - [Pub] mintCoin #
           - modifiers: onlyOwner
        - [Pub] getMintsLength
        - [Pub] registerWithdrawal #
        - [Pub] registerWithdrawalSuccess #
           - modifiers: onlyOwner
        - [Pub] getBurnsLength


    Mapping Contract - Details

    Contract Graph

    Multi-file Token

    
     ($) = payable function
     # = non-constant function
     
     Int = Internal
     Ext = External
     Pub = Public
     
     + [Lib] Address 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] functionDelegateCall #
        - [Int] functionDelegateCall #
        - [Prv] _verifyCallResult
    
     + [Int] ERC20 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
        - [Ext] mint #
        - [Ext] burnFrom #
    
     + [Lib] SafeMath 
        - [Int] tryAdd
        - [Int] trySub
        - [Int] tryMul
        - [Int] tryDiv
        - [Int] tryMod
        - [Int] add
        - [Int] sub
        - [Int] mul
        - [Int] div
        - [Int] mod
        - [Int] sub
        - [Int] div
        - [Int] mod
    
     +  Initializable 
        - [Prv] _isConstructor
    
     +  Mapping (Initializable)
        - [Pub] initialize #
           - modifiers: initializer
        - [Pub] getBurnAmount
        - [Pub] setAddressMap #
        - [Pub] getAddressMap