LambSwapToken - Smart Contract Audit Report

Audit Summary

LambSwapToken Audit Report LambSwapToken ($LST) is a new BEP-20 token on the Binance Smart Chain that is an automatic liquidity providing protocol.

We reviewed the LambSwapToken contract at 0x4fd8cC4CAF509A60dACdb34fa0b290d18d101391 on the Binance Smart Chain mainnet.

Audit Findings

Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: January 26th, 2022.
Updated: February 7th, 2022 to reflect the newly deployed LambSwapToken contract that resolves Findings #1 - #4.

Finding #1 - LambSwapToken - High (Resolved)

Description: Token transfers do not transfer delegates along with the token.
Risk/Impact: Delegatees will retain their votes even if a transfer occurs. This can result in additional votes being created through the use of transfers.
Recommendation: The _transfer() function should add the appropriate _moveDelegates() call.
Resolution: The team has implemented the recommendation above.

Finding #2 - LambSwapToken - High (Resolved)

Description: In the _transfer() function, the tokens collected through fees when buying from Pancakeswap are not deducted from the transfer amount.
			
uint recieveAmount = amount;
...
if(!_isExcludeFromFee[sender] && !_isExcludeFromFee[recipient]) {
  if(sender == PancakeSwapV2Pair){
    // buy fee
    _balances[marketingAddress] += amount.mul(buyFees.marketing).div(100);
    _balances[LPAddress] += amount.mul(buyFees.liquidity).div(100);
    _balances[address(this)] += amount.mul(buyFees.buyback).div(100);
...
}
_balances[recipient] = _balances[recipient].add(recieveAmount);
Risk/Impact: Transfer fees are not funded by the sender but are instead minted to the team's Marketing wallet, Liquidity wallet, and the contract address.
Recommendation: The tokens collected as fees should be deducted from the transfer amount before reducing the sender's balance by the transfer amount.
Resolution: The team has implemented the recommendation above.

Finding #3 - LambSwapToken - Informational (Resolved)

Description: The following functions are declared public, but are never called internally:
			
increaseAllowance, decreaseAllowance, getTotalSellFee, getTotalBuyFee.
Recommendation: These functions can be declared external for additional gas savings.
Resolution: The team has declared these four functions external.

Finding #4 - LambSwapToken - Informational (Resolved)

Description: The setDeveloper() function serves no purpose as the isDeveloper mapping is never used in the contract.
Recommendation: These can be removed to reduce contract size and deployment costs.
Resolution: The team has removed the setDeveloper() function and the isDeveloper mapping.

Contract Overview

  • The $LST token is designed to be a governance token where one token represents one vote.
  • Users may delegate their votes to another address allowing them to vote on behalf of the user.
  • Once votes are delegated, the user must explicitly delegate back to themselves to regain their votes.
  • Users also have the option to delegate through the use of a signed message, allowing for a gasless delegation for the user.

  • Any user can burn their own tokens to reduce the total supply. A user's number of votes will not be reduced after burning tokens.
  • The contract utilizes a Minter role that allows the assigned addresses to mint tokens to any account up to the maximum supply cap of 500 billion tokens.
  • The minter address can manually delegate votes from their own tokens to their own address or another address at any time after the tokens have been minted.
  • At the time of writing this report, the total supply of the token is 39 billion $LST [39,000,000,000].
  • 100% of the total supply belongs to the owner.

  • There is a Liquidity fee, Marketing fee, Buyback fee, and Burn fee charged 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 user is buying from or selling to Pancakeswap during the transfer.
  • A third fee structure can be set by the team to apply different fee percentages for all other transfers that do not involve Pancakeswap.
  • The tokens collected from the Buyback fee during transfers are stored in the contract address balance. Once the threshold value of tokens (determined by the owner) is met, a swap will occur for the purpose of funding Pancakeswap liquidity.
  • Liquidity-adds are funded by selling a portion of the tokens collected as fees (after the threshold number of tokens 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. We recommend that the team locks these newly acquired LP tokens.
  • The tokens collected from the Liquidity fee and Marketing fee are sent to the team's Liquidity wallet and Marketing wallet respectively.
  • The tokens collected from the Burn fee are deducted from the total supply.
  • The contract utilizes the SafeMath library to protect against overflows/underflows along with following the BEP-20 standard.
Ownership Controls:
  • Ownership has not been renounced.
  • The owner can modify the Liquidity fee, Marketing fee, Buyback fee, and Burn fee for all three fee structures to any percentages as long as the total fee percentages combined do not exceed 25%.
  • The owner can exclude and include accounts from transfer fees.
  • The owner can set and update a maximum transaction amount at any time, which will impose a limit to the number of tokens that can be transferred via Pancakeswap.
  • The owner can set the threshold number of tokens that triggers an automatic liquidity add to any value at any time.
  • The owner can manually add/remove accounts from a blacklist which will prevent them from being able to participate in transfers.
  • The owner can add/remove accounts from the Minter role at any time.
  • The owner can withdraw all of the BNB from the contract address at any time.
  • The owner can update the team's Marketing wallet and Liquidity wallet to any addresses at any time.
  • The owner can update the Pancakeswap Router address at any time.

External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of Control
  • The owner can set total fee percentages up to 25%.
  • The owner can mint any amount of tokens up to the 500 billion total supply cap.
  • The owner is the recipient of the LP tokens generated through the automatic liquidity add process.
  • The owner can blacklist any account from being able to participate in transfers.
  • Signed messages require the use of off-chain logic.
  • WARNING
    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
    Logical IssuesN/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

    Function Graph

    BEP20 Token Graph

    Inheritance Chart

    Multi-file Token

    Functions Overview

    												
    ($) = payable function
     # = non-constant function
    
     + [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 #
    
     +  Context 
        - [Int]  #
        - [Int] _msgSender
        - [Int] _msgData
    
     +  Ownable (Context)
        - [Int]  #
        - [Pub] owner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
        - [Int] _transferOwnership #
    
     + [Lib] SafeMath 
        - [Int] add
        - [Int] sub
        - [Int] sub
        - [Int] mul
        - [Int] div
        - [Int] div
        - [Int] mod
        - [Int] mod
    
     + [Lib] EnumerableSet 
        - [Prv] _add #
        - [Prv] _remove #
        - [Prv] _contains
        - [Prv] _length
        - [Prv] _at
        - [Int] add #
        - [Int] remove #
        - [Int] contains
        - [Int] length
        - [Int] at
        - [Int] add #
        - [Int] remove #
        - [Int] contains
        - [Int] length
        - [Int] at
    
     +  LambSwapToken (Context, Ownable)
        - [Ext] getOwner
        - [Ext] decimals
        - [Ext] symbol
        - [Ext] name
        - [Ext] totalSupply
        - [Pub] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
        - [Ext] increaseAllowance #
        - [Ext] decreaseAllowance #
        - [Ext] burn #
        - [Int] _mint #
        - [Int] _burn #
        - [Int] _approve #
        - [Int] _burnFrom #
        - [Pub]  #
        - [Ext] mint #
           - modifiers: onlyOwner
        - [Ext] mint #
           - modifiers: onlyMinter
        - [Ext] setInitialAddresses #
           - modifiers: onlyOwner
        - [Ext] setFeeAddresses #
           - modifiers: onlyOwner
        - [Ext] setLimitTxAmount #
           - modifiers: onlyOwner
        - [Ext] setNumTokensSellToAddToLiquidity #
           - modifiers: onlyOwner
        - [Ext] setBuyFee #
           - modifiers: onlyOwner
        - [Ext] setSellFee #
           - modifiers: onlyOwner
        - [Ext] setTransferFee #
           - modifiers: onlyOwner
        - [Ext] getTotalSellFee
        - [Ext] getTotalBuyFee
        - [Ext] addBlackList #
           - modifiers: onlyOwner
        - [Ext] removeBlackList #
           - modifiers: onlyOwner
        - [Ext] excludeFromFee #
           - modifiers: onlyOwner
        - [Ext] includeInFee #
           - modifiers: onlyOwner
        - [Int] _transfer #
        - [Int] swapAndLiquify #
           - modifiers: lockTheSwap
        - [Int] swapTokensForEth #
        - [Int] addLiquidity #
        - [Ext] withdrawStuckBNB #
           - modifiers: onlyOwner
        - [Ext]  ($)
        - [Ext] delegates
        - [Ext] delegate #
        - [Ext] delegateBySig #
        - [Ext] getCurrentVotes
        - [Ext] getPriorVotes
        - [Int] _delegate #
        - [Int] _moveDelegates #
        - [Int] _writeCheckpoint #
        - [Int] safe32
        - [Int] getChainId
        - [Pub] addMinter #
           - modifiers: onlyOwner
        - [Pub] delMinter #
           - modifiers: onlyOwner
        - [Pub] getMinterLength
        - [Pub] isMinter
        - [Pub] getMinter
           - modifiers: onlyOwner