Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

Multiple Referral Entries via Arbitrary referrerCode Allowing Bypass of "One Referral per Engine" Rule

Summary

The Referral contract is designed to enforce a rule where each user can have only one referrer per engine. However, the current implementation allows a malicious user to bypass this restriction by generating multiple arbitrary referrerCode values. This is because the system uses the referrerCode (a user-provided bytes input) as the key for tracking referrals, rather than the user's address. As a result, a user can create multiple unique referrerCode values, each associated with their address, and register multiple referrals per engine, violating the intended "one referral per engine" rule.

/// @dev Referrals are used to track the referrer of a user.
@audit @--> /// @dev In the current version of the contract each user can have only one referrer per engine.
contract Referral is IReferral, OwnableUpgradeable, UUPSUpgradeable {
using ReferralConfiguration for ReferralConfiguration.Data;

Vulnerability Details

The vulnerability lies in the registerReferral function, which uses the referrerCode as the key in the listOfReferrals mapping. The function checks if a referral already exists for the provided referrerCode using the verifyIfUserHasReferral function. However, this check is flawed because it only verifies if the specific referrerCode has been used before, not if the user's address has already been associated with a referral.

Exploit Steps:

  1. A user generates a unique referrerCode (e.g., hex"01") and registers a referral using a valid referralCode.

  2. The same user generates another unique referrerCode (e.g., hex"02") and registers a different referral.

  3. Since each referrerCode is treated as a unique key in the listOfReferrals mapping, both referrals are stored under different keys, even though they are associated with the same user address.

Code Analysis:

  • The registerReferral function checks if a referral exists for the provided referrerCode:

    if (verifyIfUserHasReferral(referrerCode)) {
    revert ReferralAlreadyExists();
    }
  • The verifyIfUserHasReferral function checks if the referrerCode has been used before:

    return referralConfiguration.listOfReferrals[referrer].referralCode.length > 0;
  • However, there is no check to ensure that the same user address (referrerAddress) is not already associated with a different referrerCode.

Impact:

This vulnerability allows a malicious user to bypass the "one referral per engine" rule by generating multiple referrerCode values.sses for the platform.

Tools Used

Manual review

Recommendations

Modify the listOfReferrals Mapping: Change the mapping to use the user's address as the key:

mapping(address engine => mapping(address referrerAddress => ReferralData)) public listOfReferrals;
Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!