Open c4-bot-3 opened 10 months ago
141345 marked the issue as primary issue
141345 marked the issue as sufficient quality report
Alec1017 (sponsor) confirmed
0xean marked the issue as satisfactory
0xean marked the issue as selected for report
Hi @0xean ,
It seems Issue #600 also identifies the same root cause as this issue: A lender can implement a malicious callback to DOS the stop
calls.
However, this issue does not demonstrate a freezing of victim (renter) "owned" assets. In this issue the lender (attacker) is allowing their NFT and rental payment to be frozen in order to grief the victim. However, I would argue that the victim is not impacted in a way that warrants a high
severity. Although the victim can not receive the proposed rental payment, they will essentially be able to utilize the rented NFT while the lender is "griefing" them. The renter is only losing "theoretical capital" in this situation (i.e. the rental payment, which was supplied by the attacker), but would be gaining access to the rented NFT for additional time.
Meanwhile, issue #600 has identified how to leverage the root cause in this issue with another bug (safe wallet can't differentiate between non-rented and rented ERC1155 tokens
) in order to permanently freeze a victim's ERC1155 tokens in their safe wallet.
Given the information above, can you please provide the rationale behind labeling this issue (and duplicates) as high
severity, while labeling issue #600 (and duplicates) as medium
severity? Based on my observations it seems this issue (and duplicates) should be of medium
severity. However, if its high
severity status is maintained, then I would think that issue #600 (and its duplicates) should be of high
severity as well since these issues demonstrate a greater impact.
I appreciate you taking the time to read my comment.
@0xJCN thanks for the comment.
I have re-read the impact and better understand this issue as a result. I do not agree that this loss is "theoretical", a withheld payment is not theoretical, however it is temporary if the lender has any intention to ever receive back their NFT and therefore since its temporary and not a complete loss I do think M is more appropriate.
This is final.
0xean changed the severity to 2 (Med Risk)
Hi @0xean, I agree with @0xJCN here but I believe there are a couple of duplicates in this finding which should be de-duped and for which the impact does qualify as high. The issue is largely the same, but these submissions recognize that it can also be exploited by the renter, in which scenario:
See issue #634 for a more detailed description. #379 and #487 are the only duplicates as far as I can see.
leaving these as judged.
Lines of code
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Reclaimer.sol#L33 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Reclaimer.sol#L43
Vulnerability details
In a PAY order lending, the renter is payed by the lender to rent the NFT. When the rent is stopped,
Stop.stopRent()
, transfers the NFT from the renter's Safe back to the lender and transfers the payment to the renter.To transfer the NFT from the Safe,
_reclaimRentedItems()
is used, which makes the Safe contract execute a delegatecall toStop.reclaimRentalOrder()
, which is inherited fromReclaimer.sol
. This function usesERC721.safeTransferFrom()
orERC1155.safeTransferFrom()
to transfer the the NFT.If the recipient of the NFT (the lender's wallet) is a smart contract, the
safeTransferFrom()
functions will call theonERC721Received()
oronERC1155BatchReceived()
callback on the lender's wallet. If those functions don't return the corresponding magic bytes4 value or revert, the transfer will revert. In this case stopping the rental will fail, the NFT will still be in the renter's wallet and the payment will stay in the payment escrow contract.Impact
A malicious lender can use this vulnerability to grief a PAY order renter of their payment by having the
onERC721Received()
oronERC1155BatchReceived()
callback function revert or not return the magic bytes4 value. They will need to give up the lent out NFT in return which will be stuck in the renter's Safe (and usable for the renter within the limitations of the rental Safe).However, the lender has the ability to release the NFT and payment anytime by making the callback function revert conditional on some parameter that they can set in their contract. This allows them to hold the renter's payment for ransom and making the release conditional on e.g. a payment from the renter to the lender. The lender has no risk here, as they can release their NFT at any time.
Proof of Concept
Add the following code to
StopRent.t.sol
:Add the following test to
StopRent.t.sol
:Now the PoC can be run with:
Recommended Mitigation Steps
I see three ways to mitigate this (however, the third one is incomplete):
Stop._reclaimRentedItems()
so that it doesn't revert when the transfer is unsuccessful.ERC721.transferFrom()
instead ofERC721.safeTransferFrom()
to transfer the NFT back to the lender. I believe it is reasonable to assume that the wallet that was suitable to hold a ERC721 before the rental is still suitable to hold a ERC721 after the rental and theonERC721Received
check is not necessary in this case. For ERC1155 this mitigation cannot be used because ERC1155 only has asafeTransferFrom()
function that always does the receive check. So this mitigation is incomplete.Assessed type
Token-Transfer