Part 2

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

Empty Referral Codes Allow Fraudulent Reward Claims

Summary

The referral system has a critical flaw where users can register with empty referral codes. This allows attackers to fraudulently claim rewards without valid referrals, risking financial losses and damaging trust in the system.


Vulnerability Details

Technical Breakdown

The registerReferral function lacks validation for empty referral codes:

function registerReferral(
bytes calldata referrerCode,
address referrerAddress,
bytes calldata referralCode,
bool isCustomReferralCode
) external onlyRegisteredEngines {
// ❌ Missing check for empty referralCode
if (referralCode.length != 0) {
// Validation only for non-empty codes
// ...
}
emit LogReferralSet(...); // Event emitted even for empty codes
}

This skips validation for empty codes and logs them as valid, making fraud detection difficult.

POC(Proof Of Concept)

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
import {Test} from "forge-std/Test.sol";
import {Referral} from "@zaros/referral/Referral.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {Vm} from "forge-std/Vm.sol";
contract ReferralZeroAddressEngineTest is Test {
Referral referral;
Referral implementation;
ERC1967Proxy proxy;
address owner = makeAddr("zaros");
function setUp() external {
implementation = new Referral(); bytes memory initData = abi.encodeWithSelector(Referral.initialize.selector, owner);
proxy = new ERC1967Proxy(address(implementation), initData);
referral = Referral(address(proxy));
}
function test_revertOnEmptyReferralCodePreventsFraud() public {
address attacker = makeAddr("attacker");
address engine = makeAddr("engine");
bytes memory emptyCode = "";
vm.prank(owner);
referral.configureEngine(engine, true);
// Attempt to register with empty referral code
vm.prank(engine);
vm.expectRevert("InvalidReferralCode");
//should have revert with empty referral code
referral.registerReferral(
abi.encode(attacker),
attacker,
emptyCode,
false
);
// Verify no referral data created
(bytes memory code, ) = referral.getUserReferralData(abi.encode(attacker));
assertEq(code.length, 0, "Fraudulent empty code accepted");
}
}

Impact

  • Financial Loss: Attackers drain rewards meant for legitimate users.

  • Fake Data: Empty codes corrupt referral tracking.

  • Lost Trust: Users lose confidence in the system.

Tools Used

  1. Foundry: Automated tests to detect empty code acceptance.

  2. Manual Code Review: Identified missing validation checks.

Recommendations
1. Block Empty Codes:
Add a validation check to reject empty codes:

function registerReferral(...) external onlyRegisteredEngines {
require(referralCode.length > 0, "InvalidReferralCode"); // ✅ Block empty codes
// Rest of validation logic for non-empty codes
// ...
emit LogReferralSet(...); // Only for valid codes
}

2.Add Test Cases:
Verify empty codes are rejected:

function test_emptyReferralCodeReverts() public {
address attacker = makeAddr("attacker");
bytes memory emptyCode = "";
vm.prank(registeredEngine);
vm.expectRevert("InvalidReferralCode");
referral.registerReferral(
abi.encode(attacker),
attacker,
emptyCode,
false
);
// Confirm no referral data exists
(bytes memory code, bool isCustom) = referral.getUserReferralData(abi.encode(attacker));
assertEq(code.length, 0, "Empty code was accepted");
}
  1. Improve Event Logging:
    Separate events for valid/invalid attempts:

    event ValidReferralSet(...);
    event InvalidReferralAttempt(...);
    function registerReferral(...) external {
    if (referralCode.length == 0) {
    emit InvalidReferralAttempt(...);
    revert("InvalidReferralCode");
    }
    // ... rest of logic ...
    emit ValidReferralSet(...);
    }
Updates

Lead Judging Commences

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

Support

FAQs

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