CoinFabrik was asked to audit the contracts for AVAX (Avalanche) Avalaunch’s XAVA Protocol project. First we will provide a summary of our discoveries and then we will show the details of our findings.
The contracts audited are from the Xava protocol git repository. The audit is based on the commit
fd9b97ccd963819a282fa5c21bf0545d180f8797. Revisions were made based on commit
The audited contracts are:
The scope of the audit is limited to those files. No other files in this repository were
audited. Its dependencies are assumed to work according to their documentation.
Also, no tests were reviewed for this audit.
Without being limited to them, the audit process included the following analyses:
● Arithmetic errors
● Outdated version of Solidity compiler
● Race conditions
● Reentrancy attacks
● Misuse of block timestamps
● Denial of service attacks
● Excessive gas usage
● Missing or misused function qualifiers
● Needlessly complex code and contract interactions
● Poor or nonexistent error handling
● Insufficient validation of the input parameters
● Incorrect handling of cryptographic signatures
● Centralization and upgradeability
Summary of Findings
We found one critical issue and four minor issues. Also, some enhancements were
The audit encompasses 20 contracts including interfaces and libraries. Contracts
like AllocationStaking and FarmingXava are Ownable. The owner is responsible for
setting sale parameters in the first case, and adding pools, setting allocation points
in the second case.
Other contracts, like AllocationStaking, AvalaunchBadgeFactory,
AvalaunchCollateral, the airdrop contracts (Airdrop, AirdropAVAX, AirdropSale),
AvalaunchSale and SaleFactory make use of the Admin interface, setting an
administrator at construction.
The new AvalaunchCollateral contact further introduces the role of the moderator
who is responsible for approving sales to have collateral as per this contract.
Security Issues Found
Security risks are classified as follows:
● Critical: These are issues that we manage to exploit. They compromise the
system seriously. They must be fixed immediately.
● Medium: These are potentially exploitable issues. Even though we did not
manage to exploit them or their impact is not clear, they might represent a
security risk in the near future. We suggest fixing them as soon as possible.
● Minor: These issues represent problems that are relatively small or difficult
to take advantage of but can be exploited in combination with other issues.
These kinds of issues do not block deployments in production environments.
They should be taken into account and be fixed when possible.
An issue detected by this audit can have four distinct statuses:
● Unresolved: The issue has not been resolved.
● Acknowledged: The issue remains in the code but is a result of an intentional
● Resolved: Adjusted program implementation to eliminate the risk.
● Partially resolved: Adjusted program implementation to eliminate part of the
risk. The other part remains in the code but is a result of an intentional
● Mitigated: Implemented actions to minimize the impact or likelihood of the
Critical Severity Issues
CR-01 Unlimited Permits Issued for Admin
The admin can call autoParticipate() or boostParticipation() in the contract
AvalaunchCollateral and act on behalf of a user, paying with this user’s
collateral. The user only allows the sale (address), but cannot limit amounts,
Include an amount (or maximum amount) that the user allows the admin to use.
Resolved. Developers informed us that this is the expected use. Users must
therefore trust that the admin will select the amount safely in their interests.
Medium Severity Issues
No issues found.
Minor Severity Issues
MI-01 No Booster Round Is Possible
AvalaunchSale.setSalesParams() we set the boosterRoundId as
boosterRoundId = _stakingRoundId.add(1);
after the following check
require(_stakingRoundId > 0, "Invalid staking round id.");
However, since stakingRoundId may be equal to roundIds.length-1 and
boosterRoundId could point to a nonexistent round, thus rendering the booster
round unavailable to all practical purposes.
_stakingRoundId is not the last index. Alternatively, revisit the order in
which parameters are set to prevent inconsistencies between number of rounds,
and specific rounds.
Acknowledged. Developers explained that this is an expected behavior and the
booster round is optional.
MI-02 Floating Pragma
Contracts should be deployed with the same compiler version that they have been
tested with. Locking the pragma helps to ensure that contracts do not accidentally
get deployed using, for example, an outdated compiler version that might introduce
bugs that affect the contract system negatively.
Lock the pragma version, replacing pragma solidity
^0.8.0; with a specific patch,
preferring the most updated version. For example, pragma solidity
MI-03 Inconsistent Parameters in AvalaunchSale and SalesFactory
There is a problem if the collateral parameter set in SalesFactory is different to that
set in AvalaunchSales.
Set the parameter in only one contract.
MI-04 Prefer Importing Libraries from NPM
IERC20Metadata.sol is stored locally and imported, instead of using NPM
to import it from openzeppelin’s repository. This may lead to errors in copying, or
lose an update.
Import all externally-generated code through NPM.
These items do not represent a security risk. They are best practices that we
EN-01 Outdated Solidity Compiler Version
The audited contracts use the outdated version of solidity v0.6.12 (SWC-102).
Consider updating the code to compile with the latest version.
EN-02 Unused Flattened Library
Flattened old version of OpenZeppelin’s TransparentUpgradeableProxy. If not using
the latest version, devs should specify what version they are using so we can check
for reported issues.
Document the usage of this variable and allow modifications.
EN-03 tokenPriceInUSD Is Unused and Misleading
The variable tokenPriceInUSD in
AvalauncSale.sol is misleading, since it is not used
by any of the sale functions nor needs to have any relationship with
tokenPriceInAVAX. Also tokenIpriceInAVAX may be changed but this cannot.
Document the usage of this variable and allow modifications.
EN-04 dexalotPortfolio May Be Set Before Sale Is Created
Ensure the sale is created in
EN-05 admin Array Not Checked For Repetitions During Construction
In the constructor of Admin.sol it could happen that an address is repeated in the
_addresses. If this happens, the same address would be pushed more
than once to the array admins and may create inconsistencies, e.g., when calling
removeAdmin(). We recommend you check i
sAdmin[_admins[i]] = false
before turning it to true.
EN-06 Replace Integers by Constants
FarmingXava.sol replace occurrences of 1e18 and 1e36 by a call or a constant
IERC20Metadata(address(token)).decimals() as it is done in the
EN-07 Two safeMath Libraries
Some contracts import OpenZeppelin’s safeMath library and others use a custom
safeMath library (
math/safeMath.sol) which is a copy of OpenZeppelin’s safeMath
with some modifications. Also, note that some contracts, like
importing safeMath but not using it. In that case, consider removing and saving gas.
Use Solidity’s NatSpec format for documentation (link), removing “todo”s and other
● 2022-03-22 – Initial report based on commit
● 2022-04-05 – Revision based on commit
Disclaimer: This audit report is not a security warranty, investment advice, or an
approval of the Avalaunch XAVA Protocol project since CoinFabrik has not
reviewed its platform. Moreover, it does not provide a smart contract code