Introduction
CoinFabrik was asked to audit the contracts for the AlexGo project. First we will
provide a summary of our discoveries and then we will show the details of our
findings.
Scope
The contracts audited are from the https://github.com/alexgo-io/alex-v1 git
repository. The audit is based on the commit
e268fd53370be3a271625bd45523ae07cb1239ac.
The audited contracts are:
● clarity/contracts/pool/alex-launchpad-v1-1.clar
: Launchpad
contract for IDO creation.
● clarity/contracts/pool/collateral-rebalancing-pool.clar
:
Contract for collateral-token pool creation.
● clarity/contracts/pool/yield-vault-alex.clar:
Vault for yield
tokens.
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.
Analyses
Without being limited to them, the audit process included the following analyses:
● Arithmetic errors
● Race conditions
● Misuse of block timestamps
● Denial of service attacks
● Excessive gas usage
● Needlessly complex code and contract interactions
● Poor or nonexistent error handling
● Insufficient validation of the input parameters
● Centralization and upgradeability
● Weak authentication
Summary of Findings
We found a medium issue and a minor issue. Also, two enhancements were
proposed.
The two issues were acknowledged.
Security Issues

Privileged Roles
These are the privileged roles that we identified on each of the audited contracts.
alex-launchpad-v1-1
Owner
The owner is the only role which can create ticket pools, required to start an IDO. It
is also capable of providing tickets to a pool, calling the claiming and refunding
function without waiting for the grace period to end, and transferring the entire
balance of a specific token to the owner.
Approved Operator
This role can also provide tickets to a pool and call the claiming and refunding
functions without waiting for the grace period to end.
IDO Owner
The IDO owners can add tickets to their pool and call the claiming and refunding
functions without waiting for the grace period to end.
Security Issues Found
Severity Classification
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.
Issues Status
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
decision.
● 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
decision.
● Mitigated: Implemented actions to minimize the impact or likelihood of the
risk.
Critical Severity Issues
No issues found.
Medium Severity Issues
ME-01 Launchpad: Full Distribution not Guaranteed
Location:
● clarity/contracts/pool/alex-launchpad-v1-1.clar:258-287
Launchpad randomness relies on moving positions along a chain of tickets, where
the distance of each step is determined by a random number generator, and for
each position where it stops, that ticket is determined as a winner. Each random
number is the result of a greater number modulus a predefined max_step. This
predefined value is general for each IDO and its formula (simplified for this
explanation) is:

Where registered is the number of tickets registered in the IDO by the players,
and winners is the amount of winner tickets the distribution can have.
As a consequence, full distribution is only guaranteed when

formula register number
because max_step results
in one or less than one, and therefore every player wins.
On the other hand, if that relation is not satisfied, fewer tickets might be distributed.
As a clear example, if there were only one winner ticket available and only one
ticket registered, max_step would be equal to 1.5. The player would win if the
position after the step falls between 0 and 1. Therefore, this player has a probability
of winning of just 66.67% in a single-player IDO.
Recommendation
If there are remaining tickets, a new round needs to be initiated, with the max_step
value adjusted to this amount.
Status
Acknowledged. The recommendation will be incorporated into the following IDOs.
Minor Severity Issues
MI-01 Launchpad: Tokens Locked due to Incomplete Distribution
Location:
● clarity/contracts/pool/alex-launchpad-v1-1.clar:258-287
If the tokens are not distributed because of the issue described in ME-01, they will
be locked in the contract unless the contract owner callstransfer-all-to-owner
(), which will transfer the tokens back to the owner.
Recommendation
If ME-01 remains unresolved, the IDO owner should be able to extract those tokens.
Status
Acknowledged. The development team considered the conditions of this issue
unlikely to be satisfied.
Enhancements
These items do not represent a security risk. They are best practices that we
suggest implementing.
Table

Details
EN-01 Launchpad: Unnecessary Assertions
Location:
● clarity/contracts/pool/alex-launchpad-v1-1.clar:269,353
A block’s VRF seed can be taken from a block already mined, a past block. The seed
used for the IDOs is from the block after the registration ends. However, the
assertions in lines 269 and 353 checks 𝑏𝑙𝑜𝑐𝑘𝐻𝑒𝑖𝑔ℎ𝑡 ≥ 𝑟𝑒𝑔𝑖𝑠𝑡𝑟𝑎𝑡𝑖𝑜𝑛𝐸𝑛𝑑𝐻𝑒𝑖𝑔ℎ𝑡,
while it can also fail because the seed cannot be taken if current block height is at
registration end or the block after it.
Moreover, the assertion in claim-process() will never fail becauseget-last-claim-walk-position()
is called before, and it will revert if the seed is
not available.
Status
Not implemented. The corresponding fixes are planned to be implemented in the
following iterations.
EN-02 Yield Vault: Misleading Response
Location:
● clarity/contracts/pool/yield-vault-alex.clar:161
If activated is equal to false, the response will be (ok true), even when only the
rewards are claimed, and they are not staked.
Status
Not implemented. The corresponding fixes are planned to be implemented in the
following iterations.
Other Considerations
The considerations stated in this section are not right or wrong. We do not suggest
any action to fix them. But we consider that they may be of interest for other
stakeholders of the project, including users of the audited contracts, owners or
project investors.
Centralization
Launchpad’s claiming and refunding functions are public and do not have
restrictions to be called by the users, when a grace period is passed. However, the
claiming functions require a list of winners ordered in sequence as an input. As a
consequence, if the off-chain task cannot be run, users will need to figure out the
sequence and pay the cost of, at least, the claiming of every user before them.
The refunding functions need the claiming function to be called before because
refund is only available when it is confirmed on-chain that the ticket is not a winner
ticket.
Moreover, launchpad contract owner can transfer all the tokens in the contract’s
balance.
Changelog
● 2022-04-08 – Initial report based on commite268fd53370be3a271625bd45523ae07cb1239ac.
● 2022-04-19 – Final report based on feedback provided by the development
team.
Disclaimer: This audit report is not a security warranty, investment advice, or an
approval of the AlexGo project since CoinFabrik has not reviewed its platform.
Moreover, it does not provide a smart contract code faultlessness guarantee.