<!-- canonical: https://0xsimao.com/findings/autonomint-withdrawing-ionic-liquidation-flaw -->

# Withdrawing ionic during liquidation has a flaw

Medium · Sherlock · Hedged stablecoin · 4th December 2024

Finding M-5 of the Autonomint competition.

- Protocol: https://audits.sherlock.xyz/contests/569
- Report: /reports/autonomint
- Codebase: https://github.com/0xsimao/2024-11-autonomint/tree/0d324e04d4c0ca306e1ae4d4c65f0cb9d681751b
- Source: https://github.com/sherlock-audit/2024-11-autonomint-judging/issues/198

---

### Summary
During liquidation only record yield accrued from IONIC, however those yields are not utilized/there is no way to withdraw them.

### Root Cause
The case where we update `treasury.updateInterestFromExternalProtocol` we use  `treasury.withdrawFromExternalProtocolDuringLiq(user, index)`, which essentially gives us only the extra yield accrued:
```solidity
    function withdrawFromExternalProtocolDuringLiq(address user, uint64 index) external onlyCoreContracts returns (uint256)
    {
        uint256 balanceBeforeWithdraw = address(this).balance;
        uint256 redeemAmount = withdrawFromIonicDuringLiq(user, index);
        if (address(this).balance < redeemAmount + balanceBeforeWithdraw) {
            revert Treasury_WithdrawExternalProtocolDuringLiqFailed();
        }
@>>     return (redeemAmount - (borrowing[user].depositDetails[index].depositedAmount * 50) / 100);
    } 
```

Reference during liquidation:
```solidity
       // Update treasury data
        treasury.updateTotalVolumeOfBorrowersAmountinWei(depositDetail.depositedAmountInETH);
        treasury.updateTotalVolumeOfBorrowersAmountinUSD(depositDetail.depositedAmountUsdValue);
        treasury.updateDepositedCollateralAmountInWei(depositDetail.assetName, depositDetail.depositedAmountInETH);
        treasury.updateDepositedCollateralAmountInUsd(depositDetail.assetName, depositDetail.depositedAmountUsdValue);
@>>     treasury.updateTotalInterestFromLiquidation(totalInterestFromLiquidation);
        treasury.updateYieldsFromLiquidatedLrts(yields);
        treasury.updateDepositDetails(user, index, depositDetail);

        globalVariables.updateCollateralData(depositDetail.assetName, collateralData);
        globalVariables.setOmniChainData(omniChainData);

        // If the liquidation amount to get from other is greater than zero,
        // Get the amount from other chain.
        if (liqAmountToGetFromOtherChain > 0) {
            // Call the oftOrCollateralReceiveFromOtherChains function in global variables
            globalVariables.oftOrCollateralReceiveFromOtherChains{value: msg.value}(
                IGlobalVariables.FunctionToDo(3),
                IGlobalVariables.USDaOftTransferData(address(treasury), liqAmountToGetFromOtherChain),
                // Since we don't need ETH, we have passed zero params
                IGlobalVariables.CollateralTokenTransferData(address(0), 0, 0, 0),
                IGlobalVariables.CallingFunction.BORROW_LIQ,
                admin
            );
        }

        // If the collateral is ETH, withdraw the deposited ETH in external protocol
        if (depositDetail.assetName == IBorrowing.AssetName.ETH) {
@>>         treasury.updateInterestFromExternalProtocol(treasury.withdrawFromExternalProtocolDuringLiq(user, index));
        }
```
As it can be seen above `updateTotalInterestFromLiquidation` is also updated, but we have a way to withdraw it in [Treasury.sol](https://github.com/sherlock-audit/2024-11-autonomint/blob/0d324e04d4c0ca306e1ae4d4c65f0cb9d681751b/Blockchain/Blockchian/contracts/Core_logic/Treasury.sol#L616-L625):
```solidity
    function withdrawInterest(
        address toAddress,
        uint256 amount
    ) external onlyOwner {
        require(toAddress != address(0) && amount != 0,"Input address or amount is invalid");
        require(amount <= (totalInterest + totalInterestFromLiquidation),"Treasury don't have enough interest");
        totalInterest -= amount;
        bool sent = usda.transfer(toAddress, amount);
        require(sent, "Failed to send Ether");
    }
```
As mentioned unfortunately we don't handle the yield from IONIC in any way, as the `interestFromExternalProtocolDuringLiquidation` property in `Treasury.sol` is unused:
```solidity
  function updateInterestFromExternalProtocol(uint256 amount) external onlyCoreContracts {
        interestFromExternalProtocolDuringLiquidation += amount;
    }
```

### Impact
- No way to withdraw or use the yield generated from IONIC, its just left unused.

### Mitigation
Either integrate a way to use the yield from IONIC, or a way to be withdrawn.
