When a liquidation is finalized in the Stability Pool, all of the user’s NFTs are transferred to the Stability Pool. However, there is no function in StabilityPool.sol to manage or transfer these NFTs, leading to a permanent lock of assets. Additionally, external contracts like Treasury.sol or an auction contract cannot retrieve or liquidate these NFTs, rendering them inaccessible without governance intervention.
Lack of NFT Management in Stability Pool
When finalizeLiquidation()
is executed, the liquidated user’s NFTs are transferred to the Stability Pool.
However, StabilityPool does not provide any function to transfer or sell NFTs, meaning they cannot be accessed, used, or liquidated.
External Contracts Cannot Retrieve NFTs
Even if another contract (e.g., Treasury.sol) is designed to manage liquidated assets, it cannot retrieve NFTs from StabilityPool. This is because ERC-721 tokens require explicit approval (setApprovalForAll()
) or direct transfers initiated by the contract holding them.
Since StabilityPool lacks a transfer function, these NFTs remain permanently locked in the contract.
Governance or Smart Contract Upgrade is Required for Recovery
Without an immediate fix, retrieving the locked NFTs would require a protocol upgrade via a governance proposal or a manual intervention from the deployer (if upgradeable via proxy).
This creates an unacceptable UX failure and can significantly harm the protocol.
Permanently Locked NFTs: Users who are liquidated will have their NFTs transferred to StabilityPool, but those NFTs will be stuck indefinitely since there is no function to access/transfer them.
Funds & Assets Cannot Be Recovered: Even if the protocol wants to auction or repurpose these NFTs, there is no way to interact with them.
Governance Dependency for Recovery: The only way to fix this issue is through a governance proposal or smart contract upgrade, which is slow, inconvenient, and potentially unfeasible in urgent cases.
Manual
Modify StabilityPool.sol to allow governance or an authorized entity to transfer NFTs out:
This ensures that NFTs do not remain stuck and can be sent to another contract for proper handling.
Alternatively, modify finalizeLiquidation()
so that liquidated NFTs are not sent to StabilityPool but directly to Treasury or a contract that can manage, liquidate, or redistribute them.
If StabilityPool is intended to sell or distribute these NFTs, implement an auction or liquidation function for this specific purpose too.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.