Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: low
Valid

Users could potentially use their own referral code

Summary

registerReferral is called from two different places. In VaultRouterBranch when a user initially deposits and in TradingAccountBranch when a user creates a new trading account through createTradingAccount. The problem is registerReferral always uses referrerCode to decode the user's address however that will not always be the case as seen in createTradingAccount which uses the account id. This allows a user to bypass that validation that prevents them from using their own referral code.

Vulnerability Details

in registerReferral there is a check that the decoded referral code does not equal the referrers address. The problem is that the referral code may not always be the user's address.
https://github.com/Cyfrin/2025-01-zaros-part-2/blob/39e33b2f6b3890573bb1affc41a7e520277ceb2c/src/referral/Referral.sol#L189C16-L192C18

// revert if the referral code decoded is the same as the referrer address
if (referrerAddress == abi.decode(referralCode, (address))) {
revert InvalidReferralCode();
}

In the case of createTradingAccount it passes in the user's trading account id. So the user would be able to encode what their referral id would be based on the current index and pass it into this function.
https://github.com/Cyfrin/2025-01-zaros-part-2/blob/39e33b2f6b3890573bb1affc41a7e520277ceb2c/src/perpetuals/branches/TradingAccountBranch.sol#L260C9-L264C10

if (referralCode.length != 0) {
referralModule.registerReferral(
abi.encode(tradingAccountId), msg.sender, referralCode, isCustomReferralCode
);
}

POC

Add this test to createTradingAccount.t.sol and run forge test --match-test test_UserCanUseOwnReferralCode

function test_UserCanUseOwnReferralCode()
external
givenTheTradingAccountTokenIsSet
whenTheUserHasAReferralCode
whenTheReferralCodeIsNotCustom
{
changePrank({ msgSender: users.naruto.account });
uint128 expectedTradingAccountId = 1;
bytes memory referralCode = abi.encode(expectedTradingAccountId);
address referralModule = perpsEngine.workaround_getReferralModule();
vm.expectEmit({ emitter: referralModule });
emit Referral.LogReferralSet(
address(perpsEngine), abi.encode(expectedTradingAccountId), users.naruto.account, referralCode, false
);
perpsEngine.createTradingAccount(referralCode, false);
}

Impact

User's can use their own referral code

Tools Used

Manual Review

Recommendations

Add more robust checks to see if a user is using their own code. In the case of creating a trading account where a user could create multiple accounts it wouldn't be able to use msg.sender to encode the referral code.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

User's can use their own referral code

Support

FAQs

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