FLOKI - Smart Contract Audit Report
Audit Summary
FLOKI is building a new BEP20 token with DAO functionality allowing for decentralized governance within the protocol.
For this audit, we reviewed the StaticTaxHandler, TreasuryHandlerAlpha, ZeroTaxHandler, and ZeroTreasuryHandler at commit e94179f25c2e6f28e349763b83beef65ad3187fa on the team's public GitHub and the FLOKI contract at 0xfb5b838b6cfeedc2873ab27866079ac55363d37e on the Binance Smartchain.
We previously reviewed the team's token contract on BSC here, on ETH here and FLOKIDAO contracts on ETH here.
Please ensure trust in the team prior to investing as they have some control in the ecosystem.
Date: January 21st, 2022.
Contracts Overview
FLOKI Contract:TreasuryPool Contract:
- The total supply of the token is initially set to 10 trillion.
- No mint or burn functions exist, though the circulating supply can be decreased by sending tokens to the 0x..dead address.
- At the time of this report, 44.82% of the total supply is held in an OKLGAtomicSwapInstance functioning as the FLOKI bridge.
- 35.09% of the total supply is stored in the 0x..dead address.
- 1.01% of the total supply is held in a FLOKI MultiSig contract.
- A final 0.64% is held in PancakeSwap liquidity.
- There is a tax fee taken on buys and sells from specified "exchange pools" and sent to a Treasury address controlled by the team when neither the sender nor the recipient are whitelisted from fees.
- Addresses on the whitelist are exempt from fees. If either the sender or receiver are exempt, no fees are taken.
- Each FLOKI token additionally represents votes intended to be used in a DAO 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.
- The owner may update the tax and treasury addresses used during fee calculation at any time
StaticTaxHandler Contract:
- This contract is used to send collected fees to the team as well as perform automatic liquidity adds.
- During any sell, the balance of this contract is checked to see if there is any FLOKI collected from fees.
- If there is FLOKI in the contract, the contract will perform an automatic liquidity add.
- First, a check is done whether the contract's token balance is larger than a specified percentage in the "primary exchange". If it is larger, the percentage will be set to the specified percentage.
- A liquidity-add is funded by selling the specified "liquidity percentage" of tokens collected as fees, pairing the received BNB with the token, and adding it as liquidity to the BNB pair.
- Any remaining BNB is sent to a Treasury address controlled by the team.
- The owner may update the liquidity percentage and max allowed percentage for swap and liquify functionality at any time.
- The owner may update the Treasury address at any time.
- The owner may withdraw any ERC20 token in the contract at any time. We recommend the team exclude the designated token from this functionality.
General Notes Across All Contracts:
- This contract is used to manage the FLOKI tax rate as well as exempted addresses.
- The owner may update the tax rate at any time, but the value may only be decreased.
- The owner may add and remove addresses from the whitelist at any time.
- The owner may add and remove addresses as designated exchange pools at any time.
- The owner may set the primary exchange pool at any time.
- If the team wishes to implement the FLOKI token with no fees, they may use the ZeroTreasureHandler and ZeroTaxHandler contracts in place of the TreasuryHandlerAlpha and StaticTaxHandler contracts. These contracts will always return 0 when calculating any tax value.
- As the contracts are implemented in Solidity 0.8.X, they are protected from overflows.
- Proper structuring of logic to prevent reentrancy attacks.
External Threat Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
Centralization of Control | The team has transferred ownership to a MultiSig wallet. | PASS |
Delegate Call to Untrusted Contract | N/A | PASS |
Dependence on Predictable Variables | N/A | PASS |
Deprecated Opcodes | N/A | PASS |
Ether Thief | N/A | PASS |
Exceptions | N/A | PASS |
External Calls | N/A | PASS |
Integer Over/Underflow | N/A | PASS |
Logical Issues | N/A | PASS |
Multiple Sends | N/A | PASS |
Suicide | N/A | PASS |
State Change External Calls | N/A | PASS |
Unchecked Retval | N/A | PASS |
User Supplied Assertion | N/A | PASS |
Critical Solidity Compiler | N/A | PASS |
Overall Contract Safety | PASS |
FLOKI Contract
($) = payable function
# = non-constant function
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ Context
- [Int] _msgSender
- [Int] _msgData
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ [Int] IGovernanceToken
- [Ext] getVotesAtBlock
+ [Int] ITaxHandler
- [Ext] getTax
+ [Int] ITreasuryHandler
- [Ext] beforeTransferHandler #
- [Ext] afterTransferHandler #
+ FLOKI (IERC20, IGovernanceToken, Ownable)
- [Pub] #
- [Pub] name
- [Ext] symbol
- [Ext] decimals
- [Pub] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
- [Ext] increaseAllowance #
- [Ext] decreaseAllowance #
- [Ext] delegate #
- [Ext] delegateBySig #
- [Pub] getVotesAtBlock
- [Ext] setTaxHandler #
- modifiers: onlyOwner
- [Ext] setTreasuryHandler #
- modifiers: onlyOwner
- [Prv] _delegate #
- [Prv] _moveDelegates #
- [Prv] _writeCheckpoint #
- [Prv] _approve #
- [Prv] _transfer #
TreasuryHandlerAlpha Contract
($) = payable function
# = non-constant function
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Int] verifyCallResult
+ [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] _msgSender
- [Int] _msgData
+ Ownable (Context)
- [Pub] Constructor #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ [Lib] EnumerableSet
- [Prv] _add #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Prv] _values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
+ ExchangePoolProcessor (Ownable)
- [Ext] getExchangePoolAddresses
- [Ext] addExchangePool #
- modifiers: onlyOwner
- [Ext] removeExchangePool #
- modifiers: onlyOwner
- [Ext] setPrimaryPool #
- modifiers: onlyOwner
+ LenientReentrancyGuard
- [Pub] Constructor #
+ [Int] ITreasuryHandler
- [Ext] beforeTransferHandler #
- [Ext] afterTransferHandler #
+ TreasuryHandlerAlpha (ITreasuryHandler, LenientReentrancyGuard, ExchangePoolProcessor)
- [Pub] Constructor #
- [Ext] beforeTransferHandler #
- modifiers: nonReentrant
- [Ext] afterTransferHandler #
- modifiers: nonReentrant
- [Ext] setLiquidityPercentage #
- modifiers: onlyOwner
- [Ext] setPriceImpactPercentage #
- modifiers: onlyOwner
- [Ext] setTreasury #
- modifiers: onlyOwner
- [Ext] withdraw #
- modifiers: onlyOwner
- [Prv] _swapTokensForEth #
- [Prv] _addLiquidity #
StaticTaxHandler Contract
($) = payable function
# = non-constant function
+ [Lib] EnumerableSet
- [Prv] _add #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Prv] _values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
+ [Int] ITaxHandler
- [Ext] getTax
+ Context
- [Int] _msgSender
- [Int] _msgData
+ Ownable (Context)
- [Pub] Constructor #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ ExchangePoolProcessor (Ownable)
- [Ext] getExchangePoolAddresses
- [Ext] addExchangePool #
- modifiers: onlyOwner
- [Ext] removeExchangePool #
- modifiers: onlyOwner
- [Ext] setPrimaryPool #
- modifiers: onlyOwner
+ StaticTaxHandler (ITaxHandler, ExchangePoolProcessor)
- [Pub] Constructor #
- [Ext] getTax
- [Ext] setTaxBasisPoints #
- modifiers: onlyOwner
- [Ext] addExemption #
- modifiers: onlyOwner
- [Ext] removeExemption #
- modifiers: onlyOwner
ZeroTaxHandler Contract
($) = payable function
# = non-constant function
+ [Int] ITaxHandler
- [Ext] getTax
+ ZeroTaxHandler (ITaxHandler)
- [Ext] getTax
ZeroTreasuryHandler Contract
($) = payable function
# = non-constant function
+ [Int] ITreasuryHandler
- [Ext] beforeTransferHandler #
- [Ext] afterTransferHandler #
+ ZeroTreasuryHandler (ITreasuryHandler)
- [Ext] beforeTransferHandler #
- [Ext] afterTransferHandler #