Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: high
Valid

Insufficient Access Controls On `updateReferrerInfo(address,uint256,uint256)`

Summary

The updateReferrerInfo(address,uint256,uint256) function may be called arbitrarily to manipulate the outcome of platform fee accrual for other users, meanwhile the referral system itself is ineffective for incentivising other referrals.

Vulnerability Details

In Tadle, the SystemConfig contract defines a referralInfoMap which is used to modulate the distribution of platform fees between a referrer and authority.

The contents of each mapping element is as follows:

struct ReferralInfo {
address referrer;
uint256 referrerRate;
uint256 authorityRate;
}

This object defines how core platform fees are distributed.

Notice then, that we can manipulate the ReferralInfo through an unprotected call to updateReferrerInfo(address,uint256,uint256):

/**
* @notice Update referrer setting
* @param _referrer Referrer address
* @param _referrerRate Referrer rate
* @param _authorityRate Authority rate
* @notice _referrerRate + _authorityRate = baseReferralRate + referralExtraRate
* @notice _referrer != _msgSender()
*/
function updateReferrerInfo(
address _referrer,
uint256 _referrerRate,
uint256 _authorityRate
) external {
if (_msgSender() == _referrer) { /// @audit we_can_satisfy_access_controls_for_any_other_account_except_our_own
revert InvalidReferrer(_referrer);
}
if (_referrer == address(0x0)) {
revert Errors.ZeroAddress();
}
if (_referrerRate < baseReferralRate) {
revert InvalidReferrerRate(_referrerRate);
}
uint256 referralExtraRate = referralExtraRateMap[_referrer];
uint256 totalRate = baseReferralRate + referralExtraRate;
if (totalRate > Constants.REFERRAL_RATE_DECIMAL_SCALER) {
revert InvalidTotalRate(totalRate);
}
if (_referrerRate + _authorityRate != totalRate) {
revert InvalidRate(_referrerRate, _authorityRate, totalRate);
}
ReferralInfo storage referralInfo = referralInfoMap[_referrer]; /// @audit modifying_other_referrer_and_not_msgSender()
referralInfo.referrer = _referrer;
referralInfo.referrerRate = _referrerRate; /// @audit modify_referrer_arbitrarily
referralInfo.authorityRate = _authorityRate; /// @audit modify_referrer_arbitrarily
emit UpdateReferrerInfo(
msg.sender,
_referrer,
_referrerRate,
_authorityRate
);
}

Notice here that since we are writing to referralInfoMap[_referrer] and we are assigning referralInfo.referrer = _referrer, an account may technically only ever refer to itself (even though we explicitly prevent the same account from modifying its own mapping entry, but this is easily bypassed by using a different wallet).

Impact

Users can grief other participants by defining a referrerRate and authorityRate combination which can affect the outcome of platform fee accrual, for example, by reducing a victim's share of due fee revenue. For example, an authority may front run the transaction to skew the distribution of fees entirely in their own favour by configurring referrerRate to zero and the _authorityRate to the sum of baseReferralRate + referralExtraRate.

Additionally, it is impossible for an account to have a referral address which isn't their own, since:

ReferralInfo storage referralInfo = referralInfoMap[_referrer];
referralInfo.referrer = _referrer;

This renders the incentive system ineffective.

Tools Used

Manual Review

Recommendations

When calling updateReferrerInfo(address,uint256,uint256), we should be writing to the msgSender()'s ReferralInfo_ _object and not the _referrer:

if (_referrerRate + _authorityRate != totalRate) {
revert InvalidRate(_referrerRate, _authorityRate, totalRate);
}
ReferralInfo storage referralInfo = referralInfoMap[_msgSender()]; /// @audit update_their_own_mapping_entry
Updates

Lead Judging Commences

0xnevi Lead Judge 12 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.