Sphere Finance

Smart Contract Audit Report

Audit Summary

Sphere Finance Audit Report Sphere Finance is a new ERC-20 token with an elastic supply that performs automatic liquidity adds.

For this audit, we reviewed the project team's SphereToken contract at commit 90c98feaa2b6e51f48caacc90f9021b7661c9c8d on the team's private GitHub repository.

Audit Findings

Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: April 7th, 2022.
Updated: April 8th, 2022 to reflect the changes made from commit fb61c17c21bf04babaa66a7a471145e44851ce44 to commit 90c98feaa2b6e51f48caacc90f9021b7661c9c8d that resolve Findings #1 - #6.

Finding #1 - SphereToken - Low (Resolved)

Description: The Tax bracket functionality calculates users' balances of the Sphere Game token addresses set by the team, however the owner cannot add addresses to this array as the addSphereGamesAddies() function is declared private and is never called.
 function addSphereGamesAddies(address _sphereGamesAddy, bool _value) private {
...
}
Risk/Impact: Users that own a substantial amount of Sphere Game tokens will not be charged the additional sell fee.
Recommendation: All logic involving the Sphere Game addresses should either be removed from the contract or the addSphereGamesAddies() function should be declared public and enforce the onlyOwner() modifier.
Resolution: The team has declared the addSphereGamesAddies() function public along with enforcing the onlyOwner() modifier.

Finding #2 - SphereToken - Low (Resolved)

Description: In the updateLaunchPeriodFee() function, the sellGalaxyBond fee is not included when updating the total sell fee value.
setSellFee(
	totalBuyFee
	.add(sellFeeTreasuryAdded)
	.add(sellFeeRFVAdded)
	.add(sellBurnFee)
	.add(sellLaunchFeeAdded - sellLaunchFeeSubtracted)
);
Risk/Impact: Miscalculations will occur in the swapback() function as the fee denominator will not be accurate.
Recommendation: The sellGalaxyBond fee should be included in the setSellFee() calculation.
Resolution: The team has added the sellGalaxyBond fee to the setSellFee() calculation.

Finding #3 - SphereToken - Informational (Resolved)

Description:The manualSync() function is called twice on all auto-rebases.
function _transferFrom(
...
if (shouldRebase() &&
autoRebase &&
	!automatedMarketMakerPairs[sender] &&
	!automatedMarketMakerPairs[recipient]) {
	_rebase();
	manualSync();
}
...

function coreRebase(int256 supplyDelta) private returns (uint256) {
...
manualSync();
Recommendation: The call to manualSync() can be removed from the _transferFrom() function as manualSync() is called in the coreRebase() function.
Resolution: The team has implemented the above recommendation.

Finding #4 - SphereToken - Informational (Resolved)

Description: The following functions and state variables are redundant in the contract.
Functions: setTaxNonMarketMaker(), setPartyListDivisor(), setPartyIsOver(), isOverLiquified(), getLiquidityBacking()
State Variables: nonMarketMakerFee, taxNonMarketMaker, isPartyOver, partyListDivisor
Recommendation: These functions and state variables should either be removed or utilized in a way that fits the project team's intended functionality.
Resolution: The team has implemented the above recommendation.

Finding #5 - SphereToken - Informational (Resolved)

Description: The following state variables can never be modified, but are not declared constant.
nonMarketMakerFee, oneEEighteen, secondsPerDay, sellLaunchFeeAdded
Recommendation: These state variables should be declared constant for additional gas savings on each call.
Resolution: The team has implemented the above recommendation.

Finding #6 - SphereToken - Informational (Resolved)

Description: The _burnFee local variable is not utilized in the takeFee() function.
Recommendation: This local variable can be removed to reduce contract size and deployment costs.
Resolution: The team has removed the _burnFee local variable from the takeFee() function.

Contract Overview

  • The initial supply is set to 5 billion tokens and will be minted to the owner upon deployment.
  • The maximum supply of is 340,282,366,920,938,463,463,374,607,431,768,211,455 tokens.
  • No mint or burn function are present in the contract; though the circulating supply can be decreased by sending tokens to the 0x..dead address.

  • The initial distribution period of the contract must be manually disabled by the owner in order for all trading to take place on the platform. Only users excluded by the owner are able to transfer tokens while the initial distribution period is enabled.
  • The contract enforces a maximum sell amount and a maximum buy amount (both determined by the owner) that imposes a limit to the number of tokens that can be transferred via QuickSwap in a single transaction.
  • The maximum sell amount will only be enforced if the contract's party functionality is enabled by the team and the sender belongs to the list of party addresses.
  • The owner can add accounts to the party list at any time. These accounts will be taxed at a 49% rate on all transfers.
  • The contract features an Anti-whale mechanism that prevents a user from selling more than the limit number of tokens (determined by the owner) in a 1 hour period.
  • There is a Liquidity fee, Treasury fee, RFV fee, Galaxy Bond fee, and Burn fee on all transfers via QuickSwap where neither the sender nor the recipient is excluded from fees.
  • The contract charges an extra 10% fee on sell transactions via QuickSwap. This fee is decreased by 5% every 48 rebases.
  • When the Tax bracket functionality is enabled by the team, fees are increased for users that hold over the limit number of combined tokens for the $SPHERE token and the token contracts (set by the owner) in proportion to the current number of $SPHERE tokens in liquidity.
  • The fees charged during transfers are stored in the contract address. The tokens are swapped for WMATIC for the purpose of funding QuickSwap liquidity when the following conditions are met:
    • The automatic liquidity add functionality is enabled by the team.
    • The threshold number of tokens in the contract address (determined by the owner) has been reached.
    • The contract is not currently performing an automatic liquidity add.
    • The caller is not initiating a buy transaction via QuickSwap.
    • Total fees are set to any value other than zero.
  • Liquidity-adds are automatically performed by selling the tokens collected as fees, pairing the received WMATIC with the token, and adding it as liquidity to the WMATIC pair.
  • The LP tokens received through this process are sent to the Liquidity wallet controlled by the team. We recommend that the team lock these newly acquired LP tokens.
  • The owner can elect to pair the token with the Stable Coin address set by the team for automatic liquidity adds.
  • The tokens collected from the RFV fee are either swapped for WMATIC or the Stable Coin (determined by the owner) and sent to the team's RFV wallet.
  • The tokens collected from the Galaxy Bond fee are swapped for the Stable Coin and sent to the team's Galaxy Bond wallet.
  • The tokens collected from the Burn fee are sent to the 0x..dead address.
  • The remaining tokens in the contract are swapped for WMATIC and sent to the team's Treasury wallet.
  • Also during transfers, if the "next-rebase" time has passed and auto rebase is enabled, tokens are automatically added to the total supply. The newly added tokens are distributed proportionally amongst holders in a frictionless manner.
  • The number of tokens added is dependent on the current total supply, and the ratio between the "reward yield" and the "reward yield denominator"; this ratio defaults to ~0.039% of the current total supply.
  • The rebase function calls sync() on the QuickSwap Pair contract to prevent theft-of-liquidity attacks that have occurred with other rebase tokens.
  • The contract utilizes SafeMath libraries to prevent any overflows/underflows.
Ownership Controls:
  • The owner can add accounts to an Authorized Rebase whitelist. The assigned addresses can trigger a manual rebase if the next-rebase time has passed.
  • The owner can set total transfer fees up to 25% at any time.
  • The owner can exclude accounts from transfer fees.
  • The owner can enable/disable the Anti-whale mechanism at any time.
  • The owner can set Anti-whale limit number of tokens to any value greater than 1.5 million.
  • The owner can set the Anti-whale cool-down period to any value up to 2 hours (in seconds).
  • The owner can add/remove accounts from the party list at any time.
  • The owner can enable/disable the party mechanism at any time.
  • The owner can pause all trading for non-excluded users at any time.
  • The owner can add any address as an automated market maker pair at any time.
  • The owner can enable/disable automatic liquidity adds at any time.
  • The owner can manually trigger a liquidity add at any time.
  • The owner can toggle whether the SPHERE token is paired with MATIC or the Stable Coin for automatic liquidity adds.
  • The owner can update the threshold number of tokens that triggers an automatic liquidity add to any value at any time.
  • The owner can set the target liquidity to any value at any time.
  • The owner can update the Stable Coin address to any address at any time.
  • The owner can update the team's Liquidity wallet, Treasury wallet, and RFV wallet to any addresses at any time.
  • The owner can enable/disable the Tax bracket functionality at any time.
  • The owner can add addresses to the list of token addresses that are used in the Tax bracket functionality.
  • The owner can set the Tax bracket fee multiplier to any value up to 50 at any time.
  • The owner can withdraw any MATIC or tokens (besides $SPHERE) from the contract at any time.
  • The owner can enable/disable the auto-rebase mechanism at any time.
  • The owner can enable/disable the token burning functionality at any time.
  • The owner can update the reward yield and the reward yield denominator to any values at any time.
  • The owner can enable/disable charging fees on peer-to-peer transfers at any time.
  • The owner can set the maximum buy and sell amounts to any values above 2.5 million tokens.
  • The owner can update the rebase frequency and the next-rebase timestamp at any time.

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Jump/Storage WriteN/APASS
Centralization of Control
  • The team maintains the ownership controls listed above.
  • The LP tokens generated through automatic liquidity adds are sent to the team's Liquidity wallet.
WARNING
Compiler IssuesN/APASS
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Ether/Token TheftN/APASS
Flash LoansN/APASS
Front RunningN/APASS
Improper EventsN/APASS
Improper Authorization SchemeN/APASS
Integer Over/UnderflowN/APASS
Logical IssuesN/APASS
Oracle IssuesN/APASS
Outdated Compiler VersionN/APASS
Race ConditionsN/APASS
ReentrancyN/APASS
Signature IssuesN/APASS
Unbounded LoopsN/APASS
Unused CodeN/APASS
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

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

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

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

 + [Int] InterfaceLP 
    - [Ext] sync #

 + [Lib] Roles 
    - [Int] add #
    - [Int] remove #
    - [Int] has

 +  ERC20Detailed (IERC20)
    - [Pub]  #
    - [Pub] name
    - [Pub] symbol
    - [Pub] decimals

 + [Int] IDEXRouter 
    - [Ext] factory
    - [Ext] WETH
    - [Ext] addLiquidity #
    - [Ext] addLiquidityETH ($)
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
    - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
    - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #

 + [Int] IDEXFactory 
    - [Ext] createPair #

 + [Int] IBalanceOfSphere 
    - [Ext] balanceOfSphere

 + [Int] IPublicBalance 
    - [Ext] balanceOf

 + [Int] IDexPair 
    - [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 #

 +  Ownable 
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 +  SphereToken (ERC20Detailed, Ownable)
    - [Pub]  #
       - modifiers: ERC20Detailed
    - [Ext]  ($)
    - [Ext] totalSupply
    - [Ext] allowance
    - [Pub] balanceOf
    - [Pub] markerPairAddress
    - [Pub] currentIndex
    - [Ext] checkFeeExempt
    - [Ext] checkSwapThreshold
    - [Int] shouldRebase
    - [Int] shouldBurn
    - [Int] isStillLaunchPhase
    - [Int] isTaxBracket
    - [Int] shouldTakeFee
    - [Int] shouldSwapBack
    - [Pub] getGonBalances
    - [Pub] getCirculatingSupply
    - [Pub] getCurrentTimestamp
    - [Pub] getLiquidityBacking
    - [Pub] getUserTotalOnDifferentContractsSphere
    - [Pub] getBalanceOfAllSubContracts
    - [Pub] getBalanceOfAllSphereGamesContracts
    - [Pub] getTokensInLPCirculation
    - [Pub] getOneTokenInLPCirculation
    - [Pub] getCurrentTaxBracket
    - [Pub] isOverLiquified
    - [Pub] manualSync #
    - [Ext] transfer #
       - modifiers: validRecipient
    - [Int] _basicTransfer #
    - [Int] _transferFrom #
    - [Ext] transferFrom #
       - modifiers: validRecipient
    - [Prv] _swapAndLiquify #
    - [Prv] _addLiquidity #
    - [Prv] _addLiquidityStableCoin #
    - [Prv] _swapTokensForMATIC #
    - [Prv] _swapTokensForStableCoin #
    - [Int] swapBack #
       - modifiers: swapping
    - [Ext] manualSwapBack #
       - modifiers: onlyOwner
    - [Int] takeFee #
    - [Prv] tokenBurner #
    - [Ext] decreaseAllowance #
    - [Ext] increaseAllowance #
    - [Ext] approve #
    - [Prv] _rebase #
    - [Prv] coreRebase #
    - [Ext] setRebaseWhitelist #
       - modifiers: onlyOwner
    - [Pub] manualRebase #
    - [Prv] updateRebaseIndex #
    - [Prv] updateLaunchPeriodFee #
    - [Pub] addSubContracts #
       - modifiers: onlyOwner
    - [Prv] addSphereGamesAddies #
    - [Pub] addPartyAddies #
       - modifiers: onlyOwner
    - [Pub] setAutomatedMarketMakerPair #
       - modifiers: onlyOwner
    - [Ext] setInitialDistributionFinished #
       - modifiers: onlyOwner
    - [Ext] setPartyListDivisor #
       - modifiers: onlyOwner
    - [Ext] setFeeExempt #
       - modifiers: onlyOwner
    - [Ext] setTaxNonMarketMaker #
       - modifiers: onlyOwner
    - [Ext] setTargetLiquidity #
       - modifiers: onlyOwner
    - [Ext] setSwapBackSettings #
       - modifiers: onlyOwner
    - [Ext] setFeeReceivers #
       - modifiers: onlyOwner
    - [Ext] setFees #
       - modifiers: onlyOwner
    - [Int] setSellFee #
    - [Ext] setStablecoin #
       - modifiers: onlyOwner
    - [Ext] setPartyIsOver #
       - modifiers: onlyOwner
    - [Ext] setTaxBracketFeeMultiplier #
       - modifiers: onlyOwner
    - [Ext] clearStuckBalance #
       - modifiers: onlyOwner
    - [Ext] rescueToken #
       - modifiers: onlyOwner
    - [Ext] setAutoRebase #
       - modifiers: onlyOwner
    - [Ext] setBurnFee #
       - modifiers: onlyOwner
    - [Ext] setLaunchPeriod #
       - modifiers: onlyOwner
    - [Ext] setTaxBracket #
       - modifiers: onlyOwner
    - [Ext] setRebaseFrequency #
       - modifiers: onlyOwner
    - [Ext] setRewardYield #
       - modifiers: onlyOwner
    - [Ext] setFeesOnNormalTransfers #
       - modifiers: onlyOwner
    - [Ext] setIsLiquidityInMATIC #
       - modifiers: onlyOwner
    - [Ext] setNextRebase #
       - modifiers: onlyOwner
    - [Ext] setMaxSellTransaction #
       - modifiers: onlyOwner
    - [Ext] setMaxBuyTransactionAmount #
       - modifiers: onlyOwner

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.