Incorrect `ERC20` transfer in `withdrawFee` prevents fee withdrawal
The AdminOperationalTreasury.withdrawFee() function uses safeTransferFrom() instead of safeTransfer() when withdrawing protocol fees.
Severity
Impact: Medium
Likelihood: Medium
Description
The AdminOperationalTreasury.withdrawFee() function uses safeTransferFrom() instead of safeTransfer() when withdrawing protocol fees. This is incorrect because:
safeTransferFrom()requires the spender to have an allowance from the owner.- The contract is trying to transfer from itself (
address(this)) to the recipient. - The contract has not approved itself to spend its own tokens.
function withdrawFee(address token_, address recipient_) external {OperationalTreasuryStorage.Layout storage strg = OperationalTreasuryStorage.layout();if (msg.sender != strg.setUp.base.feesReceiver) revert("FeesReceiverOnly");uint256 amount = strg.ledger.collectedFees[token_];strg.ledger.collectedFees[token_] = 0;@> IERC20Metadata(token_).safeTransferFrom(address(this), recipient_, amount);emit ProtocolFeeWithdrawn(token_, recipient_, amount);}
For normal ERC20, transferFrom always checks the allowance of the spender, even when from is the same as msg.sender. As a result, the fee transfer will fail due to insufficient allowance.
Recommendation
Replace safeTransferFrom() with safeTransfer(), since the contract is transferring tokens it owns.
Report provenance
Published by Pashov Audit Group, with Carlos (Bloqarl) participating as a contractor. The source report states that its fixes review was not fully completed; no final remediation disposition is recorded for this finding. Read the full report.