Closed code423n4 closed 1 year ago
It is the user's responsibility to keep the credit enough to sustain the loan as clearly explained in the protocol documentation.
hansfriese marked the issue as unsatisfactory: Invalid
hansfriese marked the issue as satisfactory
wukong-particle marked the issue as sponsor disputed
Judge's screenshot is right. It's trader's responsibility to maintain a positive margin to avoid liquidation. If credit == 0 at position opening time, then, by design, lender is eligible to withdraw ETH immediately.
But we acknowledge the concern, will implement proper warning and messaging in our frontend.
hansfriese marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L253-L289 https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L434-L463 https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L544-L613 https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L192-L223
Vulnerability details
Impact
When calling the following
ParticleExchange.sellNftToMarket
function, it is possible to inputamount
andmsg.value
, which can sum up tolien.price
and makecredit
equal 0. Althoughcredit
ofliens[lienId]
is 0 in this case, calling theParticleExchange.sellNftToMarket
function by the borrower does not revert.https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L253-L289
Similarly, it is also possible to call the following
ParticleExchange.swapWithEth
function withmsg.value
equalinglien.price
. Although this causescredit
ofliens[lienId]
to be 0, calling theParticleExchange.swapWithEth
function does not revert either.https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L434-L463
Moreover,
uint256 newCredit = (oldLien.credit + oldLien.price - payableInterest) - newLien.price
can possibly be evaluated to 0 in the followingParticleExchange.refinanceLoan
function. Althoughcredit
ofliens[newLienId]
is 0 in this situation, calling theParticleExchange.refinanceLoan
function does not revert.https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L544-L613
However, when
lien.credit
is 0, the followingParticleExchange.withdrawEthWithInterest
function would evaluatepayableInterest < lien.credit
to false and consider the borrower insolvent. This means when the respective lien's credit is evaluated to 0 when theParticleExchange.sellNftToMarket
,ParticleExchange.swapWithEth
, andParticleExchange.refinanceLoan
functions are called, the lender of the respective lien can immediately call theParticleExchange.withdrawEthWithInterest
function, which would cause the respective lien's borrower to unexpectedly lose its position margin without having a chance to buy an NFT for repaying the lien.https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L192-L223
Proof of Concept
The following steps can occur for the described scenario for the
ParticleExchange.sellNftToMarket
function. The cases for theParticleExchange.swapWithEth
andParticleExchange.refinanceLoan
functions are similar.ParticleExchange.sellNftToMarket
function withamount
andmsg.value
both being 0.5e18 whilelien.price
is 1e18, which causes the lien's credit to be 0.ParticleExchange.withdrawEthWithInterest
function to withdrawlien.price
that is 1e18.ParticleExchange.sellNftToMarket
function would not allow an insolvent position to be opened, unexpectedly loses her position margin, which is 0.5e18, without having a chance to buy an NFT for repaying the lien.Tools Used
VSCode
Recommended Mitigation Steps
The
ParticleExchange.sellNftToMarket
,ParticleExchange.swapWithEth
, andParticleExchange.refinanceLoan
functions can be updated to check if the calculated credit of the respective lien is higher than a reasonable threshold value that is bigger than 0. If not, calling these functions should revert.Assessed type
Other