in MarketFactory.fund()
the claimed protocolFee is stored in the contract.
but no method is provided to withdraw it, resulting in a permanent lock.
Vulnerability Detail
in MarketFactory.fund() , it can claim protocolFee to MarketFactory.sol
contract MarketFactory is IMarketFactory, Factory {
.....
function fund(IMarket market) external {
if (!instances(IInstance(address(market)))) revert FactoryNotInstanceError();
@> market.claimFee();
}
contract Market is IMarket, Instance, ReentrancyGuard {
....
function claimFee() external {
Global memory newGlobal = _global.read();
@> if (_claimFee(address(factory()), newGlobal.protocolFee)) newGlobal.protocolFee = UFixed6Lib.ZERO;
...
}
From the above code, we can see that fund() will store the claim protocolFee in the contract.
But the MarketFactory.sol contract doesn't provide any way to withdraw it, so it's permanently locked in the contract.
Suggest fund() to transfer the fee Token directly to MarketFactory.owner().
bin2chen
high
fund() fee token be locked
Summary
in
MarketFactory.fund()
the claimedprotocolFee
is stored in the contract. but no method is provided to withdraw it, resulting in a permanent lock.Vulnerability Detail
in
MarketFactory.fund()
, it can claimprotocolFee
toMarketFactory.sol
From the above code, we can see that
fund()
will store the claimprotocolFee
in the contract. But theMarketFactory.sol
contract doesn't provide any way to withdraw it, so it's permanently locked in the contract. Suggestfund()
to transfer thefee Token
directly toMarketFactory.owner()
.Impact
reward token be locked
Code Snippet
https://github.com/sherlock-audit/2023-07-perennial/blob/main/perennial-v2/packages/perennial/contracts/MarketFactory.sol#L87-L90
Tool used
Manual Review
Recommendation
Duplicate of #52