Summary
The customReferral.referrer can receive a referral bonus by setting itself as referrer when creating a TradingAccount.
Vulnerability Details
In the TradingAccountBranch.sol#createTradingAccount() function, referralCode is set so that the referrer can receive a referral bonus.
function createTradingAccount(
bytes memory referralCode,
bool isCustomReferralCode
)
public
virtual
returns (uint128 tradingAccountId)
{
SNIP...
Referral.Data storage referral = Referral.load(msg.sender);
if (referralCode.length != 0 && referral.referralCode.length == 0) {
257: if (isCustomReferralCode) {
CustomReferralConfiguration.Data storage customReferral =
CustomReferralConfiguration.load(string(referralCode));
if (customReferral.referrer == address(0)) {
revert Errors.InvalidReferralCode();
}
referral.referralCode = referralCode;
referral.isCustomReferralCode = true;
265: } else {
address referrer = abi.decode(referralCode, (address));
268: if (referrer == msg.sender) {
269: revert Errors.InvalidReferralCode();
270: }
referral.referralCode = referralCode;
referral.isCustomReferralCode = false;
}
emit LogReferralSet(msg.sender, referral.getReferrerAddress(), referralCode, isCustomReferralCode);
}
return tradingAccountId;
}
As you can see in the provided code snippet, if isCustomReferralCode is false, it checks whether referrer is msg.sender, but if it is true, it does not check.
The customReferral.referrer can be an EOA as a custom referrer set in the contract, and therefore the referrer itself can create a TradingAccount.
However, because it does not check whether the referrer is the caller (msg.sender), the referrer can create its own account and receive an unfair referral bonus.
Impact
The customReferral.referrer can create its own account and receive an unfair referral bonus.
Tools Used
Manual Review
Recommendations
It would be a good idea to add a check to check if customReferral.referrer is caller(msg.sender).
if (isCustomReferralCode) {
CustomReferralConfiguration.Data storage customReferral =
CustomReferralConfiguration.load(string(referralCode))
if (customReferral.referrer == address(0)) {
revert Errors.InvalidReferralCode();
}
+++ if (customReferral.referrer == msg.sender) {
+++ revert Errors.InvalidReferralCode();
+++ }
referral.referralCode = referralCode;
referral.isCustomReferralCode = true;
} else {
address referrer = abi.decode(referralCode, (address));
if (referrer == msg.sender) {
revert Errors.InvalidReferralCode();
}
referral.referralCode = referralCode;
referral.isCustomReferralCode = false;
}