Premium in ParticlePositionManager is used to cover trading fees accrued for the liquidity borrowed. When liquidating, a portion of the premium is also used for the liquidation reward.
The issue is that a borrower can open a position without any premium at all:
ParticlePositionManager::openPosition:
File: contracts/protocol/ParticlePositionManager.sol
240: if (
241: cache.token0PremiumPortion < params.tokenToPremiumPortionMin ||
242: cache.token1PremiumPortion < params.tokenFromPremiumPortionMin
243: ) revert Errors.InsufficientPremium();
params.tokenFrom/ToPremiumPortionMin are supplied by the borrower hence can be 0.
This removes any liquidation reward, since closeCache.tokenFrom/ToPremium is 0:
ParticlePositionManager::liquidatePosition:
File: contracts/protocol/ParticlePositionManager.sol
349: liquidateCache.liquidationRewardFrom =
350: ((closeCache.tokenFromPremium) * LIQUIDATION_REWARD_FACTOR) /
351: uint128(Base.BASIS_POINT);
352: liquidateCache.liquidationRewardTo =
353: ((closeCache.tokenToPremium) * LIQUIDATION_REWARD_FACTOR) /
354: uint128(Base.BASIS_POINT);
Thus any liquidation incentives are removed. Even if the position would immediately be liquidatable there would be no incentive to liquidate it. Other than possibly for the LP as they would get their liquidity back.
0 premium also robs the liquidity provider of any fees that would have been accrued for their borrowed liquidity:
ParticlePositionManager::_closePosition (same for the other branch of zeroForOne):
File: contracts/protocol/ParticlePositionManager.sol
461: cache.token0Owed = cache.token0Owed < cache.tokenToPremium ? cache.token0Owed : cache.tokenToPremium;
462: cache.token1Owed = cache.token1Owed < cache.tokenFromPremium ? cache.token1Owed : cache.tokenFromPremium;
Here, min(tokenOwed,tokenPremium) is taken, since tokenPremium would be 0 no fees would be owed.
A borrower can open a position without any premium. This removes any incentive to liquidate the position and also robs the liquidity provider of fees that would have been accrued.
In the extreme, if you for example open a long position above the price (thus with no leverage), a borrower will not need to provide any funds at all. Thus can spam positions like this locking liquidity providers liquidity and denying them fees (if the trading moves in their direction).
Actually, the basic test testBaseOpenLongPosition in OpenPosition.t.sol already reproduces this:
function testOpenPositionWithoutPremium() public {
testBaseOpenLongPosition();
(,, uint128 token0Premium, uint128 token1Premium,,) = particleInfoReader.getOwedInfo(SWAPPER, 0);
assertEq(0,token0Premium);
assertEq(0,token1Premium);
}
Manual audit
Consider implementing a minimum enforced premium portion. Any premium portion would guarantee a reward to the liquidator.
Invalid Validation
The text was updated successfully, but these errors were encountered:
All reactions