NapierRouter.removeLiquidityOnePt() will be permanently DOS'd once the pool reaches maturity
Summary
NapierRouter.removeLiquidityOnePt() will always revert once the pool reaches maturity.
Vulnerability Detail
Once a napier pool reaches maturity, all deposits and swaps will be stopped only withdrawals are permitted; Napier Router offers users the option to withdraw only Principal token (pt), underlying token or both.
When withdrawing both pt and underlying via router it doesn't interact with any napier pool swap and deposit functions; when withdrawing only underlying, it checks if the pool has expired before calling the pool swap function and if it has expired it uses another alternative. But when the NapierRouter.removeLiquidityOnePt() is called which is supposed to allow users to withdraw only Pt there is no check to see if the pool has expired/ reached maturity before calling the swap function and there's no alternative if the pool has matured leaving the function inaccessible.
Impact
Users cannot withdraw only Principal tokens when the pool matures, especially those that deposited just Pt to the pool and would love to get it back.
NapierRouter. removeLiquidityOneUnderlying() swaps the baseLp token on curve pools for Pt then redeems it with Tranche contract for underlying token. A similar approach should be taken to fix NapierRouter.removeLiquidityOnePt(), I didn't go over the Tranche contract to recommend a direct fix.
PASCAL
medium
NapierRouter.removeLiquidityOnePt()
will be permanently DOS'd once the pool reaches maturitySummary
NapierRouter.removeLiquidityOnePt()
will always revert once the pool reaches maturity.Vulnerability Detail
Once a napier pool reaches maturity, all deposits and swaps will be stopped only withdrawals are permitted; Napier Router offers users the option to withdraw only Principal token (pt), underlying token or both. When withdrawing both pt and underlying via router it doesn't interact with any napier pool swap and deposit functions; when withdrawing only underlying, it checks if the pool has expired before calling the pool swap function and if it has expired it uses another alternative. But when the
NapierRouter.removeLiquidityOnePt()
is called which is supposed to allow users to withdraw only Pt there is no check to see if the pool has expired/ reached maturity before calling the swap function and there's no alternative if the pool has matured leaving the function inaccessible.Impact
Users cannot withdraw only Principal tokens when the pool matures, especially those that deposited just Pt to the pool and would love to get it back.
Code Snippet
https://github.com/sherlock-audit/2024-01-napier/blob/main/v1-pool/src/NapierRouter.sol#L740-L760
https://github.com/sherlock-audit/2024-01-napier/blob/main/v1-pool/src/NapierRouter.sol#L796-L814
https://github.com/sherlock-audit/2024-01-napier/blob/main/v1-pool/src/NapierPool.sol#L451-L460
Tool used
Manual Review
Recommendation
NapierRouter. removeLiquidityOneUnderlying()
swaps the baseLp token on curve pools for Pt then redeems it with Tranche contract for underlying token. A similar approach should be taken to fixNapierRouter.removeLiquidityOnePt()
, I didn't go over the Tranche contract to recommend a direct fix.