BSCWinBulls Token - Smart Contract Audit Report
BSCWinBulls is a new BEP20 token with frictionless fee redistribution that automatically enters users into a lottery for BUSD rewards.
Notes on the Contracts:
- The total supply of 7 million BSCWIN tokens are minted to the owner upon deployment.
- No mint or burn functions exist beyond deployment, though the circulating supply can be decreased by sending tokens to the 0x..dead address.
- At the time of this audit, 10% of the total token supply is held in a wallet.
- An additional 8.1% is held as liquidity in a PancakeSwap liquidity pool.
- Another 5.5% is also held in a wallet.
- There is a liquidity and reflection fee taken during transfers; users on the whitelist are excluded from fees.
- The owner, this contract, and the token storage contract are added to this whitelist on deployment.
- Addresses can be added to a blacklist to prevent them from being eligible for wins, but logical issues allow blacklisted addresses to be determined a winner. We recommend the team add logic to prevent excluded addresses from winning.
- The tokens collected from the liquidity fee are sent to the DAOWallet address.
- 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.
- There is a maximum transfer limit on all transfers unless the owner is the sender or receiver.
- The owner may send any amount of tokens to any address through a presale transfer.
- During the first 30 minutes after launch, transactions may not be larger than 20,000 tokens.
- Token holders are automatically entered into the lottery for a chance to win a reward in BUSD.
- All users are only entered into the lottery once, but owning more tokens results in the user having more tickets and a higher likelihood of meeting the requirements for being a winner, if selected.
- Users are able to trigger the lottery if the start time for the current iteration of the lottery has passed. The caller is paid a reward for triggering the lottery in BSCWIN tokens.
- Triggering the lottery will generate a random number which is used to calculate a potential winner.
- The random number generation uses a somewhat weak source of randomness, potentially allowing outcomes to be determined by miners while a block is being mined. Abuse of this nature on BSC is also much less likely to occur than on the Ethereum chain.
- A user is automatically a winner if they have more tickets than the lottery's assigned difficulty divided by the total number of users.
- Alternatively, if the user is not a winner through the previous method, another random number is generated. If the user has more tickets than the randomly generated number, they are a winner.
- If no winner is determined before the maximum attempts are reached, the address with the most tokens is automatically the winner.
- The lottery rewards are funded by removing liquidity from the PancakeSwap liquidity pool. LP tokens must be provided to the contract to facilitate the liquidity removal.
- If there are no LP tokens in the contract when the lottery is triggered for the first time of the iteration, the trigger will be unable to execute.
- The owner may set the contract as launched only once after deployment.
- The owner may update the minimum amount of tickets required to be entered into the lottery at anytime.
- The owner may update the lottery start times and the percentage of held liquidity used to fund the rewards for each iteration at any time.
- The owner may set the limit for rewards distributed to users who trigger the lottery at any time.
- The owner may reset the iterations of the lottery at any time.
- The owner may change the lottery difficulty at any time.
- The owner may add and remove any address from the blacklist and whitelist at anytime.
- The owner may change the liquidity and tax fee at any time.
- The owner may change the number of tokens per ticket at any time.
- The owner may change the maximum number of tries before defaulting to a winner at anytime.
Audit Findings Summary
- Utilization of SafeMath to prevent overflows.
- As this is used through a proxy contract and there are no time locks in place, the logic implementation may change at any time.
- No external threats were identified.
- Ensure trust in the team as they can change the contract used as the implementation at any time.
- Date: November 21st, 2021.
|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] IERC20 - [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] Constructor # - [Int] setOwnableConstructor # - [Pub] owner - [Pub] renounceOwnership # - modifiers: onlyOwner - [Pub] transferOwnership # - modifiers: onlyOwner + [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 # + [Int] IERC20Metadata (IERC20) - [Ext] name - [Ext] symbol - [Ext] decimals + ERC20 (Context, IERC20, IERC20Metadata) - [Pub] Constructor # - [Int] ERCProxyConstructor # - [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 # + ERCStorage - [Pub] Constructor # - [Pub] sendToken1 # - [Pub] sendLP # - [Pub] sendTokens # + Proxiable - [Int] updateCodeAddress # - [Pub] proxiableUUID + LibraryLockDataLayout + LibraryLock (LibraryLockDataLayout) - [Int] initialize # + DataLayout (LibraryLock) + BSCWinBulls (Context, ERC20, Ownable, Proxiable, DataLayout) - [Pub] Constructor # - modifiers: ERC20 - [Pub] proxyConstructor # - [Pub] updateCode # - modifiers: onlyOwner,delegatedOnly - [Pub] totalSupply - [Pub] balanceOf - [Pub] transferFrom # - [Pub] isExcludedFromReward - [Pub] totalFees - [Pub] sendPresaleTokens # - [Pub] hasLaunched # - modifiers: onlyOwner - [Int] launchLimiter - [Pub] setMinimumLotteryBalance # - modifiers: onlyOwner - [Pub] setLotteryTimes # - modifiers: onlyOwner - [Pub] setCallerRewardLimit # - modifiers: onlyOwner - [Pub] resetTimeIndex # - modifiers: onlyOwner - [Pub] isTimeForLottery - [Pub] nextLotteryTime - [Int] calculatePoolWithdrawal # - [Int] removeLiquidity # - [Pub] triggerLottery # - [Int] payCallerReward # - [Int] lotteryCheck # - [Int] getRandomNumber - [Pub] setLotteryDifficulty # - modifiers: onlyOwner - [Int] didUserWin - [Pub] getWinners - [Pub] getUserWinnings - [Pub] deliver # - [Pub] reflectionFromToken - [Pub] tokenFromReflection - [Pub] excludeFromReward # - modifiers: onlyOwner - [Ext] includeInReward # - modifiers: onlyOwner - [Prv] _transferBothExcluded # - [Pub] excludeFromFee # - modifiers: onlyOwner - [Pub] includeInFee # - modifiers: onlyOwner - [Ext] setRFITaxPercent # - modifiers: onlyOwner - [Ext] setDAOTaxPercent # - modifiers: onlyOwner - [Pub] setSwapAndLiquifyEnabled # - modifiers: onlyOwner - [Ext] Fallback ($) - [Prv] _reflectFee # - [Prv] _getValues - [Prv] _getTValues - [Prv] _getRValues - [Prv] _getRate - [Prv] _getCurrentSupply - [Prv] _takeLiquidity # - [Prv] calculateTaxFee - [Prv] calculateLiquidityFee - [Prv] removeAllFee # - [Prv] restoreAllFee # - [Pub] isExcludedFromFee - [Pub] setTicketDivider # - modifiers: onlyOwner - [Pub] setMaxTries # - modifiers: onlyOwner - [Pub] setCallerRewardPerc # - modifiers: onlyOwner - [Pub] setDAOWallet # - modifiers: onlyOwner - [Pub] setNFTContract # - modifiers: onlyOwner - [Int] _rebalanceTickets # - [Int] _transfer # - [Prv] _tokenTransfer # - [Prv] _transferStandard # - [Prv] _transferToExcluded # - [Prv] _transferFromExcluded #