QuantAMM

QuantAMM
49,600 OP
View results
Submission Details
Severity: high
Valid

Owner Fee in `UpliftOnlyExample::onAfterSwap` Sent to Contract Without Withdrawal Mechanism

Summary

In the UpliftOnlyExample::onAfterSwap function, the ownerFee is calculated and sent to address(this) instead of the owner's address. Additionally, there is no function or mechanism for the owner to withdraw these funds, effectively locking them in the contract.

Vulnerability Details

The onAfterSwap function sends the calculated ownerFee to the contract's address (address(this)), as shown below:

if (ownerFee > 0) {
_vault.sendTo(feeToken, address(this), ownerFee); //@audit
}

Since the contract does not include a mechanism for the owner to withdraw these fees, the funds become inaccessible. This oversight prevents the owner from claiming fees earned through swaps.

Impact

The owner loses access to the ownerFee funds.

POC

The following test demonstrates the issue, where the ownerFee is locked in the contract:

function testOwnerFee() public {
uint256 swapAmount = 1e18;
uint64 hookFeePercentage = 0.1e16;
vm.prank(owner);
UpliftOnlyExample(payable(poolHooksContract)).setHookSwapFeePercentage(hookFeePercentage);
uint256 hookFee = swapAmount.mulUp(hookFeePercentage);
BaseVaultTest.Balances memory balancesBefore = getBalances(address(upliftOnlyRouter));
vm.prank(bob);
router.swapSingleTokenExactIn(address(pool), dai, usdc, swapAmount, 0, MAX_UINT256, false, bytes(""));
BaseVaultTest.Balances memory balancesAfter = getBalances(address(upliftOnlyRouter));
assertEq(
balancesAfter.userTokens[usdcIdx] - balancesBefore.userTokens[usdcIdx], hookFee, "hook fee is not in upliftOnlyRouter"
);
}

Recommendations

To address this issue, implement one of the following solutions:

  1. Directly Send Fees to Owner Address:

  2. Add a Restricted Withdrawal Function:

Updates

Lead Judging Commences

n0kto Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_ownerFee_cannot_be_withdrawn

Likelihood: High, every swap. Impact: High, funds are stuck.

Support

FAQs

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