Closed c4-bot-6 closed 10 months ago
141345 marked the issue as primary issue
141345 marked the issue as sufficient quality report
Alec1017 (sponsor) acknowledged
Without more proof, this is QA. The potential is clearly shown by the warden but for this to be M the issue would need to show a specific scenario that exceeds the gas limit and is within reasonable usage of the protocol.
0xean marked issue #538 as primary and marked this issue as a duplicate of 538
0xean marked the issue as partial-25
0xean marked the issue as satisfactory
Lines of code
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L205 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L227-L233 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L210-L212 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L300 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L222 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L257-L264 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L271-L277 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L231 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L174-L178
Vulnerability details
Once a user executes the
Stop::stopRent()
(orStop::stopRentBatch()
) to stop a rental order. The function must process a handful of gas-exceeding significant-risk tasks.In the worst-case scenario, the rental stop transaction will be reverted if the function consumes gas beyond the block gas limit. Consequently, all ERC-721/ERC-1155 rented items and ERC-20 payments will be frozen permanently.
Proof of Concept
The following highlights a list of gas-exceeding significant-risk tasks of the
stopRent()
:rentalAssetUpdates
array from all ERC-721/ERC-1155 rented items.onStop()
of allHook
contracts.Gnosis Safe
contract to a lender.PaymentEscrow
contract to all respective recipients.Storage
contract.This report will analyze only the most significant risk tasks, including the processing of the
onStop()
of allHook
contracts (Task 2 above) and settling and transferring all ERC-20 payments from the protocol'sPaymentEscrow
contract to all respective recipients (Task 4). Furthermore, the gas risks when deploying the protocol to multiple chains are also analyzed in this report.The remaining of this section will be categorized into three sub-sections as follows.
onStop()
Gas Exceeding Significant Risk #1 -- Processing Hooks'
onStop()
The
Stop::_removeHooks()
is responsible for processing and triggering allHook
contracts attached to the rental order. Therefore, the moreHooks
to be processed, the more gas is required.For each
Hook
contract, the_removeHooks()
will trigger theonStop()
to process the rental stop event. Even though theonStart()
of eachHook
in question would have successfully been executed on the rental start transaction, that cannot guarantee that the rental stop transaction will succeed because the stop transaction will call another callback function:onStop()
(not theonStart()
).Specifically, the
onStop()
can consume more gas than theonStart()
as the function can route the execution control flow to different logic branches.If the
Hooks
consume gas beyond the block gas limit, the rental order will be permanently DoS'ed. The protocol admin cannot disable someHooks
to remedy the DoS issue because the stop transaction will be reverted when the_removeHooks()
executes theStorage::hookOnStop()
to check for disabledHooks
.Furthermore, we cannot remove some
Hooks
from the rental order payload because the resultingrentalOrderHash
derived from theStop::_deriveRentalOrderHash()
will be changed. Subsequently, theStorage::removeRentals()
will revert the stop transaction, as therentalOrderHash
has changed.@1 -- Loop to trigger every attached hook (the more hooks to be processed, the more gas is required)
: https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L205@2 -- The hook's onStop() can consume more gas than the onStart(). This poses a significant risk to the issue: "gas consumption beyond the block gas limit"
: https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L227-L233Gas Exceeding Significant Risk #2 -- Processing Payment Settlements
The
PaymentEscrow::_settlePayment()
is responsible for processing and transferring all ERC-20 payments from the protocol'sPaymentEscrow
contract to all respective recipients.The settlement can be categorized into two scenarios.
Token transfers are external calls that can consume a considerable amount of gas. Hence, the more ERC-20 items to be transferred, the more gas is required. Moreover, in the case of a pro-rata split payment, the gas cost required for each settlement will be doubled since the token must be transferred to both lender and renter.
If the payment settlements consume gas beyond the block gas limit, the rental order will be permanently DoS'ed.
We cannot remove some items from the rental order payload because the resulting
rentalOrderHash
derived from theStop::_deriveRentalOrderHash()
will be changed. Subsequently, theStorage::removeRentals()
will revert the stop transaction, as therentalOrderHash
has changed.@3 -- Loop to process every ERC-20 item (the more items to be processed, the more gas is required)
: https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L231@4 -- In the case of a pro-rata split payment, 2x gas cost is required for each payment settlement (transfer token to both lender and renter)
: https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L257-L264@5 -- In the case of a full-amount payment, 1x gas cost is required for each payment settlement (transfer token to one recipient)
: https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L271-L277Gas Exceeding Significant Risk #3 -- Multi-Chain Protocol Deployment
The
reNFT
protocol is planned to be deployed on multiple chains. Each chain can have a different block gas limit and gas calculation scheme. Some chains have a lower block gas limit than others.Therefore, rental orders containing certain
Hooks
andrental items
successfully executed on one chain cannot guarantee that they will work on other chains.Tools Used
Manual Review
Recommended Mitigation Steps
To mitigate the DoS issue, limit each rental order's number of
Hooks
andrental items
(ERC-721, ERC-1155, and ERC-20 items). Also, the protocol's contracts should be performed intensively for gas testing when deploying to a new chain.Assessed type
DoS