Tadle

Tadle
DeFi
30,000 USDC
View results
Submission Details
Severity: high
Valid

Referral system incorrectly sets the referrer address, allowing users to be both the referrer and the authority simultaneously.

Summary

Users can set the same address as both the referrer and authority simultaneously, which will lead to incorrect rewards distribution because all rewards would go to a single address.

Vulnerability Details

The protocol gives users the ability to set a referrer for taker orders, so rewards are split between the user and the referrer, allowing for reduced platform fees. However, the problem lies in how updateReferrer incorrectly sets the referrer address, as seen here (https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/SystemConfig.sol#L69-L70):

ReferralInfo storage referralInfo = referralInfoMap[_referrer]; // bug is here
referralInfo.referrer = _referrer

Because in createTaker we retrieve referralInfo like this (https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L199-L201):

ReferralInfo memory referralInfo = systemConfig.getReferralInfo(
_msgSender()
);

This means that referralInfo.referrer will always be msg.sender itself, leading to referral rewards being distributed to a single user (https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L868-L886).

tokenManager.addTokenBalance(
TokenBalanceType.ReferralBonus,
this is msg.sender @> referralInfo.referrer,
makerInfo.tokenAddress,
referrerReferralBonus
);
uint256 authorityReferralBonus = platformFee.mulDiv(
referralInfo.authorityRate,
Constants.REFERRAL_RATE_DECIMAL_SCALER,
Math.Rounding.Floor
);
tokenManager.addTokenBalance(
TokenBalanceType.ReferralBonus,
this is msg.sender too @> _msgSender(),
makerInfo.tokenAddress,
authorityReferralBonus
);

Impact

The referral system won’t function properly, and users can set themselves as their own referrers (using a different account), leading to significant protocol losses in fees. This is because anyone can make all orders cheaper for themselves by the baseReferralRate value.

PoC

import {ReferralInfo} from "../src/interfaces/ISystemConfig.sol";
...
function testReferrerBug() public{
vm.startPrank(user);
preMarktes.createOffer(
CreateOfferParams(
marketPlace,
address(mockUSDCToken),
1000,
0.01 * 1e18,
12000,
300,
OfferType.Ask,
OfferSettleType.Turbo
)
);
vm.stopPrank();
vm.startPrank(user1);
// our user will have some extra rewards
systemConfig.updateReferralExtraRateMap(user, 700_000);
vm.stopPrank();
// just update it from random address
systemConfig.updateReferrerInfo(user, baseReferralRate, 700_000);
ReferralInfo memory ref_info = systemConfig.getReferralInfo(user);
@> assertTrue(ref_info.referrer == user); // BUG IS HERE: USER AND REFERRER ARE THE SAME PERSON
vm.startPrank(user);
address offerAddr = GenerateAddress.generateOfferAddress(0);
preMarktes.createTaker(offerAddr, 1);
console2.log(tokenManager.userTokenBalanceMap(user, address(mockUSDCToken), TokenBalanceType.ReferralBonus));
// OUTPUT:
// 50000000000
// BUT IN REALITY, WE HAVE 2 DIFFERENT REWARDS WHICH ARE EQUAL TO:
// referrerReferralBonus = 15000000000 - this should go to the referrer (which should not be the same person as msg.sender)
// authorityReferralBonus = 35000000000 - and this should go to msg.sender
vm.stopPrank();
}

Tools Used

Foundry.

Recommendations

Fix it so that referral info is received for msg.sender instead of _referrer.

- ReferralInfo storage referralInfo = referralInfoMap[_referrer];
+ ReferralInfo storage referralInfo = referralInfoMap[_msgSender()];
Updates

Lead Judging Commences

0xnevi Lead Judge 9 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-SystemConfig-updateReferrerInfo-msgSender

Valid high severity. There are two impacts here due to the wrong setting of the `refferalInfoMap` mapping. 1. Wrong refferal info is always set, so the refferal will always be delegated to the refferer address instead of the caller 2. Anybody can arbitrarily change the referrer and referrer rate of any user, resulting in gaming of the refferal system I prefer #1500 description the most, be cause it seems to be the only issue although without a poc to fully describe all of the possible impacts

Support

FAQs

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