Omniscia Evergon Labs Audit

TransferFundsAfterLiquidationFacet Manual Review Findings

TransferFundsAfterLiquidationFacet Manual Review Findings

TFL-01M: Inexistent Release of Bought NFT

Description:

The TransferFundsAfterLiquidationFacet::doBuyBackAfterLiquidation mechanism will not actually unlock the underlying NFT or release it to the new account that has paid for it which we consider invalid.

Impact:

A user who buys back a fractionalized wrapper NFT after it has been liquidated will not actually acquire it resulting in fund loss as the NFT will also become inaccessible by its original owner due to the state advancement.

Example:

packages/contracts/contracts/subInternalFacets/twoClickLiquidationPhaseFacets/liquidationBuyBackFacets/transferFundsAfterLiquidation/TransferFundsAfterLiquidationFacet.sol
23function doBuyBackAfterLiquidation(uint256 campaignId, address account, uint256 settledState) external onlyInternalDelegateCall {
24 FungibleAndSemiFungiblePurchaseStorage.IdInfo memory info = FungibleAndSemiFungiblePurchaseStorage.layout().infoForId[
25 campaignId
26 ];
27 uint256 totalFractionsPurchased = info.totalFractionsPurchased;
28 uint256 totalBuybackAmount = IBuybackAmountFacet(address(this)).getBuybackAmount(campaignId);
29 BuybackStorage.layout().obligationToEachFractionPerId[campaignId] = totalBuybackAmount / totalFractionsPurchased;
30 uint256 requiredBuybackAmount = ILendingOracleFacet(address(this)).getRemainingObligation(campaignId);
31
32 IERC20(info.fundingCurrency).safeTransferFrom(account, address(this), requiredBuybackAmount);
33
34 uint256 currentState = IStateFacet(address(this)).getStateOfId(campaignId);
35 IStateFacet(address(this)).changeState(campaignId, currentState, settledState);
36}

Recommendation:

We advise the TransferFundsAfterLiquidationFacet::doBuyBackAfterLiquidation function to release the underlying wrapper NFT represented by the fractionalized EIP-1155 NFT to its caller, ensuring that the buyback mechanism functions as intended.

Alleviation (71cda4ccfdcfa25fb96a4565f1f8143b350dd246):

The Evergon Labs team evaluated this exhibit and clarified that while the NFT is not meant to be released, the highlighted discrepancy does indicate a flaw in the way buybacks work whereby the forced unlock of an NFT should have happened before the buyback after a liquidation.

This type of validation was introduced to the function that ultimately invokes the TransferFundsAfterLiquidationFacet::doBuyBackAfterLiquidation function, alleviating this exhibit as a result.