Reboot

Smart Contract Audit Report

Audit Summary

Reboot Audit Report Reboot is a new platform which allows users to create and play games against one another to earn rewards.

For this audit, we reviewed Reboot's contracts at commit 4ddd86c23f0381ad1350fc1ed6457b5d8effac24 on the team's private GitHub repository.

We previously reviewed the project team's GG Token contract here.

Audit Findings

A High finding remains and the team must resolve this issue. In addition, centralized aspects are present.
Date: September 15th, 2023.
Updated: October 2nd, 2023 to reflect changes addressing findings from commit ce06ce137de467c00825aba5d6aab16650938e10 to commit 1384310431c219fe56912bfd242d8b9ca9dce672.
Updated: October 17th, 2023 with additional Dust, CommunityPool, and DotStaking contracts.
Updated: November 29th, 2023 to reflect changes from commit 1384310431c219fe56912bfd242d8b9ca9dce672 to commit bec9009670667cd6562d61504903b27d64d24e51.
Updated: December 1st, 2023 to reflect changes to the RewardPool contract from commit bec9009670667cd6562d61504903b27d64d24e51 to commit 70ede4f871da3c4d758be5e8c46759c593c28fd0.
Updated: December 15th, 2023 to reflect changes from commit 70ede4f871da3c4d758be5e8c46759c593c28fd0 to commit 6cd01113d6cb63ff2db52e9e6d5fd76436c12ba1.
Updated: December 27th, 2023 to resolve findings and reflect changes to GGVesting, RebootGovernor, and the contracts within the Swapper folder from commit 6cd01113d6cb63ff2db52e9e6d5fd76436c12ba1 to commit 4ddd86c23f0381ad1350fc1ed6457b5d8effac24.

Finding #1 - TokenMarket - High (Resolved)

Description: Tickets are burned from the user specified _receivingAddress in the purchase() function without checking for proper allowance.
Risk/Impact: A malicious user can use another user's Tickets to purchase MItems without their approval.
Recommendation: The team should check the user's allowance before burning Tickets.
Resolution: The team now enforces that users must buy tickets for themselves and can no longer specify another user's address.

Finding #2 - CreditBundle - High (Resolved)

Description: Upon purchasing a bundle, if the user has not provided enough ETH via msg.value, the remaining funds may be supplemented with the recipient's stored ETH balance in the contract.
Risk/Impact: Users can make purchases on behalf of other users, using their stored ETH without an approval.
Recommendation: Purchasing bundles should be supplemented with the caller's stored ETH rather than the receiver's stored ETH.
Resolution: The team has implemented the above recommendation.

Finding #3 - CreditBundle - High (Resolved)

Description: Upon calculating the total price, the total credits are multiplied by the price of 1 GG token in ETH.
Risk/Impact: The total price calculation will be incorrect as this calculation assumes that 1 Credit equals 1 GG token.
Recommendation: The team must convert the total credits to a GG value using creditGGTValue() from the Credits contract before multiplying it by the GG price.
Resolution: The team has implemented the above recommendation.

Finding #4 - RewardPool - High (Updated)

Description: An auction can be ended on the same block that a bid is made.
Risk/Impact: A malicious validator or bot can manipulate transaction ordering to execute their bid first at the end block of an auction in order to win the auction.
Recommendation: An auction's end block should be extended if a bid is made close to the end of an auction.
Resolution: The Arbitrum Sequencer is currently maintained by the Arbitrum foundation which largely reduces any risk of malicious sequencing, but in the future the Sequencer will be replaced by a distributed committee of Sequencers who come to consensus on transaction ordering.

Finding #5 - Credits - High

Description: The purchaseCreditsInGG function allows users to pass in any amount of GG tokens in order to purchase an equivalant amount of Credits. Considering that the amount of GG tokens the user passes in may not be a multiple of the amount of GG tokens needed to create one Credit, the team attempts to store any excess tokens as the _mintTo address's remainderBalance. However, only the exact amount of tokens needed to purchase Credits will only be transferred to the contract while the user's remainderBalance may be unjustifiably increased.
Risk/Impact: Users may pass in an amount of GG tokens that is the smallest unit under the amount needed to purchase at least 2 Credits. Only the necessary tokens to purchase the Credits will be transferred from the user to the contract, while the difference between the amount of GG tokens passed in and the GG tokens actually used will be added to the _mintTo address's remainderBalance. This amount can be as much as the cost of 1 Credit in GG tokens minus the smallest unit of GG token. The user can then withdraw the remainder balance as profit.
Recommendation: Since only the exact amount of GG tokens needed to purchase Credits are transferred from the payer to the contract, there is no need to keep track of any remainderBalance as there will never be any remaining tokens left in the contract. The project team should remove any logic related to the remainderBalance mapping as well as the function to withdraw the remainderBalance.
Resolution: The team has not yet addressed this issue.

Finding #6 - MItems & Tickets - High

Description: These contracts allow users to maintain their voting power when minting MItems and Tickets. The tokens are transferred to the contract and the associated votes are moved as well. However, users are minted the same amount of votes so that they can retain their voting power while the tokens are in the contract. As a result the tokens represent two sets of votes, the ones held by the contract and the ones held by the user. These contracts also support transferring tokens across chains using LayerZero. When transferring across chain, the tokens and corresponding votes are burned from the contract but the votes previously minted to the user are not burned.
Risk/Impact: Users will retain votes when moving their tokens across chains using the MItems burnBatch() function and the Tickets burnToExtract() function. These users will have votes that they are not entitled to, and the receiver of the tokens on the recipient chain will have the same amount of votes. This will create double voting power for these tokens.
Recommendation: The team should remove the voting power from the user in the MItems burnBatch() function and the Tickets burnToExtract() function using the GG moveVotingPower() function.
Resolution: The team has not yet addressed this issue.

Finding #7 - RewardPool - Medium (Resolved)

Description: ETH to GG token swaps used for payouts are susceptible to frontrunning.
Risk/Impact: The GG price can be artificially increased before a swap using a flashloan, requiring the contract to swap more ETH than intended.
Recommendation: A price oracle such as a TWAP should be used in order to determine the expected amounts to swap.
Update: This issue is no longer present as a result of the updated functionality of the RewardPool contract.

Finding #8 - PowPunksVesting - Medium (Resolved)

Description: Upon releasing vested tokens, the GG tokens are transferred to the caller, but the voting power associated with those tokens in the ggVotes contract is not revoked from the user. Instead, additional voting power is granted to the contract address.
Risk/Impact: Since the voting power is assigned to the beneficiary upon registering a stake, the user will end up with double the intended voting power for the vested tokens, and extra voting power will be assigned to the contract address.
Recommendation: The voting power associated with released tokens should not be minted to the contract, but should be revoked from the user in the GGT contract.
Resolution: The team has updated the voting system, and in doing so votes are now properly revoked from the user as GG tokens and their associated votes are transferred from the contract to the user.

Finding #9 - CreditBundle - Medium (Resolved)

Description: Upon claiming or purchasing bundles, the amount of bundles available for sale is not checked to ensure that it is never exceeded.
Risk/Impact: Although individual users cannot purchase more than the maximum they are allowed to purchase, the amount of bundles purchased across all users may exceed the amount of bundles available for sale. As a result, more voting power than intended may be allocated away from the dev wallet. In addition, the bundle will not be able to be deleted.
Recommendation: The team should enforce that the number of bundles purchased does not exceed the number of bundles available.
Resolution: The team has implemented the above recommendation.

Finding #10 - RewardPool - Medium (Resolved)

Description: There is no minimum bidding increment for auction participants.
Risk/Impact: Users can bid a negligible amount more than the existing top bidder in order to become the new top bidder.
Recommendation: A minimum bidding increment should be added to prevent bidding wars with negligible increments.
Resolution: The team has implemented the above recommendation.

Finding #11 - RebootGovernor - Low (Resolved)

Description: The quorum needed to pass a proposal is initially set to 0.
Risk/Impact: A malicious user could propose an action immediately after the contract is deployed. They can then execute this action if the quorum is not updated before the voting delay elapses.
Recommendation: The team should set a non-zero initial quorum.
Resolution: The team now sets the voting delay, voting period and proposal threshold upon deployment.

Finding #12 - GameCard - Low (Resolved)

Description: The setSkin() function does not check the GameCard's enabledSkins.
Risk/Impact: Users can set their currentSkin to any skin regardless of whether it is enabled for their GameCard.
Recommendation: The team should check the GameCard's enabledSkins in the setSkin() function.
Resolution: Users can now only select skins that have been enabled for their GameCard.

Finding #13 - CommunityPool - Low (Resolved)

Description: The project utilizes LayerZero to allow for cross-chain functionality. A sharedDecimals value is used to truncate token amounts during a transfer to support the LayerZero architecture. The batchClaim() function is truncating the reward amount for a non-LayerZero transfer.
Risk/Impact: This will result in the wrong amount of tokens being transferred for a LayerZero transfer.
Recommendation: The batchClaim() function should instead truncate the reward amount when the chainId is not the novaChainId.
Resolution: The team has implemented the above recommendation.

Finding #14 - NonblockingLzApp - Informational (Resolved)

Description: Since failed messages are not stored upon failure, the retryMessage() function will revert every time.
Recommendation: The team should consider if they want to make use of this functionality, and remove it if it is not needed.
Resolution: Failed messages are now stored appropriately.

Contracts Overview

  • The contracts are implemented using an AccessControl permission scheme.
  • This allows the team to implement various "roles" within the contract with each role having potentially different permissions.
  • The Relayer role may perform most functionality on the behalf of users.
  • The LZ Endpoint contract is not in scope for this audit, so our team is unable to provide an assessment with regards to security.
Credits Contract:
  • This contract is used to exchange GG tokens for game credits to be used throughout the platform.
  • The Factory Controller address can set the game address associated with a credit id, and the credit id associated with a game address, at any time.
  • The Factory Controller address can grant the Game Role to any address at any time.
  • The Credit Minter Role can mint any amount of credits for any game (except for the universal credit) to any address as long as the protocol is not paused.
  • Upon minting credits, an amount of GG tokens equivalent to the amount of credits being minted are transferred from the caller to the contract.
  • The GG value of a credit is determined by the team upon deployment.
  • The Credit Bundle Contract address can use this contract to mint credits for any game to any user as long as the protocol is not paused, without supplying GG tokens or assigning voting power.
  • The Relayer role can use this contract to purchase universal credits as long as the protocol is not paused.
  • Credits can be purchased with tickets or GG tokens.
  • Upon paying with tickets, the tickets are burnt and the underlying GG tokens are sent to the contract.
  • Upon paying with GG tokens, the tokens are sent to the contract.
  • Any address with the Protocol role can use this contract to purchase universal credits with GG tokens without assigning voting power as long as the protocol is not paused.
  • Any address with the Controller role can burn credits for any game from any specified user as long as the protocol is not paused.
  • Upon burning credits, the underlying GG tokens are transferred back to the user.
  • Anyone can use this contract to convert credits they own for any game to universal credits as long as the protocol is not paused.
  • Any address with the Relayer role can convert credits for any game from any account to universal credits as long as the protocol is not paused.
  • The Game role can use this contract to burn any amount of credits from any user as long as the protocol is not paused; credits may be supplemented with the user's universal credits if needed.
  • Upon releasing credits, the underlying GG tokens are transferred to the AMM contract.
  • The Governor can set the CreditBundle and ProtocolDirectory contract addresses to any address at any time.
CreditBundle Contract:
  • This contract is used to support a marketplace for bundles of credits.
  • Anyone can create a new Credit Bundle offering at any time.
  • Upon creating a new Credit Bundle, an amount of GG tokens equivalent to the amount of credits to be included in the bundle is transferred from the bundle creator (dev wallet) to the Credits contract.
  • The Dev Wallet associated with a bundle can activate or deactivate their existing bundle at any time.
  • The Dev Wallet associated with a bundle can delete their bundle at any time.
  • Upon deleting a bundle, the GG tokens underlying any remaining credits in the bundle are transferred from the Credits contract to the bundle's dev wallet.
  • Users can claim any bundle they have been approved for at any time, as long as the bundle is still active.
  • Upon claiming a bundle, the voting power associated with the bundle's underlying GG tokens is moved from the bundle's dev wallet address to the specified address, and the credits are subsequently minted to the specified user in the Credits contract.
  • Active bundles can be purchased as long as the user qualifies for purchasing the bundle; purchase qualifications are determined by calling a function on a permission query contract set by the bundle's dev wallet.
  • Users cannot purchase more than the maximum purchasable per wallet, as set by the bundle's dev wallet.
  • Upon calculating the final price, any bundle discounts are applied; the contract uses a Price Feed to retrieve the price of GG tokens in ETH.
  • Users must provide an amount of ETH in order to purchase bundles; ETH may be supplemented with the user's ETH balance stored in the contract if needed.
  • After the payment is processed, the voting power associated with the GG tokens underlying the credits is moved to the specified address, and the bundle credits are minted to the user in the Credits contract.
  • Users are also able to purchase bundles from L1; in this case, the function will never revert but will credit any ETH to the appropriate accounts if needed.
  • Anyone can withdraw any ETH in the contract that is allocated to them at any time.
  • The Admin can withdraw any ETH from the contract at any time.
Tickets Contract:
  • This contract defines ERC-1155 Ticket tokens which can be used throughout the Platform.
  • Ticket tokens are soulbound and cannot be transferred.
  • Any address with the Protocol role may mint Ticket tokens on the behalf of users by supplying GG tokens.
  • Each Ticket type is associated with its own "tickets per GG" rate and will provide Ticket tokens at that rate per supplied GG token.
  • Users may burn their Tickets for the underlying GG tokens when the protocol is not paused.
  • If the specified chain ID is the "Nova Chain ID" users will be transferred GG tokens equal to the underlying tokens for the Tickets burned.
  • Otherwise the underlying amount of GG tokens will be relayed to the LZEndpoint.
  • Any address with the Protocol role may burn users' Ticket tokens for the underlying GG tokens at any time.
  • Users may optionally burn any specified extractors whitelisted in the Game contract during any burn.
  • Any address with the Protocol role may perform a "burn and transfer sale".
  • This will burn the specified amount of Tickets for a specified address and Ticket ID.
  • The underlying GG tokens will be split between 4 specified receiver addresses.
  • The share between each address is also specified by the Protocol address with any remaining tokens going to the 4th address.
  • The FactoryController address may set the tickets per GG rate for any Ticket ID once per ID when the Protocol is not paused.
  • The Governor or Directory address may give an approval to the current GG tokens address defined in the Directory contract at any time.
  • The Governor or Directory address may set the base URI at any time.
  • The Governor or Directory address may set the Nova Chain ID and adapter params at any time.
UItems Contract:
  • This contract defines UItem NFTs which can be used throughout the Platform.
  • Each UItem NFT is associated with a corresponding item type and collateral amount.
  • UItem NFTs are soulbound and cannot be transferred.
  • Any address with the Rewards role may mint any amount of NFTs when the Protocol is not paused.
  • The specified amount of GG tokens will be distributed across the minted NFTs as collateral with any leftover collateral given to the last NFT minted.
  • The GG tokens will be transferred to the contract and the associated voting power transferred to a specified address.
  • Users may burn their own UItem NFTs when the Protocol is not paused and they have no active Game sessions.
  • An address with the Relayer role may burn UItem NFTs on behalf of users when the Protocol is not paused.
  • Users are minted Ticket tokens corresponding to the amount of collateral associated with the burned NFT and the current "tickets per GG" of the specified Ticket.
  • The GG tokens deposited as collateral are transferred to the Tickets contract.
  • Users' Ticket tokens will be used to purchase an MItem NFT.
  • Users specify a maximum price to purchase the MItem NFT.
  • Any address may give the Tickets address a maximum allowance for GG tokens when the Protocol is not paused.
MItems Contract:
  • This contract defines MItem NFTs which can be used throughout the Platform.
  • The Token Market address may mint any amount of MItem NFTs to any address at any time.
  • The specified amount of collateral will be distributed across the minted NFTs with any leftover collateral given to the last NFT minted.
  • Any address with the Controller role may "craft" when the Protocol is not paused.
  • The specified MItem NFTs will be burned from the user with new MItem NFTs being minted in return.
  • Users may burn their own MItem NFTs when the protocol is not paused.
  • The GItems address and any address with the Relayer role may burn MItems on the behalf of a user when the protocol is not paused.
  • The specified Extractors that are also whitelisted in the Game contract will additionally be burned.
  • The user will be credited with the amount of collateral associated with the MItem NFT.
  • The MItem NFTs will not be burned if the function caller is the GItems address.
  • If the specified chain ID is the "Nova Chain ID" users will be transferred GG tokens corresponding to the total collateral associated with all burned tokens but the voting power associated with those tokens will be forfeited.
  • Otherwise the amount of GG tokens will be relayed to the LZEndpoint.
  • Users may "wrap" an MItem NFT when the Protocol is not paused.
  • This will burn the NFT from the user and perform a wrap in the GItems contract.
  • The GItems address may "unwrap" MItem NFTs at any time. This will update the corresponding item ID and collateral associated with an NFT's ID and subsequently mint the specified user a new MItem NFT.
  • The Governor or Directory address may withdraw any GG tokens not accounted for by this contract.
  • The Governor or Directory address may set the Nova Chain ID and adapter params at any time.
GItems Contract:
  • This contract defines GItem NFTs which can be used throughout the Platform.
  • GItem NFTs are soulbound and cannot be transferred.
  • GItem NFTs are each associated with an MItem NFT.
  • The MItems address may wrap tokens at any time. This will mint the specified user a GItem NFT and set the associated MItem for the NFT.
  • Users may burn their GItem NFTs for the underlying GG tokens if they have no active sessions in the Game contract and the Protocol is not paused.
  • Any address with the Relayer role may also burn GItem NFTs on the behalf of a user.
  • Burning GItem NFTs will also burn the Extractors associated with the GItem's corresponding MItem NFT.
  • Users may unwrap their GItem NFTs if they have no active sessions in the Game contract and the Protocol is not paused.
  • Any address with the Relayer role may also unwrap GItem NFTs on the behalf of a user.
  • This will burn the specified GItem NFTs from the user and perform an unwrap in the MItems contract.
  • The MItems address may be set once after deployment.
Extractors Contract:
  • This contract defines ERC-1155 Extractor tokens.
  • Each Extractor token ID is associated with its own current supply and its own "GG per extractor".
  • Any address with the Protocol role may mint any amount of tokens to any address at any time.
  • Any address with the Protocol role may burn any amount of tokens from any address at any time.
  • The FactoryController address may set the GG per extractor for a specified token ID at any time.
  • The Governor or Directory address may set the base URI at any time.
TokenMarket Contract:
  • This contract allows users or an address with the Protocol Role to purchase MItem NFTs by supplying Ticket tokens.
  • Each MItem address is associated with a Token Sale.
  • Any address with the Admin role for a valid MItems address may create a Token Sale when the Protocol is not paused.
  • A Token Sale can have either a logistic or linear price curve.
  • Users may purchase specified active MItem NFTs that are also whitelisted in the Game contract when the Protocol is active.
  • Users must pass a "permission check" from the Token Sale's "Permission Query Contract" if the MItem NFT's corresponding Token Sale is "allow list only".
  • The total amount of sold tokens may not exceed the "max sellable" amount if the Token Sale is a linear price curve.
  • The token price will vary over either a linear or logistic curve based on the corresponding Token Sale curve type.
  • Users may specify a "max price" that the total cost of the MItem NFTs cannot exceed.
  • The total cost of Ticket tokens will be burned from the user. The Ticket's underlying GG will be split between a Dev Share address, a Protocol Fee address, and potentially an Affiliate address if one is defined in the AffiliateRegistry contract.
  • Any remaining tokens after each share is taken will be transferred to the MItem address.
  • The Governance address may set the Protocol Fee Receiver address and their share percent at any time.
  • The Governance address may set the maximum dev share percent at any time.
  • The Controller Role can grant the Protocol Role to any address at any time.
  • Any address with the Admin role for an MItems address may toggle whether the sale is active and allow list only at any time.
  • Any address with the Admin role for an MItems address may set the Dev Share address and corresponding percentage at any time.
GameCard Contract:
  • This contract defines GameCard NFTs which can be used throughout the Platform.
  • GameCard NFTs are soulbound and cannot be transferred.
  • Users may only have one GameCard.
  • Any address may mint a GameCard NFT to any address when the Protocol is not paused.
  • Any address with the Controller role may enable specified skinIds for specified GameCard IDs when the Protocol is not paused.
  • Users may set the current skin associated with their own GameCard when the Protocol is not paused.
  • Any address with the Relayer role may set the current skin on the behalf of another address when the Protocol is not paused.
Game Contract:
  • This contract allows users to participate in game sessions.
  • Each session consists of a number of rounds.
  • Each round consists of two opponents competing where one challenges the other.
  • Winning users will earn a payout based on the game's payout table consisting of various "strength" levels.
  • Users must first commit to a game session by providing the required number of credits as an entry fee.
  • Only approved contract addresses may commit to a game session.
  • Any address with the Relayer role may commit a user to a game session on their behalf.
  • Users may only commit to a "max active session" number of games.
  • An entry fee is determined from the current GG-USD price and session price.
  • The minimum entry fee is 1 credit with a maximum of "max credits" amount.
  • An additional "validator tip" and "match maker tip" amount of GG tokens may also be required from the user.
  • Users must be an approved address in the Custodial contract if one has been set.
  • Credits will be burned from the Custodial address rather than the player in this case.
  • A "fixed fee percentage" determined in the RewardsAMM contract is dispersed between the game developer and the player.
  • The remaining entry fee will be reserved for the maximum payout based on the specified payout table's maximum strength.
  • The game session will expire at the "max game duration" from the user's initial game commitment.
  • Users may commit to a round after they have committed to a game and before the game expires.
  • Users may only commit to a total of "max rounds per session" per each game session.
  • The previous round must be resolved before committing to a new round.
  • Users may record a match after committing to a round.
  • Addressees must be approved in the MatchMakerRegistry address in order to record a match. Recording a match will determine its outcome.
  • Users commit to a match by choosing their opponent for the current round by specifying their opponent's game session and round.
  • An approved address in the Validator Registry contract may validate a game session at any time. This will determine the outcome of the game.
  • Addresses approved in the Validator Registry contract may sign a game validation message for users who may then submit the signed message to validate the game.
  • Users may choose to forfeit the game. This will transfer the max payout to the rewards pool and the user will earn nothing.
  • This will calculate a payout amount to the payout address. The payout will then be distributed in the Rewards AMM contract.
  • The player's rating will be updated based on the game's result.
  • Any address with the Admin role may set the current session price to any value at any time.
  • Any address with the Admin role may toggle whether the contract is active at any time.
  • Any address with the Admin role may set the maximum rounds allowed per game session to any value at any time.
  • Any address with the Admin role may set the maximum game duration to any value at any time.
  • Any address with the Admin role may set the maximum active game sessions to any value at any time.
  • Any address with the Admin role may add a new payout table at any time.
CommitmentPermissions Contract:
  • This contract is used by the Game contract to validate game commitments.
  • The Directory address or Governor Role can grant or revoke permission for a contract to make a commitment at any time.
  • The Governor or Directory address can upgrade this contract at any time.
AMM Contract:
  • This contract is used to calculate reward distributions and mint Ticket tokens.
  • Any address with the AMM role may "disperse fees" when the Protocol is not paused.
  • This will distribute the specified fee amount between the matchmaker, validator, and game dev addresses.
  • The affiliate receiver will receive a percentage if the specified player has an affiliate set in the AffiliateRegistry contract.
  • Any remaining fees will be transferred to the EcoFund address.
  • Any address with the AMM role may "lock a maximum payout" when the Protocol is not paused.
  • This will add the specified amount of GG tokens to the locked balance. Any additional GG tokens needed will be requested from the RewardsPool address.
  • Any address with the AMM role may perform a "payout" up to the maximum payout and locked GG token balance when the Protocol is not paused.
  • The user must have permission in the RewardsPermission contract in order to receive the payout.
  • This will mint a Dev Extractor and Player Extractor amount to the Game Dev and player addresses respectively.
  • The player address will be minted the Ticket amount corresponding to the GG payout from the corresponding game result.
  • The extra rewards will be transferred to the Rewards Pool address if the payout was not the max payout.
  • Any address with the AMM role may perform a "forfeit" when the Protocol is not paused.
  • This will transfer the specified max payout amount to the RewardsPool address and remove it from the locked GG token balance.
  • Any address may grant a maximum GG token approval to the Tickets address when the protocol is not paused.
  • The Governance address may set the fixed fee split at any time.
  • The Governance address may set the Extractor weights at any time.
  • The Governance address may set the Extractor coefficient at any time.
  • The Governance address may set the fixed fee percentage at any time.
  • The Governance address may set the base fee at any time.
  • The Governance address may set the dev Extractor percentage at any time.
  • The Governance address may withdraw any GG tokens from the contract at any time.
RewardPool Contract:
  • This contract is used to collect and provide GG tokens for payouts.
  • Any address can deposit ETH into this contract while the platform is active; their total deposited amount is tracked.
  • The associated AMM contract can "request GG" from this contract at any time.
  • If the contract's GG balance after a request results in the GG balance falling below the minimum GG threshold, an auction is started if one is not already active.
  • If an auction is active but is expired, it is finalized.
  • While an auction is active, users can bid GG tokens in exchange for the auction's ETH reward.
  • The user's bid amount is transferred from their Sponsor address to this contract; if the user has not assigned themselves a Sponsor, tokens are instead transferred from their own address.
  • The previous highest bidder is returned their bid at the time of being outbid.
  • A user must bid at least the "minimum bidding increment" more than the latest highest bid.
  • If the auction's end block has been reached at the time of a bid, the auction is automatically finalized.
  • Once finalized, the auction's ETH reward is transferred to the highest bidder.
  • An active auction can also be manually finalized by any address if it has been bid on and its end block has been reached.
  • The project team must ensure that the contract maintains a sufficient ETH balance to support auction rewards.
  • An auction can only be bid on or finalized while the protocol is active.
  • A user can update their Signer address at any time; a user's Signer has the ability to update the user's Sponsor address at any time.
  • The Governor can update the minimum bidding increment at any time.
  • The Governor can update the auction length to any number of blocks at any time.
  • The Governor can update the contract's ETH reward at any time.
  • An auction cannot be started or finalized if the contract does not have a sufficient ETH balance to provide auction rewards.
  • The Governor can update the minimum bid and minimum GG threshold to any amounts at any time.
  • The Governor or Directory address can withdraw any amount of GG tokens or ETH from this contract at any time.
  • The Governor or Directory address can upgrade this contract at any time.
AffiliateRegistry Contract:
  • This contract allows users to register as affiliates.
  • Any address may register themselves as an affiliate when the Protocol is not paused.
  • Any address with the Relayer role may register an address as an affiliate on their behalf.
  • Any address may set the affiliate associated with their address when the Protocol is not paused.
  • Any address with the Relayer role may set the affiliate associated with an address when the Protocol is not paused.
  • Any address with the Controller role may register a sale for the affiliate associated with a player address.
  • Any address with the controller role may register a session for an affiliate associated with a player address.
FactoryController Contract:
  • This contract utilizes various Factory contracts to deploy new proxies for Game and Items contracts.
  • Any address may create a new Game when the Protocol is not paused.
  • This will deploy a new proxy of the Game contract implementation through the GameFactory and use the GItemsFactory to deploy new proxies of GItems, MItems, and UItems contract implementations.
  • The Ticket contract's tickets per GG and the Extractor contract's GG per extractor are registered in the Directory contract.
  • The game address will be associated with a new credit id in the Credit contract.
  • The GameFactory and GItemsFactory addresses may be set once by any address after deployment.
GameFactory Contract:
  • This contract is used to deploy new proxies for the Game contract implementation.
  • The FactoryController contract may deploy a new proxy of the Game contract at any time.
GItemsFactory Contract:
  • This contract is used to deploy new proxies for the GItems, MItems, and UItems contract implementations.
  • The FactoryController contract may deploy a new proxy of the GItems contract at any time. The MItemsFactory will be called to deploy a new proxy for the MItems and UItems contracts.
  • The MItemsFactory address may be set once by any address after deployment.
MItemsFactory Contract:
  • This contract is used to deploy new proxies for the MItems and UItems contract implementations.
  • The GItemsFactory contract may deploy a new Proxy of the MItems contract at any time. The UItemsFactory will be called to deploy a new Proxy for the UItems contract.
  • The UItemsFactory address may be set once by any address after deployment.
  • The Governor address may add and remove deployed MItems contracts from the whitelist at any time.
RebootBeacon Contract:
  • This contract serves as a valid Beacon implementation to be used with the RebootBeaconProxy contract.
  • The contract returns the current implementation address for the associated contract.
  • The Governance address may set the implementation address at any time.
RebootBeaconProxy Contract:
  • This contract functions as a proxy for the implementation contract provided by a Beacon.
  • The contract forwards function calls to the implementation address which executes the relevant logic in the context of this contract.
  • The Governance address may set the Beacon address at any time.
RebootGovernor Contract:
  • This contract is used to manage the DAO voting and proposal functionality within the ecosystem.
  • Users will receive one vote per GG token they possess and for each GG token staked in the ProtocolStaking contract.
  • Users may vote for, vote against, or abstain from a proposal.
  • Users also have the option to vote through the use of a signed message, allowing for a gasless vote for the user.
  • Votes for and abstained from a proposal will count towards a quorum.
  • A "quorum threshold" of the total token supply must be reached to pass a proposal.
  • Users with more tokens than the "proposal threshold" are proposers, allowing them to submit a proposal.
  • After a proposal is submitted, votes may not be cast until the "voting delay" has passed; this allows users to delegate and stake/unstake tokens as necessary.
  • The proposal will remain open for votes for the entire "voting period".
  • After the voting period, if a quorum is reached and the proposal is passed, the execution of the proposal is delegated to a Timelock contract.
  • The Timelock contract will not execute the function until a further delay has passed.
  • Users may change the previously described quorum threshold, proposal threshold, voting delay, and voting period through a successful proposal.
  • An Admin Council address is declared upon deployment and may cancel any pending transaction.
  • The Proposal Proposer can additionally cancel their transaction while the proposal is in Pending status.
  • The Governance address may set the Admin Council address at any time.
PowPunksVesting Contract:
  • This contract is used to create vesting structures for GG tokens for users where tokens are released linearly over the duration (set by the team) starting with the start time set by the user who creates the vesting structure.
  • Anyone can use this contract to register a vested stake for another user.
  • Upon registering a stake, the GG tokens are deposited into the contract, and the associated voting power is assigned to the beneficiary.
  • If the GG token transfer fails, the stake data will be added to a "failed transfers" list.
  • The failed transfers can be reprocessed all at once. However, if the transfers fail for a second time, they cannot be retried again.
  • Users can withdraw any releasable tokens as they are vested.
  • Users can alternatively choose to convert their releasable tokens to game credits, as long as they have a sufficient amount to release.
  • Vested tokens cannot be released or converted to game credits until there are no failed transfers to retry.
  • The Relayer role can release tokens or convert releasable tokens to game credits on behalf on any user as the tokens are vested.
  • Any user with voting power can use this contract to express and subsequently cast their votes towards a proposal.
  • Anyone can grant a max approval of GG tokens to the Credits contract at any time.
  • The Admin role can set the Credits contract address to any address at any time.
  • The Admin role can pause all functionality throughout the contract at any time.
  • The Admin role can withdraw any amount of GG tokens in the contract at any time.
MatchMakerRegistry Contract:
  • This contract is used to manage addresses that have permission to validate a match in the Game contract.
  • The Governor address may add and remove an address from the approved addresses at any time.
  • The Governor address may withdraw any GG tokens from the contract at any time.
ValidatorRegistry Contract:
  • This contract is used to manage addresses that have permission to validate a game submission.
  • The Governor address may add and remove an address from the approved addresses at any time.
  • The Governor address may withdraw any GG tokens from the contract at any time.
ProfileStorage Contract:
  • This contract is used to record certain player statistics.
  • Any address may register a player address when the protocol is not paused.
  • Registering a player will initialize all of their statistics to the default values.
  • A Game contract registered in the Factory Controller address may update the profile of a registered address when the protocol is not paused.
GGVesting Contract:
  • This contract can be used to release vested GG tokens to beneficiary addresses.
  • The deployer will specify the beneficiary address, total number of tokens to be vested, total number of vesting periods, number of seconds in each period, start time, and whether the tokens can be "clawbackable".
  • The deployer will also specify an Admin address that will be granted the Default Admin role and Clawback role.
  • The beneficiary address can begin claiming tokens after the contract's release start time has been reached.
  • The beneficiary address can claim a proportionate amount of the total number of tokens due to them after each vesting epoch has passed.
  • Claimed tokens are transferred from the contract to the destination address specified by the beneficiary.
  • If the Clawback functionality is enabled by the team on deployment, addresses granted the "Clawback" role can withdraw any currently unvested tokens from the contract.
  • The specified recipient address receives the unvested tokens, calculated as the contract's current GG token balance minus the amount already vested but not yet claimed by the beneficiary.
  • The beneficiary address can delegate their voting power to any address in the GGT contract at any time.
  • The beneficiary address can set the beneficiary address to any address at any time.
fGG Contract:
  • The total supply is initially set to zero on deployment.
  • Any address granted the Protocol role can mint any number of tokens to any address at any time.
  • Any address granted the Protocol role can specify a number of any user's tokens to burn at any time.
  • Any user can burn their own tokens at any time.
  • Any user can burn tokens on another user's behalf if an allowance has been granted.
  • The contract complies with the ERC-20 token standard.
L1Payments Contract:
  • This contract is used to purchase credits through the associated Inbox contract.
  • When purchasing, the caller provides a bundle ID, number of credits, the maximum amount they are willing to pay, a receiver address, maximum submission and gas costs, and a gas price bid.
  • The supplied payment but be at least equal to their maximum payment amount.
  • This data is then used to purchase credits through the Inbox contract.
  • As the Inbox contract was not included within the scope of this audit, we are unable to provide an assessment with regards to its security or functionality.
TimeLock Contract:
  • This contract is used to execute successful proposals.
  • The deployer and this contract are granted the Timelock Admin role upon deployment.
  • A provided list of addresses are granted the Proposer role upon deployment.
  • Similarly, another list of addresses is granted the Executor role upon deployment.
  • The Timelock Admin role may grant the Timelock Admin, Proposer, or Executor role to any address at any time.
  • The Proposer role may schedule an operation that will be executed by the Timelock after the delay period has passed.
  • The Canceller role may cancel a pending operation before it is executed.
  • The Executor role may execute an operation once the delay period has passed.
  • The delay period may be updated through successful execution of a proposal.
ProtocolStakingContracts Contract:
  • This contract is used to add and remove registered Staking contracts within the platform.
  • The Governor or Directory address can add or remove a contract from the list of Staking contracts at any time.
  • This contract can also be used to determine the total number of votes across all registered Staking contracts.
  • The Governor or Directory address can upgrade this contract at any time.
PriceFeed Contract:
  • This contract allows the Backend Role to manually update token prices.
  • Any address can fetch the stored price of a pair at any time.
  • The Controller Role can update the price of any pair at any time.
  • The Governor or Directory address can upgrade this contract at any time.
RandomizerAIProvider Contract:
  • Any address, intended to be a Game contract, can request a random number at any time.
  • When requesting, the caller must supply the required amount of ETH, which is estimated using the Randomizer contract and the contract's callback gas limit.
  • The Randomizer address will then execute this contract's callback function to fulfill the random number request and provide it to the Game contract.
  • The Admin Role can update the callback gas limit and Randomizer address at any time.
  • The Admin Role can withdraw any unreserved ETH from the Randomizer address at any time.
  • As the Randomizer contract was not included within the scope of this audit, we are unable to provide an assessment with regards to its security or functionality.
QRNGProvider Contract:
  • This contract is intended to be used to provide randomness functionality to the Game contract.
  • A Game can request a random number at any time, which initiates a request to an AirnodeRRP address using the contract's Airnode and Endpoint.
  • The Game's Sponsor and SponsorWallet addresses are also included in the request.
  • The Airnode will then execute this contract's callback function to fulfill the random number request and provide it to the Game contract.
  • A Game's Admin can update the Game's Sponsor and Sponsor Wallet address at any time.
  • The Directory or Governor address can update the Airnode address and Endpoint IDs used to provide randomness at any time.
  • As the Airnode contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
PVRF Contract:
  • This contract is used as a method to request random numbers.
  • An ETH amount equal to at least the contract's expected fee must be supplied when requesting.
  • The expected fee is determined by the contract's assigned gas callback price, fee, and the blockchain's current gas price.
  • When requesting, the request ID is added to the current batch.
  • If the polling interval duration has passed from the latest batch's start time, a new batch is started with a new batch ID.
  • A requester can withdraw any excess ETH that they have provided to the contract at any time.
  • The Callback Role can fulfill all random number requests from a batch once the polling interval duration has passed from the start of the batch.
  • When fulfilling, the Callback Role will provide a random number; this number is assigned to all of the requests in the batch.
  • Batches must be fulfilled in order.
  • The Admin Role can pause the contract at any time, disabling random number requests.
  • The Admin Role can withdraw any accumulated fees from the contract at any time.
  • The Admin Role can update the polling interval to any frequency at any time.
  • The Admin Role can update the fee and gas callback to any values at any time.
ProtocolDirectory Contract:
  • The deployer will specify the contract's Governor address upon deployment.
  • The Governor can set the Admin Council address to any address at any time.
  • The Admin Council address can pause/unpause the protocol at any time.
  • The Governor can set the GGT, Tickets, Profile Storage, Extractors, Token Market, Factory Controller, Credits, Game Beacon, mItem Beacon, and uItem Beacon to any addresses at any time.
  • The Governor can set the gItem Beacon, Game Card, Price Feed, Rewards AMM, Matchmaker Registry, Validator Registry, Governor, Commitment Permissions, Affiliate Registry, and RN Provider to any addresses at any time.
  • The Governor can set the next Protocol Directory Version, Protocol Staking Contracts, Game Factory, mItems Factory, EcoFund, Rewards Pool, or Partnerships address and any address at any time.
  • The Governor can grant/revoke a specific role for an address within the Affiliate Registry at any time.
  • The Governor can update the default session share and sale share in the Affiliate Registry to any value at any time.
  • The Governor can set the affiliate session share and sale share for a specific ID within the Affiliate Registry to any value at any time.
  • The Governor can grant/revoke a specific role for an address within the Rewards AMM at any time.
  • The Governor can update extractor weights and extractor coefficient within the Rewards AMM at any time.
  • The Governor can set the fixed fee percentage and the base fee percentage within the Rewards AMM contract to any values at any time.
  • The Governor can set the development extractor percentage and the fixed fee split within the Rewards AMM to any values at any time.
  • The Governor can grant/revoke a specific role for an address within the Extractors address at any time.
  • The Governor can set the URI for the Extractors address at any time.
  • The Governor can set permission for a specific address within the Commitment Permissions address at any time.
  • The Governor can set the Credit Bundle Contract address within the Game Cards address at any time.
  • The Governor can grant/revoke a specific role for an address within the Game Card address at any time.
  • The Governor can grant/revoke a specific role for an address within the GGT address at any time.
  • The Governor can approve or disapprove specified Match Maker addresses at any time.
  • The Governor can set the validity status of a specific M-Items address at any time.
  • The Governor can add a new staking contract to the Protocol Staking Contracts address at any time.
  • The Governor can remove a staking contract from the Protocol Staking Contracts address based on its index at any time.
  • The Governor can set request parameters for the QRNG Provider at any time.
  • The Governor can withdraw any amount of GG tokens and ETH from the Rewards Pool to a specific address at any time.
  • The Governor can set the Protocol Fee Receiver address in the Token Market address at any time.
  • The Governor can set the Protocol Fee and Maximum Developer Share in the Token Market address to any values at any time.
  • The Governor can approve or disapprove a specific Validator address at any time.
  • The Governor can approve or disapprove a batch of Validator addresses at any time.
  • The Governor can grant/revoke a specific role for an address within the Tickets address at any time.
  • The Governor can upgrade the Game Beacon to a new implementation at any time.
MainnetSWPR Contract:
  • Anyone can use this contract to bridge Pow, Punks, and Planets to L2.
  • Upon initiating the bridge, any Punks are locked in the Treasury, and any Planets or Pow tokens are burned.
  • The Admin role can set the Treasury address to any address at any time.
  • The Admin role can set the config, receive version, and force resume receive on the LZ Endpoint contract address.
  • The Admin role can set the trusted remote address for any chain ID to any address at any time.
BoostController Contract:
  • The LZ Endpoint contract can use this contract to process requests to set new checkpoints on the Dust contract with the specified vesting durations.
  • The Admin role can set the config, receive version, and force resume receive on the LZ Endpoint contract address.
  • The Admin role can set the trusted remote address for any chain ID to any address at any time.
L2Recv Contract:
  • The LZ Endpoint contract can use this contract to process claims on an L2 on behalf of any user.
  • Claims may involve minting Planets in the Dust contract, purchasing Credits in the Credits contract, or registering a stake in the PowPunksVesting contract.
  • The Admin role can withdraw any amount of GG tokens in the contract at any time.
  • The Admin role can set the Credits, Dust, and PowPunksVesting addresses to any address at any time.
  • The Admin role can set the config, receive version, and force resume receive on the LZ Endpoint contract address.
  • The Admin role can set the trusted remote address for any chain ID to any address at any time.
Dust Contract:
  • This contract defines Dust NFTs.
  • Dust NFTs are soulbound and cannot be transferred.
  • Each NFT is associated with a collateral amount and the time the NFT is minted.
  • Any address with the Controller role may mint any amount of NFTs to any address when the contract is not paused.
  • Each NFT will be associated with a collateral amount of GG tokens according to the the "planet ID" specified by the minter.
  • If the GG token transfer upon minting fails, the transfer data will be added to a "failed transfers" list.
  • The failed transfers can be reprocessed all at once. However, if the transfers fail for a second time, they cannot be retried again.
  • The NFT ID will be registered as staking in the CommunityPool contract.
  • Users will be delegated voting power equal to the total amount of collateral associated with the NFTs minted to them.
  • Users may perform a claim when the contract is not paused and their NFT is fully vested.
  • If the specified chain ID is the Nova Chain ID, the user will receive the the GG tokens.
  • Otherwise the token amount will be relayed to the LZEndpoint.
  • Users may perform a "rage quit" when the contract is not paused.
  • The amount of tokens vested begins at 1/4 of the total amount, increasing up to 1/2 of the total tokens before all tokens become fully vested.
  • If the specified chain ID is the Nova Chain ID, users will receive the current amount of GG tokens that are currently vested.
  • Otherwise the token amount will be relayed to the LZEndpoint.
  • The remaining tokens allocated to the user will be transferred to the CommunityPool address.
  • The user's Dust NFT will subsequently be burned.
  • The team must provide sufficient GG tokens in order for all users to be able to claim rewards.
  • Users may perform a claim when the contract is not paused and the tokens allocated to the NFT are fully vested.
  • This will transfer the user the full amount of tokens and begin vesting in the CommunityPool address.
  • Users will not be able to claim or rage quit until there are no failed transfers to retry.
  • Any user with voting power can use this contract to express and subsequently cast their votes towards a proposal.
  • Any address with the Admin role may withdraw all GG tokens from the contract.
  • Any address with the Admin role may set the base URI at any time.
  • Any address with the Admin role may set the CommunityPool address at any time.
  • Any address with the Admin role may set the Nova Chain ID and adapter params at any time.
CommunityPool Contract:
  • This contract allows Dust NFT owners to earn rewards when users perform a rage quit or a claim.
  • The Dust contract may register a user's stake when the contract is not paused. This will set the user's staked amount.
  • The Dust contract may process a rage quit when the contract is not paused. This will add the specified forfeited rewards amount to the total rewards.
  • The Dust contract may start the vesting for a specified Dust ID when the contract is not paused.
  • The length of the user's vesting period will be set to the current "vesting duration".
  • Users may claim their pending rewards when the contract is not paused.
  • Users will receive rewards based on the rewards accumulated from the time their staking began and the amount of tokens they have staked proportionally to the total amount.
  • If the specified chain ID is the Nova Chain ID, users will receive the current amount of GG tokens that are currently vested.
  • Otherwise the token amount will be relayed to the LZEndpoint.
  • Users will no longer earn rewards once their vesting duration has passed.
  • Any address with the Admin role may set the Dust contract once after deployment.
  • Any address with the Admin role may set the Nova Chain ID and adapter params at any time.
DotStaking Contract:
  • This contract allows users to stake DOTS tokens.
  • The DOTS contract is outside the scope of this audit so we are unable to give an assessment in regard to security.
  • Any user may stake and unstake when the contract is not paused.
  • The vesting duration for staked DOTS tokens varies based on the DOTS' "evo num".
  • The staking information will additionally be relayed to a LZEndpoint address.
  • Any address with the admin role may pause the contract at any time.

Audit Results

Vulnerability Category Notes Result
Arbitrary Jump/Storage Write N/A PASS
Centralization of Control
  • The project team has the permissions described above.
  • The project team can manually update token prices in the PriceFeed contract at any time.
  • The Governor address can update any address used by the platform through the PlatformDirectory contract.
  • Various contracts can be upgraded by the Governor or Directory address at any time.
  • The Admin role can withdraw any amount of GG tokens in the PowPunksVesting contract at any time.
  • The Governor address may withdraw any excess GG tokens from the MItems contract.
  • The Game contract's admin may set the session price to any value.
  • The Governor address may withdraw any GG tokens from the AMM contract.
  • The Admin role can withdraw any ETH from the CreditBundle contract at any time.
  • WARNING
    Compiler Issues N/A PASS
    Delegate Call to Untrusted Contract N/A PASS
    Dependence on Predictable Variables N/A PASS
    Ether/Token Theft N/A PASS
    Flash Loans N/A PASS
    Front Running
  • Front running risk on bids is currently greatly reduced due to Arbitrum's centralized sequencers, but this could change in the future.
  • PASS
    Improper Events N/A PASS
    Improper Authorization Scheme N/A PASS
    Integer Over/Underflow N/A PASS
    Logical Issues N/A PASS
    Oracle Issues N/A PASS
    Outdated Compiler Version N/A PASS
    Race Conditions N/A PASS
    Reentrancy N/A PASS
    Signature Issues N/A PASS
    Sybil Attack N/A PASS
    Unbounded Loops N/A PASS
    Unused Code N/A PASS
    Overall Contract Safety   PASS

    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.