Adversary can game the liquidation flow by transfering a dust amount of the payment token to ClearingHouse contract to settle the auction if no one buy the auctioned NFT #112
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
M-30
primary issue
Highest quality submission among a set of duplicates
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
Lines of code
https://github.com/code-423n4/2023-01-astaria/blob/1bfc58b42109b839528ab1c21dc9803d663df898/src/ClearingHouse.sol#L169
https://github.com/code-423n4/2023-01-astaria/blob/1bfc58b42109b839528ab1c21dc9803d663df898/src/ClearingHouse.sol#L123
Vulnerability details
Impact
Adversary can game the liquidation flow by transfering a dust amount of the payment token to ClearingHouse contract to settle the auction
Proof of Concept
The function ClearingHouse#safeTransferFrom is meant to settle the auction but the function severely lack of access control
which calls:
We can look into the liquidation flow:
first, the liquidate function is called in AstariaRouter.sol
then function auctionVault is called in CollateralToken
the function _generateValidOrderParameters is important:
note the first consideration item:
prices[0] is the initialLiquidationPrice the starting price, prices[1] is the ending price, which is 1000 WEI. this means if no one buy the dutch auction, the price will fall to 1000 WEI.
In the code above, note that the code check if the current balance of the payment token is larger than currentOfferPrice computed by _locateCurrentAmount, this utility function comes from seaport.
https://github.com/ProjectOpenSea/seaport/blob/f402dac8b3faabdb8420d31d46759f47c9d74b7d/contracts/lib/AmountDeriver.sol#L38
If there is no one buy the dutch auction, the price will drop to until 1000 WEI, which means _locateCurrentAmount returns lower and lower price.
In normal flow, if no one buy the dutch auction and cover the outstanding debt, the NFT can be claimabled by liquidator. The liquidator can try to sell NFT again to cover the debt and loss for lenders,
However, if no one wants to buy the dutch auction and the _locateCurrentAmount is low enough, for example, 10000 WEI, an adversary can transfer 10001 WEI of ERC20 payment token to the ClearingHouse contract
Then call safeTransferFrom to settle the auction.
the code below will execute
.
beceause the airdropped ERC20 balance make the payment larger than currentOfferPrice
In this case, the adversary blocks the liquidator from claiming the not-auctioned liquidated NFT.
the low amount of payment 10001 WEI is not likely to cover the outstanding debt and the lender has to bear the loss.
Tools Used
Manual Review
Recommended Mitigation Steps
We recommend the protocol validate the caller of the safeTransferFrom in ClearingHouse is the seaport / conduict contract and check that when the auction is settled, the NFT ownership changed and the Astaria contract does not hold the NFT any more.
The text was updated successfully, but these errors were encountered: