Galactix Zone security record

BNB Chain, Ethereumgalactixzone.ioGitHub

As of 3 Nov 2026, Galactix Zone has 2 audit reports by 1 security firm on Trustblock; the latest is by CertiK, dated 25 Sep 2023. Those reports list no open critical findings.

Critical findings
No open critical findings
Across the 2 reports, 1 critical finding was reported. It is marked fixed by the firm that reported it. See the findings
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.

Audits2

Newest first

AuditSecurity firmDateScopeCritical findingsReport
Galactix Zone v2Security firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com
GalactixzoneSecurity firm: CertiKDate: Scope: Files named in the report1 critical finding, fixedOpen · skynet.certik.com

Findings43

Statuses are the security firm’s own, from each report.

SeverityOpenAcknowledgedFixed
Critical001
High341
Medium103
Low9021
Criticalstring `mergeSet` is not unique for `_tokenIds`Galactixzone · CertiK · 24 Nov 2022Fixed

The string `mergeSet` created from function `generateMergeSet()` in library `MergeHelper` is not unique for a given `uint` array `_tokenIds`. For instance, the array `[1,2,3]` (an array of token Ids 1, 2, and 3) will yield string `123`, but so will array `[123]` (an array containing only token Id 123). Because of this, mapping `mergeSetCreatedAt` can be overwritten for two differing, legitimate inputs, with two differing signatures. This can result in permanently locked tokens that cannot be burned nor used to mint new tokens, since `mergeSetCreatedAt` is used as a check in the merge functions.

Open the report
HighCheck on `balanceOf(_buyer)` allows signatures toGalactixzone · CertiK · 24 Nov 2022Fixed

In contract `key`, function `verifySignature()` uses the NFT `balanceOf(_buyer)` in verifying a signature for given input information. Please explain the significance of the check on the balance. Once the balance is attained by the user, they need only maintain that balance to use the signature again. This can be done by either buying no new NFTs, or buying more and transferring to a secondary account. Is the intention to confirm that the user has bought a certain threshold amount of `GMA` NFTs in order to buy more, or is it to make sure they do not own a certain number? If it is the latter, this check will not prevent this scenario.

Open the report
MediumPotential Reentrancy Attack (Incrementing State)Galactix Zone v2 · CertiK · 25 Sep 2023Fixed

A reentrancy attack can occur when the contract creates a function that makes an external call to another untrusted contract before resolving any effects. If the attacker can control the untrusted contract, they can make a recursive call back to the original function, repeating interactions that would have otherwise not run after the external call resolved the effects. *This finding is considered minor because the state variable is only incremented or decremented. So, the effect of out-of-order increments may be unobservable after transaction. However, the reentrancy vulnerability may still cause other issues in the middle of transaction.* ### External call(s) ```solidity=148 antisnipe.assureCanTransfer(msg.sender, from, to, amount); ``` ### State variables written after the call(s) ```solidity=183 _balances[from] -= (ownerTax + commonTax); ``` ```solidity=188 _balances[taxRecipient] += commonTax; ``` ```solidity=196 _balances[taxRecipient] += ownerTax; ``` *Note: Only a sample of 3 assignments (out of 4) are shown above.*

Open the report
MediumInconsistency in `_timestamp` CheckGalactixzone · CertiK · 24 Nov 2022Fixed

Functions `temporaryMerge()` and `permanentMerge()` achieve the same end result, but `temporaryMerge()` requires execution within four minutes of the `_timestamp` used in signature verification, while `permanentMerge()` does not. This appears to make this check ineffective, since a user can use the same signed information in either function successfully.

Open the report
MediumUsers Can Bypass Transfer FeeGalactixzone · CertiK · 24 Nov 2022Fixed

A user can bypass the ERC721 transfer fee. Function `safeTransferFrom(address from, address to, uint256 tokenId)` in the inherited `ERC721Upgradeable` contract calls to the other public function ```solidity safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) ``` the only difference being the secondary function has an option for input `data`. Users can call this latter function directly, thus bypassing the transfer fee.

Open the report
LowMissing Emit EventsGalactix Zone v2 · CertiK · 25 Sep 2023Fixed

The smart contract contains one or more state changes related to arithmetic operations that do not emit events to communicate the changes outside the blockchain, which can lead to difficulties in tracking or verifying these changes and may affect the contract's transparency and auditability. ```solidity=293 if (_isLPPool) { success = liquidityPoolAddresses.add(_lpPoolAddress); } else { success = liquidityPoolAddresses.remove(_lpPoolAddress); } if (!success) { revert('Address pool status is already set to this value.'); } ``` --- ```solidity=362 antisnipeDisable = true; ``` --- ```solidity=366 antisnipe = IAntisnipe(addr); ``` --- ```solidity=381 commonTaxRate = _newTaxRate; ``` --- ```solidity=386 ownerTaxRate = _newTaxRate; ```

Open the report
LowMissing Zero Address ValidationGalactix Zone v2 · CertiK · 25 Sep 2023Fixed

The cited address input is missing a check that it is not `address(0)`.

Open the report
Low`Ownable` Inheritance is Not UsedGalactixzone · CertiK · 24 Nov 2022Fixed

Contract `GalactixToken` inherits from contract `Ownable`. While the deployer is made the `owner` of the contract, the `onlyOwner` modifier is never used on any of the functionality.

Open the report
LowEvent Not Accurate when `_salePhase` is 4Galactixzone · CertiK · 24 Nov 2022Fixed

The event emitted uses the inputs `_endTime`, `_priceInBUSD`, and `_priceAfter24Hours` regardless of which `_salePhase` is being deployed. However, in `_salePhase` 4, this information is meant to change.

Open the report
LowImproper Values RecordedGalactixzone · CertiK · 24 Nov 2022Fixed

In function `deployNewSalePhase()`, if `_salePhase` is 4, then `salePhaseStatistics[_salePhase].priceInBUSD` is updated to `launchPrice`. Regardless, it is also updated to input `_priceInBUSD` further in the function code. On a related note, `salePhaseStatistics[_salePhase].priceAfter24Hours` is set to the input value `_priceAfter24Hours`. This may lead to unexpected changes in the price if the intention is for the `priceInBUSD` for the fourth sale phase to stay at the launch price in perpetuity at that time.

Open the report
Show 10 more
LowInput `_isUsingBNB` allows for Locked BNBGalactixzone · CertiK · 24 Nov 2022Fixed

If a user inputs `false` for `_isUsingBNB`, but sends BNB with the function call, the BNB will not be sent to the `treasuryAddress` and instead will be locked in the contract.

Open the report
LowMissing initialization of `ReentrancyGuardUpgradeGalactixzone · CertiK · 24 Nov 2022Fixed

The function `initialize()` does not call `__ReentrancyGuard_init()`. This function initializes the `status` variable in the parent contract.

Open the report
LowMissing Input ValidationGalactixzone · CertiK · 24 Nov 2022Fixed

The given input is missing a check for the following: **Contract `dNFT`** - `_feeRate` is missing a check that it is no larger that 10000 (the dividing factor). - `_minimumGalactixTokenRequire` is missing a check that it is nonzero. - `_rescuePrice` is missing a check that it is nonzero. - `_launchPrice` is missing a check that it is nonzero. - `_claimableTime` is missing a check that it is nonzero. - function `executeTemporaryMerge()` is missing a check that the relevant session Id exists (it should revert if the session Id does not exist). - function `permanentMerge()` is missing a check on input `_sessionId` and `_timestamp`. --- **Contract `key`** - `_feeRate` is missing a check that it is no larger that 10000 (the dividing factor). - `_keyPrice` is missing a check that it is nonzero. - `_buyTime` is missing a check that it is at least the value of `block.timestamp`. --- **Contract `PreSalePool`** - `_salePhase` is missing a check that it is a strictly increasing value (old `_salePhase` inputs cannot be reused).

Open the report
LowMissing Zero Address ValidationGalactixzone · CertiK · 24 Nov 2022Fixed

Addresses should be checked before assignment or external call to make sure they are not `address(0)`.

Open the report
LowPotential for Replay AttacksGalactixzone · CertiK · 24 Nov 2022Fixed

In contract `PreSalePool`, functions `buyTokenWithExactlyBUSD()` and `buyTokenWithExactlyBNB()` use function `verifyWhitelist()` to verify a `_candidate` address can participate in the presale and, for what amount of BUSD they are approved to purchase the presale token with. The input information in function `verifyWhitelist()` is then used in the `Whitelist` library function `verifySignature()`, along with the state variable `signer` address. This function uses `getMessageHash()` to hash together `_salePhase`, `_signer`, `_candidate`, and `_BUSDAmount`, which is then used to check against the provided `_signature` using OpenZeppelin's ECDSA `recover()` function. A `nonce` value is usually incorporated to prevent a user from using the same signature for the exact same message twice within the contract instance. Within the context of the `PreSalePool` contract, it is conceivable that this omission is by design, since the amount a `_candidate` address can purchase is checked against a running sum of what they have already purchased. If `maxBUSDUserCanSpend` for the `currentSalePhase` is a multiple of the `_BUSDAmount` a user is verified to use, then the user may call one of the two buying functions several times. However, if this is not the intention, then we recommend adding a `nonce` in the message hash to keep track of the exact message for which the signature was created. Moreover, specifications such as the name of the function, name of the project, version, and type of project are often used within the message hash to prevent the message from being used elsewhere. This information is typically encoded in a *domain separator* (note not all of this information necessarily must be included, if not relevant). Lastly, a chain ID is usually encoded as well in the event that a fork of the chain occurs. The concern is that a lack of this information within the message hash may allow for a signature to be reused, if the `signer` address is ever used in another context, and if the same generic information is ever used for a message hash. A similar set up is used within the cited functions in contract `dNFT`, creating the same potential issue.

Open the report
LowRedundant ChecksGalactixzone · CertiK · 24 Nov 2022Fixed

The only time `lockToken()` is called is in function `temporaryMerge()`, where the owner of the token is checked prior, as is the status of whether the token is locked. These same two checks are made within the function `lockToken()` again and are unnecessary, since `lockToken()` is a private function. A similar issue occurs with `unlockToken()`.

Open the report
LowShadowing Local VariableGalactixzone · CertiK · 24 Nov 2022Fixed

A local variable is shadowing another component defined elsewhere. ```solidity=8 constructor(address _admin, uint256 _totalSupply) ERC20("GalactixCoin", "GXZ") { ``` - Local variable `_totalSupply` in `GalactixToken.constructor` shadows the variable `_totalSupply` in `ERC20`.

Open the report
LowSome Users May Be Prevented from Purchasing TokenGalactixzone · CertiK · 24 Nov 2022Fixed

In contracts `dNFT` and `PreSalePool`, the amount of tokens a user is able to buy is restricted. In `dNFT`, it is restricted by value `_maxAmountUserCanBuy` for the sale phase. This value may be set as high as the `MAX_SALE_AMOUNT`. If the product of (`_maxAmountUserCanBuy`)*(number of users buying) exceeds the `MAX_SALE_AMOUNT`, then it is possible that some users may buy all tokens before others get the chance to purchase the tokens for which they are whitelisted to buy. In `PreSalePool`, a similar issue occurs where if the `maxBUSDUserCanSpend` allows a user to purchase an amount of tokens such that the product of (max amount user can buy)*(number of whitelisted users) exceeds `maxPreSaleAmount`, then some users may be able to purchase all available tokens for the sale phase before other whitelisted members have purchased any tokens at all.

Open the report
LowTaxes on `transferFrom()` and `safeTransferFrom()Galactixzone · CertiK · 24 Nov 2022Fixed

Requiring that `BUSDToken` is transferred from the `from` address to the `treasuryAddress` as a tax may keep a third party who is supposed to be approved to transfer the NFT from being able to transfer the NFT. As constructed, the user who owns the NFT must both give approval to the third party user to move their tokens, but then must also approve the contract for the amount of tax on the `launchPrice` (in `key`, the `keyPrice` - neither are necessarily known ahead of time). Failure to do the second part will keep the third party from being able to transfer the NFT.

Open the report
LowUnchecked Value of ERC-20 `transfer()`/`transferFGalactixzone · CertiK · 24 Nov 2022Fixed

The linked `transfer()`/`transferFrom()` invocations do not check the return value of the function call, which should yield `true` in the case of a proper ERC-20 implementation.

Open the report
Show 6 more
LowUnsafe Integer CastGalactixzone · CertiK · 24 Nov 2022Fixed

Aggregators allow for the possibility of negative values as price. ```solidity uint256 BNBPerBUSDInUint256 = uint256(BNBPerBUSD); ``` The type conversion `uint256(BNBPerBUSD)` from type int256 to type uint256 may cause a negative value to be converted to a large, nonequivalent unsigned integer.

Open the report
LowUsage of `transfer()`/`send()` for sending EtherGalactixzone · CertiK · 24 Nov 2022Fixed

Using Solidity's `transfer()` and `send()` functions for transferring Ether is not recommended, since some contracts may not be able to receive the funds. These functions forward only a fixed amount of gas (2300 specifically) and the receiving contracts may run out of gas before finishing the transfer. Additionally, gas costs may increase in the future. Thus, some contracts that can receive now may stop working in the future due to the gas limitation.

Open the report
LowUse of `VerifyWhitelist()` in `buyTokenWithExactlGalactixzone · CertiK · 24 Nov 2022Fixed

Functions `buyTokenWithExactlyBUSD()` and `buyTokenWithExactlyBNB()` both use `verifyWhitelist()` as a check, where the former function uses input `_BUSDAmount` as `_BUSDAmount` for `verifyWhitelist()` and the latter uses `msg.value` as `_BUSDAmount` for `verifyWhitelist()`. Since verifying an amount of BUSD (for example, 100 BUSD) is different than verifying the same amount of BNB (e.g., 100 BNB), the `msg.value` and `_BUSDAmount` should not be interchangeable in the signature verification process. If a user inputs a signature intended to be used in `buyTokenWithExactlyBUSD()` into function `buyTokenWithExactlyBNB()`, they may be able to buy more tokens faster than other users. Since there is a limit on the total number of tokens that can be bought in a phase, this may give an unfair advantage that leaves other whitelisted users unable to buy tokens.

Open the report
LowUser can buy in the wrong `_salePhase`Galactixzone · CertiK · 24 Nov 2022Fixed

Any user with a valid `_signature` can buy tokens in any sale phase. Note that both functions `buyUsingBUSD()` and `buyUsingBNB()` both pass a check through `verifyBuySignature()` which uses the input `_salePhase` as part of the check. However, all `salePhaseStatistics` are for the `currentSalePhase` which does not have to be the input `_salePhase` value, since there is no check for this. Note that modifier `inSalePhase` only checks that the current `block.Timestamp` is within the range of the *current* sale phase, not the input `_salePhase`. This may allow more users than intended to purchase tokens in a given sale phase.

Open the report
LowUser May Pay More than `priceInBNB`Galactixzone · CertiK · 24 Nov 2022Fixed

In functions set up for users to pay an amount of BNB, the only check is that the `msg.value` is not less than the `priceInBNB`. This means that a user may pay more than the `priceInBNB` and regardless, it will all go to the `treasuryAddress`.

Open the report
LowValue is never NegativeGalactixzone · CertiK · 24 Nov 2022Fixed

Input values `_priceInBUSD`, `_priceAfter24Hours`, and `_maxAmountUserCanBuy` in function `deployNewSalePhase()` of `dNFT` are of type `uint` and as such are always nonnegative. The check that these values are less than 0 will always be false. The same is true of input `_BUSDAmount` in function `canBuyMoreToken()` of `PreSalePool`.

Open the report

Contracts

No deployed address is recorded for these audits.

The reports name a repository or files. Open a report to see its scope.

The repositories and files the reports name

Show this on your site

Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.

Content

Facts

Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="galactix-zone"
></div>
</body>

Paste the code where the label should appear. It uses no API credit and updates by itself.

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us