protocolFeeReceiver can sometimes receive more fees than expected
Summary
Everytime when a user claims his incentive, the protocol fee receiver will receive the whole balance of the contract BoostCore, which can be way more than expected as a user can send more ETH than the fee required.
Root Cause
The function BoostCore::_routeClaimFee is responsible to route the claim fee to the creator, referrer, and protocol fee receiver. It basically starts with the received claimeFee in ETH by sending a portion to the referer, then giving half of the rest to the boost creator. However, instead of sending what has left of the received claimeFee, it sends the whole current balance of ETH in the contract BoostCore to the protocol fee receiver.
function _routeClaimFee(BoostLib.Boost storage boost, address referrer_) internal {
if (claimFee == 0) return;
uint256 netFee = claimFee;
// If a referrer is provided, transfer the revshare and reduce the net fee
if (referrer_ != address(0)) {
uint256 referralShare = claimFee * boost.referralFee / FEE_DENOMINATOR;
netFee -= referralShare;
referrer_.safeTransferETH(referralShare);
}
// The remaining fee is split between the owner and the protocol
boost.owner.safeTransferETH(netFee / 2);
>> protocolFeeReceiver.safeTransferETH(address(this).balance);
}
Internal pre-conditions
NA
External pre-conditions
A user sends more fees than expected.
Another user claims at the same time his incentive.
Attack Path
NA
Impact
There are several potential impacts:
Another user sends ETH to claim his incentive can have his transaction revert as the current BoostCore balance is 0
A user will have his remaining ETH after deduction of claim fee sent to the protocol fee receiver.
PoC
NA
Mitigation
The protocol should only receive what has left of claimFee and send back the remaining to the end user.
function _routeClaimFee(BoostLib.Boost storage boost, address referrer_) internal {
if (claimFee == 0) return;
uint256 netFee = claimFee;
// If a referrer is provided, transfer the revshare and reduce the net fee
if (referrer_ != address(0)) {
uint256 referralShare = claimFee * boost.referralFee / FEE_DENOMINATOR;
netFee -= referralShare;
referrer_.safeTransferETH(referralShare);
}
// The remaining fee is split between the owner and the protocol
boost.owner.safeTransferETH(netFee / 2);
- protocolFeeReceiver.safeTransferETH(address(this).balance);
+ protocolFeeReceiver.safeTransferETH(netFee - netFee / 2);
+ if (msg.value > claimFee) {
+ address(msg.sender).safeTransferETH(msg.value - claimFee);
+ }
}
befree3x
Medium
protocolFeeReceiver
can sometimes receive more fees than expectedSummary
Everytime when a user claims his incentive, the protocol fee receiver will receive the whole balance of the contract
BoostCore
, which can be way more than expected as a user can send more ETH than the fee required.Root Cause
The function
BoostCore::_routeClaimFee
is responsible to route the claim fee to the creator, referrer, and protocol fee receiver. It basically starts with the receivedclaimeFee
in ETH by sending a portion to the referer, then giving half of the rest to the boost creator. However, instead of sending what has left of the receivedclaimeFee
, it sends the whole current balance of ETH in the contractBoostCore
to the protocol fee receiver.Reference: https://github.com/sherlock-audit/2024-06-boost-aa-wallet/blob/main/boost-protocol/packages/evm/contracts/BoostCore.sol#L318
Internal pre-conditions
NA
External pre-conditions
Attack Path
NA
Impact
There are several potential impacts:
BoostCore
balance is 0PoC
NA
Mitigation
The protocol should only receive what has left of
claimFee
and send back the remaining to the end user.