Category: Coding Mistakes
Wrong ERC in reserve pool could brick fee system
Medium Severity
Medium Impact
Low Likelihood
Description
In FeesHandler, the function claimFees
is used to claim fees from cozySafetyModuleManager
. This function always iterates all reserve pools. But if one reserve pool causes the call to revert then claimFees
always fails.
In this case, since there is no function to collect fees from each reserve pool, the fees become trapped in the SafetyModule.
function claimFees(address owner_) external {
// Cozy fee claims will often be batched, so we require it to be initiated from the CozySafetyModuleManager to save
// gas by removing calls and SLOADs to check the owner addresses each time.
if (msg.sender != address(cozySafetyModuleManager)) revert Ownable.Unauthorized();
IDripModel dripModel_ = cozySafetyModuleManager.getFeeDripModel(ISafetyModule(address(this)));
uint256 numReservePools_ = reservePools.length;
for (uint8 i = 0; i < numReservePools_; i++) {
ReservePool storage reservePool_ = reservePools[i];
_dripFeesFromReservePool(reservePool_, dripModel_);
uint256 feeAmount_ = reservePool_.feeAmount;
if (feeAmount_ > 0) {
IERC20 asset_ = reservePool_.asset;
reservePool_.feeAmount = 0;
assetPools[asset_].amount -= feeAmount_;
asset_.safeTransfer(owner_, feeAmount_);
emit ClaimedFees(asset_, feeAmount_, owner_);
}
}
}
Impact
A malicious owner of the SafetyModule could create incorrect ERC tokens and add them to the reserve-pool list. As a result, the cozySafetyModuleManager
would fail to collect fees from the SafetyModule.
Recommendations
We recommend adding a function to collect from each reserve pool. This measure would help prevent incorrect ERC tokens from obstructing the fee collection process.