IntegrityCoin

Smart Contract Audit Report

Audit Summary

IntegrityCoin is a BEP-20 token on the Binance Smart Chain that is an automatic liquidity providing protocol that pays dividends to holders.

For this audit, we reviewed the project team's IntegrityCoin contract at 0x745497b34553C4fc72ed11aEF2D9080F08337452 on the Binance Smart Chain Mainnet.

Audit Findings

Low findings were identified and the team should consider resolving these issues. In addition, some centralized aspects are present.
Date: December 13th, 2023.
Updated: December 18th, 2023 to reflect the contract's mainnet address.

Finding #1 - IntegrityCoin - Low

Description: In the _transfer() function, during peer-to-peer transfers, the setShare() function is called for both the sender and recipient even if they have been excluded from this functionality via the isExemptCheckingHold mapping.
Risk/Impact: Accounts that have been excluded from the share setting functionality will still be added as shareholders.
Recommendation: The _transfer() should be modified to only call the setShare() function if the user has not been excluded via the isExemptCheckingHold mapping.
Update: The project team has acknowledged this Finding.

Finding #2 - IntegrityCoinDividendTracker - Low

Description: The updateUniswapV2Router() function can only be called by the owner which is the IntegrityCoin contract. However, the IntegrityCoin contract does not contain a function that invokes the updateUniswapV2Router() function in the IntegrityCoinDividendTracker contract.
Risk/Impact: The updateUniswapV2Router() function can never be called by the team.
Recommendation: The team should add a function in the IntegrityCoin contract that invokes the updateUniswapV2Router() function in the IntegrityCoinDividendTracker contract.
Update: As the Router address has already been properly set, the project team does not intend to update it in the contract.

Finding #3 - IntegrityCoin - Informational

Description: The following conditions in the _transfer() function that check whether both the sender and recipient are not excluded from fees on a peer-to-peer transfer are redundant as they are previously checked in the function.
if (transferFee > 0 && !_isExcludedFromFees[from] && !_isExcludedFromFees[to]) {
Recommendation: The if-statement could be modified as follows for additional gas savings on each peer-to-peer transfer:
if (transferFee > 0 {

Finding #4 - IntegrityCoinDividendTracker - Informational

Description: The allowCustomTokens state variable is not used in the contract.
Recommendation: The allowCustomTokens state variable and setAllowCustomTokens() function should either be removed to reduce contract size and deployment costs or utilized in a way that fits the project team's intended functionality.

Finding #5 - IntegrityCoinDividendTracker - Informational

Description: The ClaimWaitUpdated event is not used in the contract.
Recommendation: The above event should either be removed to reduce contract size and deployment costs or utilized in a way that fits the project team's intended functionality.

Contract Overview

  • The total supply of the token is set to 1 trillion $TEG [1,000,000,000,000].
  • No mint functions are accessible beyond deployment.
  • Any user can burn their own tokens by initiating a transfer to the 0x..dead address. The specified number of tokens are burned from the caller's wallet address.
  • At the time of writing this report, there are 221 total token holders. The token allocation is as follows:
    • 36.55% of the total supply has been sent to the 0x..dead address.
    • 13.36% of the total supply belongs to the owner.
    • 10% of the total supply belongs to an EOA.
    • 5.41% of the total supply belongs to an EOA.
    • The next five holders own a cumulative 6.44% of the total supply.
  • Trading must be enabled by the owner before all transfers can take place on the platform. Only addresses that have been exempt by the owner can initiate a transfer before trading is enabled. Once trading is enabled, it can never be disabled.
  • Blacklisted accounts are prohibited from participating in transfers.
  • The contract features an anti-sniper mechanism that prevents a buy from occurring if the contract's delay time has not yet passed since trading was enabled by the owner.
  • Users are prohibited from initiating more than one buy transaction within the same block.
  • The contract features a cool-down mechanism that prevents a sell from occurring if the contract's cool-down time has not yet passed since the user's previous buy or sell.
  • The contract enforces a maximum sell amount (set by the team) which imposes a limit to the number of tokens that can be sold via Pancakeswap in a single transaction.
  • There is a Rewards fee, Liquidity Fee, Buyback fee, and Backup fee on all transfers where neither the sender nor the recipient is excluded from fees. A separate fee structure can be set by the team to apply different fee percentages depending on whether the transfer is a buy, sell, or peer-to-peer transfer.
  • The tokens collected from fees are stored in the contract address. The tokens are swapped for BNB for the purpose of funding Pancakeswap liquidity and addresses set by the team when the following conditions are met:
    • The automatic liquidity add functionality is enabled by the team.
    • The threshold number of tokens (set by the team) in the contract address has been reached.
    • The contract is not currently performing an automatic liquidity add.
    • The caller is initiating a sell transaction via Pancakeswap.
  • Liquidity-adds are automatically performed by selling the tokens collected as fees, pairing the received BNB with the token, and adding it as liquidity to the BNB pair.
  • The LP tokens received through this process are sent to the owner. We recommend that the team lock these newly acquired LP tokens.
  • The tokens collected through the Buyback fee and Backup fee are swapped for BNB and sent to the team's Buyback wallet and Backup wallet respectively.
  • The tokens collected through the Rewards Fee are swapped for BNB and sent to the DividendTracker contract to be distributed as rewards.

  • Once dividends are distributed, they will need to be claimed; claiming happens automatically on each transfer.
  • Dividend rewards can also be claimed manually by kicking off the claim cycle, which will process all eligible token holders.
  • Alternatively, a user can manually claim dividends as an individual at any time. If the reward token address is set to the 0x00 address, the calculated amount of dividends is transferred from the contract to the user in the form of BNB.
  • If the reward token address is set, the calculated amount of BNB dividends is swapped for the reward token and sent to the user.
  • If the owner has declared that the user's dividends are to be reinvested, the amount of BNB dividends due to the user are swapped for $TEG and subsequently transferred to their wallet address.
  • As the contract is implemented with Solidity v0.8.x, it is safe from any possible overflows/underflows.
  • The contract complies with the BEP-20 token standard.
Ownership Controls:
  • The owner can set total fees for both the buy and sell fee structures to up to 35% each at any time.
  • The owner can set the fee charged on peer-to-peer transfer to any percentage up to 10% at any time.
  • The owner can exclude and include addresses from transfer fees and dividends at any time.
  • The owner can add/remove any address from the transfer blacklist at any time.
  • The owner can update the threshold number of tokens that triggers the contract's automatic token swapping functionality to any value at any time.
  • The owner can enable/disable the contract's automatic token swapping functionality at any time.
  • The owner can allow/disallow any address to be able to initiate transfers before trading is enabled.
  • The owner can set the maximum sell amount to any value greater than 0.1% of the current total supply at any time.
  • The owner can enable/disable the cool-down, same block purchase, and gas price restrictions at any time.
  • The owner can set the gas price limit to 5 gwei or greater at any time.
  • The owner can set the cool-down time to any value up to 5 minutes (in seconds) at any time.
  • The owner can add/remove any address as an Automated Market Maker Pair address at any time.
  • The owner can manually trigger the swapping and sending of dividends at any time.
  • The owner can transfer any number of tokens to up to 400 addresses in a single transaction at any time.
  • The owner can set the dividend payout token to any address at any time.
  • The owner can update the minimum number of tokens a user must own in order to be eligible for dividends to any values at any time.
  • The owner can exclude and include accounts from the share setting functionality at any time.
  • The owner can update the amount of gas used for processing to any value between 200,000 and 2 million at any time.
  • The owner can enable/disable the automatic reinvest functionality at any time.
  • The owner can transfer ownership to any specified address at any time.
  • The owner can pause/unpause the automatic dividend processing functionality at any time.
  • The owner can set the Backup address and Buyback address to any addresses at any time.

Audit Results

Vulnerability Category Notes Result
Arbitrary Jump/Storage Write N/A PASS
Centralization of Control
  • The LP tokens generated through automatic liquidity adds are sent to the owner.
  • The owner can add addresses to the transfer blacklist at any time.
  • The owner can set total fees for both the buy and sell fee structures to up to 35% each at any time.
WARNING
Compiler Issues N/A PASS
Delegate Call to Untrusted Contract N/A PASS
Dependence on Predictable Variables N/A PASS
Ether/Token Theft N/A PASS
Flash Loans N/A PASS
Front Running The automatic token swapping functionality may be susceptible to front-running; The team must monitor and if suspicious activity is detected, should lower the swapTokensAtAmount value. PASS
Improper Events N/A PASS
Improper Authorization Scheme N/A PASS
Integer Over/Underflow N/A PASS
Logical Issues
  • In the _transfer() function, during peer-to-peer transfers, the setShare() function is called for both the sender and recipient even if they have been excluded from this functionality via the isExemptCheckingHold mapping.
  • The updateUniswapV2Router() function can only be called by the owner which is the IntegrityCoin contract. However, the IntegrityCoin contract does not contain a function that invokes the updateUniswapV2Router() function in the IntegrityCoinDividendTracker contract.
WARNING
Oracle Issues N/A PASS
Outdated Compiler Version N/A PASS
Race Conditions N/A PASS
Reentrancy N/A PASS
Signature Issues N/A PASS
Sybil Attack N/A PASS
Unbounded Loops N/A PASS
Unused Code N/A PASS
Overall Contract Safety   PASS

Inheritance Chart

Smart Contract Audit - Inheritance

Function Graph

Smart Contract Audit - Graph

Functions Overview


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 + [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] IUniswapV2Factory 
    - [Ext] feeTo
    - [Ext] feeToSetter
    - [Ext] getPair
    - [Ext] allPairs
    - [Ext] allPairsLength
    - [Ext] createPair #
    - [Ext] setFeeTo #
    - [Ext] setFeeToSetter #

 + [Int] IERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 + [Int] IERC20Metadata (IERC20)
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals

 +  ERC20 (Context, IERC20, IERC20Metadata)
    - [Pub]  #
    - [Pub] name
    - [Pub] symbol
    - [Pub] decimals
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] allowance
    - [Pub] approve #
    - [Pub] transferFrom #
    - [Pub] increaseAllowance #
    - [Pub] decreaseAllowance #
    - [Int] _transfer #
    - [Int] _mint #
    - [Int] _burn #
    - [Int] _approve #
    - [Int] _beforeTokenTransfer #

 + [Int] DividendPayingTokenOptionalInterface 
    - [Ext] withdrawableDividendOf
    - [Ext] withdrawnDividendOf
    - [Ext] accumulativeDividendOf

 + [Int] DividendPayingTokenInterface 
    - [Ext] dividendOf
    - [Ext] distributeDividends ($)
    - [Ext] withdrawDividend #

 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] mod
    - [Int] mod

 +  Ownable (Context)
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner

 + [Lib] SafeMathInt 
    - [Int] mul
    - [Int] div
    - [Int] sub
    - [Int] add
    - [Int] abs
    - [Int] toUint256Safe

 + [Lib] SafeMathUint 
    - [Int] toInt256Safe

 + [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] IUniswapV2Router02 (IUniswapV2Router01)
    - [Ext] removeLiquidityETHSupportingFeeOnTransferTokens #
    - [Ext] removeLiquidityETHWithPermitSupportingFeeOnTransferTokens #
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
    - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
    - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #

 +  DividendPayingToken (ERC20, DividendPayingTokenInterface, DividendPayingTokenOptionalInterface)
    - [Pub]  #
       - modifiers: ERC20
    - [Ext]  ($)
    - [Pub] distributeDividends ($)
    - [Pub] withdrawDividend #
    - [Int] _withdrawDividendOfUser #
    - [Pub] dividendOf
    - [Pub] withdrawableDividendOf
    - [Pub] withdrawnDividendOf
    - [Pub] accumulativeDividendOf
    - [Int] _transfer #
    - [Int] _mint #
    - [Int] _burn #
    - [Int] _setBalance #

 +  IntegrityCoin (ERC20, Ownable)
    - [Pub]  #
       - modifiers: ERC20
    - [Pub] decimals
    - [Ext]  ($)
    - [Ext] enableTrading #
       - modifiers: onlyOwner
    - [Ext] toggleBlacklist #
       - modifiers: onlyOwner
    - [Ext] setBuyBackWallet #
       - modifiers: onlyOwner
    - [Ext] setBackupWallet #
       - modifiers: onlyOwner
    - [Pub] setExcludeFees #
       - modifiers: onlyOwner
    - [Pub] setExcludeDividends #
       - modifiers: onlyOwner
    - [Pub] setIncludeDividends #
       - modifiers: onlyOwner
    - [Ext] setCanTransferBefore #
       - modifiers: onlyOwner
    - [Ext] setLimitsInEffect #
       - modifiers: onlyOwner
    - [Ext] setGasPriceLimit #
       - modifiers: onlyOwner
    - [Ext] setcooldowntimer #
       - modifiers: onlyOwner
    - [Ext] setmaxTX #
       - modifiers: onlyOwner
    - [Pub] setSwapTriggerAmount #
       - modifiers: onlyOwner
    - [Pub] enableSwapAndLiquify #
       - modifiers: onlyOwner
    - [Pub] setAutomatedMarketMakerPair #
       - modifiers: onlyOwner
    - [Pub] setAllowCustomTokens #
       - modifiers: onlyOwner
    - [Pub] setAllowAutoReinvest #
       - modifiers: onlyOwner
    - [Prv] _setAutomatedMarketMakerPair #
    - [Pub] updateGasForProcessing #
       - modifiers: onlyOwner
    - [Pub] transferAdmin #
       - modifiers: onlyOwner
    - [Pub] updateTransferFee #
       - modifiers: onlyOwner
    - [Pub] updateFees #
       - modifiers: onlyOwner
    - [Ext] getTotalDividendsDistributed
    - [Pub] isExcludedFromFees
    - [Pub] withdrawableDividendOf
    - [Pub] dividendTokenBalanceOf
    - [Ext] getAccountDividendsInfo
    - [Ext] getAccountDividendsInfoAtIndex
    - [Ext] processDividendTracker #
    - [Ext] claim #
    - [Ext] getLastProcessedIndex
    - [Ext] getNumberOfDividendTokenHolders
    - [Ext] setAutoClaim #
    - [Ext] setReinvest #
    - [Ext] setDividendsPaused #
       - modifiers: onlyOwner
    - [Ext] isExcludedFromAutoClaim
    - [Ext] isReinvest
    - [Pub] blacklisted
    - [Int] _transfer #
    - [Prv] swapAndLiquify #
    - [Prv] swapTokensForEth #
    - [Pub] updatePayoutToken #
       - modifiers: onlyOwner
    - [Pub] getPayoutToken
    - [Pub] setMinimumTokenBalanceForAutoDividends #
       - modifiers: onlyOwner
    - [Pub] setMinimumTokenBalanceForDividends #
       - modifiers: onlyOwner
    - [Prv] addLiquidity #
    - [Pub] forceSwapAndSendDividends #
       - modifiers: onlyOwner
    - [Prv] swapAndSendDividends #
    - [Ext] airdropToWallets #
       - modifiers: onlyOwner
    - [Int] setShare #
    - [Int] addShareholder #
    - [Int] removeShareholder #
    - [Ext] setIsExemptCheckingHold #
       - modifiers: onlyOwner
    - [Ext] getHolders
    - [Ext] getHoldersWithShare

 +  IntegrityCoinDividendTracker (DividendPayingToken, Ownable)
    - [Pub]  #
       - modifiers: DividendPayingToken
    - [Pub] decimals
    - [Pub] name
    - [Pub] symbol
    - [Int] _transfer
    - [Pub] withdrawDividend
    - [Ext] isExcludedFromAutoClaim
       - modifiers: onlyOwner
    - [Ext] isReinvest
       - modifiers: onlyOwner
    - [Ext] setAllowCustomTokens #
       - modifiers: onlyOwner
    - [Ext] setAllowAutoReinvest #
       - modifiers: onlyOwner
    - [Ext] excludeFromDividends #
       - modifiers: onlyOwner
    - [Ext] includeFromDividends #
       - modifiers: onlyOwner
    - [Ext] setAutoClaim #
       - modifiers: onlyOwner
    - [Ext] setReinvest #
       - modifiers: onlyOwner
    - [Ext] setMinimumTokenBalanceForAutoDividends #
       - modifiers: onlyOwner
    - [Ext] setMinimumTokenBalanceForDividends #
       - modifiers: onlyOwner
    - [Ext] setDividendsPaused #
       - modifiers: onlyOwner
    - [Ext] getLastProcessedIndex
    - [Ext] getNumberOfTokenHolders
    - [Pub] getAccount
    - [Pub] getAccountAtIndex
    - [Ext] setBalance #
       - modifiers: onlyOwner
    - [Pub] process #
    - [Pub] processAccount #
       - modifiers: onlyOwner
    - [Pub] updateUniswapV2Router #
       - modifiers: onlyOwner
    - [Pub] updatePayoutToken #
       - modifiers: onlyOwner
    - [Pub] getPayoutToken
    - [Prv] _reinvestDividendOfUser #
    - [Int] _withdrawDividendOfUser #

 + [Lib] IterableMapping 
    - [Int] get
    - [Int] getIndexOfKey
    - [Int] getKeyAtIndex
    - [Int] size
    - [Int] set #
    - [Int] remove #

About SourceHat

SourceHat has quickly grown to have one of the most experienced and well-equipped smart contract auditing teams in the industry. Our team has conducted 1800+ solidity smart contract audits covering all major project types and protocols, securing a total of over $50 billion U.S. dollars in on-chain value!
Our firm is well-reputed in the community and is trusted as a top smart contract auditing company for the review of solidity code, no matter how complex. Our team of experienced solidity smart contract auditors performs audits for tokens, NFTs, crowdsales, marketplaces, gambling games, financial protocols, and more!

Contact us today to get a free quote for a smart contract audit of your project!

What is a SourceHat Audit?

Typically, a smart contract audit is a comprehensive review process designed to discover logical errors, security vulnerabilities, and optimization opportunities within code. A SourceHat Audit takes this a step further by verifying economic logic to ensure the stability of smart contracts and highlighting privileged functionality to create a report that is easy to understand for developers and community members alike.

How Do I Interpret the Findings?

Each of our Findings will be labeled with a Severity level. We always recommend the team resolve High, Medium, and Low severity findings prior to deploying the code to the mainnet. Here is a breakdown on what each Severity level means for the project:

  • High severity indicates that the issue puts a large number of users' funds at risk and has a high probability of exploitation, or the smart contract contains serious logical issues which can prevent the code from operating as intended.
  • Medium severity issues are those which place at least some users' funds at risk and has a medium to high probability of exploitation.
  • Low severity issues have a relatively minor risk association; these issues have a low probability of occurring or may have a minimal impact.
  • Informational issues pose no immediate risk, but inform the project team of opportunities for gas optimizations and following smart contract security best practices.