GalaxyGoggle - Audit Report

Summary

GalaxyGoggle Audit Report GalaxyGoggle is protocol that uses a treasury to back the value of its token, and includes a staking contract where users can earn rewards.

For this audit, we reviewed the following contracts on the Avalanche blockchain mainnet:

Notes on the Contracts:
TimeERC20Token Contract:
  • This contract defines the GalaxyGoggle ($GG) ERC-20 token.
  • At the time of this audit, the total supply is 1,723,183.519918 $GG tokens.
  • Anyone can burn their own tokens, or tokens they are approved to spend, at any time.
  • The Vault address can mint any amount of tokens to any address at any time.
  • Currently, 86.94% of the total supply is held in the TimeStaking contract, 7.46% is in Joe LP, and 1.08% is held in a TimeBondDepository contract
  • Of the LP tokens, 91.91% is held in the TimeTreasury contract and 6.96% is held by a single wallet.
  • The owner is able to set the Vault address to any address at any time.
  • The contract implements the EIP-2612 standard in order to support permits which allows for gasless approvals to be made via signatures.
  • The contract complies with the ERC-20 token standard.
  • As the contract utilizes the SafeMath library, it is protected against any underflow/overflow attacks.
MEMOries Contract:
  • This contract defines the Staked GalaxyGoggle ($sGG) ERC-20 token.
  • At the time of this audit, the total supply is 141,726,636.198893 $sGG tokens.
  • There are no burn functions present, but anyone can send their tokens to the 0x..dead address at any time, which will reduce the circulating supply.
  • Only the TimeStaking contract address can trigger a rebase, which will increase the total supply based on the profit accumulated in the TimeStaking contract.
  • The newly minted tokens are distributed proportionally amongst holders in a frictionless manner.
  • Currently, 98.1% of the total supply is held in the TimeStaking contract, 0.36% is held in the StakingWarmup contract, and 0.05% is held in the Wrapped sGG token contract
  • The $sGG token should not be added as part of a token pair for any liquidity pool; if the team decides to create a liquidity pool, the sync() function will have to be called on the liquidity pool in order to absorb any tokens earned from the rebase into the liquidity pool.
  • The contract implements the EIP-2612 standard in order to support permits which allows for gasless approvals to be made via signatures.
  • The contract complies with the ERC-20 token standard.
  • As the contract utilizes the SafeMath library, it is protected against any underflow/overflow attacks.
TimeStaking Contract:
  • Anyone can use this contract to stake GalaxyGoggle tokens and earn rewards in Staked GalaxyGoggle ($sGG) tokens.
  • As the contract allows anyone to stake on behalf of any address, users can choose to lock the deposit functionality for their address. Users can unlock deposits for their address at any time.
  • Upon staking, an equivalent amount of $sGG tokens are transferred from the contract to the Warmup contract controlled by the team.
  • Staked funds are locked for a number of epoch periods determined by the project team.
  • The length of each epoch period is determined by the team on deployment and cannot be modified.
  • The epoch can only be advanced by calling the rebase() function.
  • Anyone can manually trigger the rebase() function which will rebase the $sGG token once the end time of the current epoch has elapsed.
  • The rebase() function is called automatically before every stake, and can optionally be called before an unstake.
  • The rebase() function will use the profit collected from the epoch to mint new $sGG tokens which are distributed amongst holders.
  • The profit is effectively the amount of $GG tokens in the contract that are not currently staked.
  • The Distributor contract is called within the rebase() function, which will mint an appropriate amount of $GG tokens to the contract as profit based on the excess reserve amounts in the Treasury contract.
  • The Locker contract address can also contribute a "bonus" amount of $sGG tokens to the profit at any time. As the Locker contract address is currently unset, our team has not provided an assessment of the Locker contract based on security.
  • The Locker contract address can also retrieve any amount of $sGG tokens from the contract, but only up to the amount that it has contributed.
  • In order to unstake, users must first claim their $sGG tokens.
  • Users can only claim once the expiry time of their stake has elapsed.
  • Upon claiming, the contract uses the Warmup contract to transfer staked amount of $sGG tokens plus any tokens earned as reflections to the user.
  • Upon unstaking, the user exchanges their $sGG tokens for an equivalent amount of $GG tokens.
  • The user can emergency withdraw their staked amount of $GG tokens from the contract at any time, forfeiting any $sGG rewards.
  • The Manager address can set the Distributor, Warmup, and Locker contract addresses to any address only one time; Currently, the Distributor and Warmup contract addresses are set and cannot be changed.
  • The Manager address can set the lock period for staked funds to any value at any time.
  • As the contract utilizes the SafeMath library, it is protected against any underflow/overflow attacks.
Distributor Contract:
  • Anyone can use this contract to distribute epoch rewards in $GG tokens to a list of recipient addresses specified within the contract.
  • Each recipient address has its own reward rate, which determines the amount of rewards that are minted to the recipient address.
  • Followed by the distribution, the reward rate of each recipient address is increased or decreased one step at a time, depending on the adjustment settings associated with the recipient address, until the target adjustment rate is met.
  • The Policy address retains control of the contract and can add any recipient address to the distribution list. The project team must exercise caution and as to not add the same recipient address more than once.
  • The Policy address can remove any recipient address from the distribution list at any time. Note that while recipient address and reward rate data is reset, the array which stores the recipient addresses is not re-adjusted to account for the null spaces. Therefore, the project team should exercise caution when adding and removing recipient addresses. As the length of the array can only grow, this could cause the loop processing the addresses to exceed the block gas limit.
  • The Policy address can set reward rate, the target reward rate, and the instruction to increase or decrease the reward rate at any time.
  • The Policy address may propose to transfer the Policy role to any address, but the appointed address must accept the role in order to complete the role transfer.
  • As the contract utilizes the SafeMath library, it is protected against any underflow/overflow attacks.
StakingWarmup Contract:
  • This contract contains a single function that is only intended to be used by the TimeStaking contract in order to transfer any amount of $sGG tokens from the contract to the specified recipient.
  • The team is responsible for ensuring the contract is supplied with enough tokens to support the transfers.
  • As the contract utilizes the SafeMath library, it is protected against any underflow/overflow attacks.
TimeTreasury Contract:
  • Any approved Reserve Depositor can deposit any approved Reserve Token into the Treasury Reserves and receive $GG tokens in a 1:1 ratio in return.
  • Any approved Liquidity Depositor can deposit any approved Liquidity Token into the Treasury Reserves and receive an equivalent value of $GG tokens in return.
  • Any approved Reserve Spender can withdraw any approved Reserve Token from the Treasury Reserves in exchange for $GG tokens in a 1:1 ratio; the $GG tokens are subsequently burned.
  • Any approved Debtor can borrow any approved Reserve Token from the Treasury Reserves against their balance of $sGG tokens.
  • The Debtor can repay their incurred debt using $GG tokens or any approved Reserve Token; if repaid using $GG tokens, they are subsequently burned.
  • Any Liquidity Manager can withdraw Liquidity Tokens from the Treasury Reserves in any amount that exceeds the value of the total supply of $GG tokens.
  • Any Reserve Manager can withdraw value in excess of the value of the total supply of $GG tokens in the form of any token from the Treasury Reserves.
  • Any Reward Manager can mint an amount of $GG tokens to any address up until the value of the tokens in the Treasury Reserve is matched.
  • The Manager can fetch the value of each Reserve and Liquidity token in the Treasury Reserves in order to update the total value of all the tokens in the Reserves.
  • The Manager can queue any address to be added as a Reserve Depositor, Reserve Spender, Liquidity Depositor, Debtor, Reserve Manager, Liquidity Manager, Reward Manager, Reserve Token, or Liquidity Token.
  • After the wait time has elapsed, the Manager must manually trigger the toggle() function in order to add the queued address to the appropriate list.
  • The project team should exercise caution and ensure to only use trusted stablecoins as Reserve Tokens and trusted LP tokens as Liquidity Tokens, or the Treasury Reserve valuation will not be accurate.
  • As the contract utilizes the SafeMath library, it is protected against any underflow/overflow attacks.
TimeBondingCalculator Contract:
  • This contract is intended to be used to provide a valuation for each Liquidity Token asset defined in the Treasury.
  • The valuations are derived by doubling the square root of Uniswap's constant product for reserves in order to account for both assets in the liquidity pair.
  • A portion of the total valuation is returned based on the proportion of LP tokens the user is looking to value to the total supply of the LP tokens.
  • As the contract utilizes the SafeMath library, it is protected against any underflow/overflow attacks.

Audit Findings Summary
  • No security threats from outside attackers were identified.
  • Ensure trust in the team as they have substantial control in the ecosystem.
  • Date: December 21st, 2021

External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of ControlN/APASS
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
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

TimeERC20Token Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function

 + [Lib] EnumerableSet 
    - [Prv] _add #
    - [Prv] _remove #
    - [Prv] _contains
    - [Prv] _length
    - [Prv] _at
    - [Prv] _getValues
    - [Prv] _insert #
    - [Int] add #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at
    - [Int] getValues
    - [Int] insert #
    - [Int] add #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at
    - [Int] getValues
    - [Int] insert #
    - [Int] add #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at
    - [Int] getValues
    - [Int] insert #
    - [Int] add #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at
    - [Int] add #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at

 + [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
    - [Int] sqrrt
    - [Int] percentageAmount
    - [Int] substractPercentage
    - [Int] percentageOfTotal
    - [Int] average
    - [Int] quadraticPricing
    - [Int] bondingCurve

 +  ERC20 (IERC20)
    - [Pub]  #
    - [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 #

 + [Lib] Counters 
    - [Int] current
    - [Int] increment #
    - [Int] decrement #

 + [Int] IERC2612Permit 
    - [Ext] permit #
    - [Ext] nonces

 +  ERC20Permit (ERC20, IERC2612Permit)
    - [Pub]  #
    - [Pub] permit #
    - [Pub] nonces

 + [Int] IOwnable 
    - [Ext] owner
    - [Ext] renounceOwnership #
    - [Ext] transferOwnership #

 +  Ownable (IOwnable)
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner

 +  VaultOwned (Ownable)
    - [Ext] setVault #
       - modifiers: onlyOwner
    - [Pub] vault

 +  TimeERC20Token (ERC20Permit, VaultOwned)
    - [Pub]  #
       - modifiers: ERC20
    - [Ext] mint #
       - modifiers: onlyVault
    - [Pub] burn #
    - [Pub] burnFrom #
    - [Pub] _burnFrom #

MEMOries Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function

 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] mod
    - [Int] mod
    - [Int] sqrrt
    - [Int] percentageAmount
    - [Int] substractPercentage
    - [Int] percentageOfTotal
    - [Int] average
    - [Int] quadraticPricing
    - [Int] bondingCurve

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Prv] _functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Prv] _verifyCallResult
    - [Int] addressToString

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

 +  ERC20 (IERC20)
    - [Pub]  #
    - [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 #

 + [Lib] Counters 
    - [Int] current
    - [Int] increment #
    - [Int] decrement #

 + [Int] IERC2612Permit 
    - [Ext] permit #
    - [Ext] nonces

 +  ERC20Permit (ERC20, IERC2612Permit)
    - [Pub]  #
    - [Pub] permit #
    - [Pub] nonces

 + [Int] IOwnable 
    - [Ext] manager
    - [Ext] renounceManagement #
    - [Ext] pushManagement #
    - [Ext] pullManagement #

 +  Ownable (IOwnable)
    - [Pub]  #
    - [Pub] manager
    - [Pub] renounceManagement #
       - modifiers: onlyManager
    - [Pub] pushManagement #
       - modifiers: onlyManager
    - [Pub] pullManagement #

 +  MEMOries (ERC20Permit, Ownable)
    - [Pub]  #
       - modifiers: ERC20,ERC20Permit
    - [Ext] initialize #
    - [Ext] setIndex #
       - modifiers: onlyManager
    - [Pub] rebase #
       - modifiers: onlyStakingContract
    - [Int] _storeRebase #
    - [Pub] balanceOf
    - [Pub] gonsForBalance
    - [Pub] balanceForGons
    - [Pub] circulatingSupply
    - [Pub] index
    - [Pub] transfer #
    - [Pub] allowance
    - [Pub] transferFrom #
    - [Pub] approve #
    - [Int] _approve #
    - [Pub] increaseAllowance #
    - [Pub] decreaseAllowance #

TimeStaking Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function

 + [Lib] SafeMath 
    - [Int] add
    - [Int] add32
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div

 + [Int] IERC20 
    - [Ext] decimals
    - [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 #
    - [Prv] _functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Prv] _verifyCallResult
    - [Int] addressToString

 + [Lib] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 + [Int] IOwnable 
    - [Ext] manager
    - [Ext] renounceManagement #
    - [Ext] pushManagement #
    - [Ext] pullManagement #

 +  Ownable (IOwnable)
    - [Pub]  #
    - [Pub] manager
    - [Pub] renounceManagement #
       - modifiers: onlyManager
    - [Pub] pushManagement #
       - modifiers: onlyManager
    - [Pub] pullManagement #

 + [Int] IMemo 
    - [Ext] rebase #
    - [Ext] circulatingSupply
    - [Ext] balanceOf
    - [Ext] gonsForBalance
    - [Ext] balanceForGons
    - [Ext] index

 + [Int] IWarmup 
    - [Ext] retrieve #

 + [Int] IDistributor 
    - [Ext] distribute #

 +  TimeStaking (Ownable)
    - [Pub]  #
    - [Ext] stake #
    - [Pub] claim #
    - [Ext] forfeit #
    - [Ext] toggleDepositLock #
    - [Ext] unstake #
    - [Pub] index
    - [Pub] rebase #
    - [Pub] contractBalance
    - [Ext] giveLockBonus #
    - [Ext] returnLockBonus #
    - [Ext] setContract #
       - modifiers: onlyManager
    - [Ext] setWarmup #
       - modifiers: onlyManager

Distributor Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function

 + [Lib] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 + [Lib] SafeMath 
    - [Int] add
    - [Int] add32
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] mod
    - [Int] mod
    - [Int] sqrrt
    - [Int] percentageAmount
    - [Int] substractPercentage
    - [Int] percentageOfTotal
    - [Int] average
    - [Int] quadraticPricing
    - [Int] bondingCurve

 + [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 #
    - [Prv] _functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Prv] _verifyCallResult
    - [Int] addressToString

 + [Int] IPolicy 
    - [Ext] policy
    - [Ext] renouncePolicy #
    - [Ext] pushPolicy #
    - [Ext] pullPolicy #

 +  Policy (IPolicy)
    - [Pub]  #
    - [Pub] policy
    - [Pub] renouncePolicy #
       - modifiers: onlyPolicy
    - [Pub] pushPolicy #
       - modifiers: onlyPolicy
    - [Pub] pullPolicy #

 + [Int] ITreasury 
    - [Ext] mintRewards #

 +  Distributor (Policy)
    - [Pub]  #
    - [Ext] distribute #
    - [Int] adjust #
    - [Pub] nextRewardAt
    - [Pub] nextRewardFor
    - [Ext] addRecipient #
       - modifiers: onlyPolicy
    - [Ext] removeRecipient #
       - modifiers: onlyPolicy
    - [Ext] setAdjustment #
       - modifiers: onlyPolicy

StakingWarmup Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function

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

 +  StakingWarmup 
    - [Pub]  #
    - [Ext] retrieve #

TimeTreasury Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function

 + [Lib] SafeMath 
    - [Int] add
    - [Int] add32
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] mul32
    - [Int] div
    - [Int] div

 + [Lib] Address 
    - [Int] isContract
    - [Int] functionCall #
    - [Prv] _functionCallWithValue #
    - [Prv] _verifyCallResult

 + [Int] IOwnable 
    - [Ext] manager
    - [Ext] renounceManagement #
    - [Ext] pushManagement #
    - [Ext] pullManagement #

 +  Ownable (IOwnable)
    - [Pub]  #
    - [Pub] manager
    - [Pub] renounceManagement #
       - modifiers: onlyManager
    - [Pub] pushManagement #
       - modifiers: onlyManager
    - [Pub] pullManagement #

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

 + [Lib] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Prv] _callOptionalReturn #

 + [Int] IERC20Mintable 
    - [Ext] mint #
    - [Ext] mint #

 + [Int] IOHMERC20 
    - [Ext] burnFrom #

 + [Int] IBondCalculator 
    - [Ext] valuation

 +  TimeTreasury (Ownable)
    - [Pub]  #
    - [Ext] deposit #
    - [Ext] withdraw #
    - [Ext] incurDebt #
    - [Ext] repayDebtWithReserve #
    - [Ext] repayDebtWithOHM #
    - [Ext] manage #
    - [Ext] mintRewards #
    - [Pub] excessReserves
    - [Ext] auditReserves #
       - modifiers: onlyManager
    - [Pub] valueOf
    - [Ext] queue #
       - modifiers: onlyManager
    - [Ext] toggle #
       - modifiers: onlyManager
    - [Int] requirements
    - [Int] listContains

TimeBondingCalculator Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function

 + [Lib] FullMath 
    - [Prv] fullMul
    - [Prv] fullDiv
    - [Int] mulDiv

 + [Lib] Babylonian 
    - [Int] sqrt

 + [Lib] BitMath 
    - [Int] mostSignificantBit

 + [Lib] FixedPoint 
    - [Int] decode
    - [Int] decode112with18
    - [Int] fraction
    - [Int] sqrt

 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] sqrrt

 + [Int] IERC20 
    - [Ext] decimals

 + [Int] IUniswapV2ERC20 
    - [Ext] totalSupply

 + [Int] IUniswapV2Pair (IUniswapV2ERC20)
    - [Ext] getReserves
    - [Ext] token0
    - [Ext] token1

 + [Int] IBondingCalculator 
    - [Ext] valuation

 +  TimeBondingCalculator (IBondingCalculator)
    - [Pub]  #
    - [Pub] getKValue
    - [Pub] getTotalValue
    - [Ext] valuation
    - [Ext] markdown