Closed code423n4 closed 1 year ago
hansfriese marked the issue as duplicate of #9
hansfriese marked the issue as satisfactory
Judge is correct, indeed duplication
wukong-particle marked the issue as sponsor confirmed
mitigated with https://github.com/Particle-Platforms/particle-exchange-protocol/pull/12 (imposing a max treasury rate)
Lines of code
https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L338-L393 https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L466-L515 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#L688-L748 https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L231-L246 https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L800-L806
Vulnerability details
Impact
Calling the following
ParticleExchange.buyNftFromMarket
,ParticleExchange.repayWithNft
,ParticleExchange.refinanceLoan
, andParticleExchange.auctionBuyNft
functions accrueinterestAccrued
for the corresponding lender. When calling these functions, the portions of these accrued interests that should belong to_treasury
are not accrued.https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L338-L393
https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L466-L515
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#L688-L748
Then, when calling the following
ParticleExchange._withdrawAccountInterest
function, the portion ofinterestAccrued[lender]
that should belong to_treasury
based on_treasuryRate
is accrued, and the remaining portion ofinterestAccrued[lender]
is sent to the corresponding lender.https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L231-L246
However, since
_treasuryRate
can be updated through calling the followingParticleExchange.setTreasuryRate
function,_treasuryRate
can be different wheninterestAccrued
is accrued and wheninterestAccrued
is withdrawn. If_treasuryRate
is lower wheninterestAccrued
is accrued and is higher wheninterestAccrued
is withdrawn, the interest received by the lender at the withdrawal time can be less than that if the interest could be withdrawn before_treasuryRate
becomes higher. As a result, the lender loses some interest that it is entitled to, which is unfair to the lender.https://github.com/code-423n4/2023-05-particle/blob/bbd1c01407a017046c86fdb483bbabfb1fb085d8/contracts/protocol/ParticleExchange.sol#L800-L806
Proof of Concept
The following steps can occur for the described scenario.
buyNftFromMarket
function is called for this lien, Alice'sinterestAccrued
becomes0.01e18
. At this moment,_treasuryRate
is1_000
.ParticleExchange.setTreasuryRate
function is called to change_treasuryRate
to5_000
.ParticleExchange.withdrawNftWithInterest
function, which further calls theParticleExchange._withdrawAccountInterest
function, to withdraw her interest that is0.01e18 * (1 - 5_000 / 10_000) = 0.005e18
._treasuryRate
is changed, she should receive0.01e18 * (1 - 1_000 / 10_000) = 0.009e18
, which is higher than0.005e18
. Hence, Alice loses0.009e18 - 0.005e18 = 0.004e18
in interest.Tools Used
VSCode
Recommended Mitigation Steps
The
ParticleExchange.buyNftFromMarket
,ParticleExchange.repayWithNft
,ParticleExchange.refinanceLoan
, andParticleExchange.auctionBuyNft
functions can be respectively updated to accrue the portion ofpayableInterest
that should belong to_treasury
based on the current_treasuryRate
and accrue the remaining portion ofpayableInterest
tointerestAccrued
for the corresponding lender. Then, theParticleExchange._withdrawAccountInterest
function can be updated to not accrue the portion ofinterestAccrued[lender]
for_treasury
or deduct such portion from the interest payable to the lender since these actions are already done in the updatedParticleExchange.buyNftFromMarket
,ParticleExchange.repayWithNft
,ParticleExchange.refinanceLoan
, andParticleExchange.auctionBuyNft
functions.Assessed type
Other