Pirate Coin - Smart Contract Audit Report
Pirate Coin ($PirateCoin) is a new community-driven DeFi token on the Binance Smart Chain that is a an automatic liquidity providing protocol, and enables holders to participate in a lottery.
We reviewed Pirate Coin's contract at 0x041640ea980e3fe61e9c4ca26d9007bc70094c15 on the BSC mainnet.
Notes of the Contract:
- The total supply of the token is 100 quadrillion $PirateCoin [100,000,000,000,000,000].
- No mint or burn functions exist, though the circulating supply can be decreased by sending tokens to the burn address.
- At the time of writing this report, 15.1% of the total token supply is in Pancakeswap liquidity.
- Of that liquidity, 98.84% of the LP tokens are held in a token locking contract and will vest to the team on February 9th, 2022.
- The top ten holders own a cumulative 9.88% of the total supply
- There is a liquidity fee, tax fee, lottery fee, marketing fee, and a txGold (Charity) fee on all transactions for any "non-excluded" address that participates in a transfer. The owner has the ability to modify these fees to any percentage at any time.
- The liquidity fee charged on transactions is stored in the contract and, once a threshold value is met, is used to fund Pancakeswap liquidity. This functionality can be enabled/disabled by the owner.
- Liquidity-adds are funded by selling a portion of the tokens collected as fees (after the threshold as determined by the owner is met), then pairing the received BNB with the token, and adding it as liquidity to the BNB pair.
- The recipient of the newly created LP tokens is the owner of the contract. The team is responsible for locking these newly acquired LP tokens.
- At the time of writing this report, the tax fee is currently set to 0%. If this percentage is modified to any other value by the owner, users who hold tokens will automatically benefit from the frictionless fee redistribution at the time of each transaction as the tokens collected through the tax fee are removed from the circulating supply.
- The lottery fee charged on transactions is stored in the lottery pool, and once a threshold value (determined by the owner) is met, a winner will be pseudo-randomly chosen. The chosen winner must own the required minimum number of tokens determined by the owner in order to receive the tokens stored in the lottery pool. user holding the required minimum number of tokens (also determined by the owner) will be pseudo-randomly chosen as the winner.
- The contract utilizes a "shouldSwaptoBNB" feature which can be toggled on/off by the owner. When toggled off, The tokens collected through the marketing fee and txGold fee are sent directly to the team's marketing wallet and txGold (Charity) wallet respectively. When toggled on, the tokens are swapped for BNB, sent to the contract address, and subsequetly sent to the team's marketing wallet and txGold (Charity) wallet respectively.
- As the project is deployed with Solidity v0.8.4, it is protected from overflows.
- The owner of the contract can exclude and include accounts from transfer fees and frictionless fee redistribution.
- The owner has the ability to set and update a maximum transaction percent at any time, which will impose a limit to the number of tokens that can be transferred during any given transaction.
- This maximum transaction amount does not apply to the owner during transactions where the owner is either the sender or the recipient.
- The contract features an anti-whale mechanism which, when enabled by the owner, prevents a transaction from occuring if the receivers balance, after the transaction takes palce, will be greater than 1% of total supply. The owner can modify this percentage to any value at any time.
- The owner can enable/disable the lottery as well as update the minimum threshold token value that dictates when a winner is chosen.
- The owner has the ability to update the Pancakeswap Pair and Pancakeswap Router address at any time.
- The owner has the ability to use the "lock" function in order to temporarily set ownership to address(0). Ownership is restored after the duration of time determined by the owner has passed and they use the 'unlock' function.
- The unlock function has the potential to be used after ownership is renounced, which will restore ownership to the original owner that initially created the ownership lock. This can be used in a nefarious way by the project team to restore ownership and change fee structures.
- We recommend that the unlock function is modified to set the "previous owner" = "address(0)" at the end of the unlock function to prevent it from being used more than once per lock.
Audit Findings Summary:
- No external threats were identified.
- There are potential risks that exist for holders regarding the team's ability to retain control of the contract.
- We recommend that the team renounces ownership without ever calling the lock function.
- Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
- Further, ensure trust in the team as the LP tokens can be migrated to a new address at any time.
- Date: September 5th, 2021.
External Threat Results
|Arbitrary Storage Write||N/A||PASS|
|Delegate Call to Untrusted Contract||N/A||PASS|
|Dependence on Predictable Variables||N/A||PASS|
|State Change External Calls||N/A||PASS|
|User Supplied Assertion||N/A||PASS|
|Critical Solidity Compiler||N/A||PASS|
|Overall Contract Safety||PASS|
($) = payable function # = non-constant function Int = Internal Ext = External Pub = Public + [Int] IBEP20 - [Ext] totalSupply - [Ext] balanceOf - [Ext] transfer # - [Ext] allowance - [Ext] approve # - [Ext] transferFrom # + [Lib] SafeMath - [Int] add - [Int] sub - [Int] sub - [Int] mul - [Int] div - [Int] div - [Int] mod - [Int] mod + Context - [Int] _msgSender - [Int] _msgData + [Lib] Address - [Int] isContract - [Int] sendValue # - [Int] functionCall # - [Int] functionCall # - [Int] functionCallWithValue # - [Int] functionCallWithValue # - [Prv] _functionCallWithValue # + Ownable (Context) - [Pub]
# - [Pub] owner - [Pub] renounceOwnership # - modifiers: onlyOwner - [Pub] transferOwnership # - modifiers: onlyOwner - [Pub] geUnlockTime - [Pub] lock # - modifiers: onlyOwner - [Pub] unlock # + [Int] IUniswapV2Factory - [Ext] feeTo - [Ext] feeToSetter - [Ext] getPair - [Ext] allPairs - [Ext] allPairsLength - [Ext] createPair # - [Ext] setFeeTo # - [Ext] setFeeToSetter # + [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] IUniswapV2Router02 (IUniswapV2Router01) - [Ext] removeLiquidityETHSupportingFeeOnTransferTokens # - [Ext] removeLiquidityETHWithPermitSupportingFeeOnTransferTokens # - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens # - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($) - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens # + PirareCoin (Context, IBEP20, Ownable) - [Pub] # - [Pub] name - [Pub] symbol - [Pub] decimals - [Pub] totalSupply - [Pub] minLottoBalance - [Pub] currentLottoPool - [Pub] balanceOf - [Pub] transfer # - [Pub] allowance - [Pub] approve # - [Pub] transferFrom # - [Pub] increaseAllowance # - [Pub] decreaseAllowance # - [Pub] isExcludedFromReward - [Pub] isIncludeFromLotto - [Pub] totalFees - [Pub] deliver # - [Pub] reflectionFromToken - [Pub] tokenFromReflection - [Pub] excludeFromReward # - modifiers: onlyOwner - [Ext] includeInReward # - modifiers: onlyOwner - [Prv] _transferBothExcluded # - [Ext] setUniswapRouter # - modifiers: onlyOwner - [Ext] setUniswapPair # - modifiers: onlyOwner - [Pub] excludeFromFee # - modifiers: onlyOwner - [Pub] includeInFee # - modifiers: onlyOwner - [Ext] setTaxFeePercent # - modifiers: onlyOwner - [Ext] setLottoFeePercent # - modifiers: onlyOwner - [Ext] setTxgoldFeePercent # - modifiers: onlyOwner - [Ext] setMarketingFeePercent # - modifiers: onlyOwner - [Pub] setshouldSwapToBNB # - modifiers: onlyOwner - [Pub] setLottoEnabled # - modifiers: onlyOwner - [Pub] setTxgoldAddress # - modifiers: onlyOwner - [Pub] setMarketingAddress # - modifiers: onlyOwner - [Pub] setMinLottoBalance # - modifiers: onlyOwner - [Pub] setLotteryThresHold # - modifiers: onlyOwner - [Ext] setLiquidityFeePercent # - modifiers: onlyOwner - [Ext] setMaxTxPercent # - modifiers: onlyOwner - [Pub] setSwapAndLiquifyEnabled # - modifiers: onlyOwner - [Ext] setAntiWhaleEnabled # - modifiers: onlyOwner - [Ext] setAntiWhaleThreshold # - modifiers: onlyOwner - [Ext] setExcludedFromAntiWhale # - modifiers: onlyOwner - [Ext] ($) - [Prv] _reflectFee # - [Prv] _getValues - [Prv] _getTValues - [Prv] _getRValues - [Prv] _getRate - [Prv] _getCurrentSupply - [Prv] addAddress # - [Prv] random - [Prv] lotterize - [Prv] _takeLotto # - [Prv] drawLotto # - modifiers: lockTheLottery - [Prv] _takeTxgold # - [Prv] _takeMarketing # - [Prv] _takeLiquidity # - [Prv] calculateLottoFee - [Prv] calculateTxgoldFee - [Prv] calculateMarketingFee - [Prv] calculateTaxFee - [Prv] calculateLiquidityFee - [Prv] removeAllFee # - [Prv] restoreAllFee # - [Pub] isExcludedFromFee - [Prv] _approve # - [Prv] _transfer # - [Prv] swapAndLiquify # - modifiers: lockTheSwap - [Prv] swapTokensForEth # - [Prv] addLiquidity # - [Prv] _tokenTransfer # - [Prv] _transferStandard # - [Prv] _transferToExcluded # - [Prv] _transferFromExcluded #