Platform: Code4rena
Start Date: 08/01/2024
Pot Size: $83,600 USDC
Total HM: 23
Participants: 116
Period: 10 days
Judge: 0xean
Total Solo HM: 1
Id: 317
League: ETH
Rank: 101/116
Findings: 1
Award: $4.78
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: AkshaySrivastav
Also found by: 0xA5DF, 0xAlix2, 0xDING99YA, 0xdice91, BARW, BI_security, EV_om, J4X, Jorgect, SBSecurity, ZdravkoHr, evmboi32, hals, haxatron, imare, juancito, kaden, marqymarq10, oakcobalt, rbserver, rokinot, rvierdiiev, said, serial-coder, trachev
4.7844 USDC - $4.78
Hooks represent added functionalities or restriction and are applied to the rented token inside the wallet.
When a lender places a order and decides to use hooks. This hooks have three main callbacks one of them is Hook#onStop
. If this callback fails the rented items are blocked inside the wallet. And event the GUARD_ADMIN
cannot unstuck it.
Rented items can become stuck inside the lender wallet if a hook fails on the onStop
call.
For a successfully created lend order the Hook#onStart
is used without revert:
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Create.sol#L606-L612 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Create.sol#L496-L503
The lender can also interact with a hook trough the Hook#onTransaction
when making transaction trough the assigned lender wallet.
But
when a lender or renter tries to stop the renting he/she calls the stop
policy method stopRent
and the hook is again called trough Hook#onStop
If this call fails it reverts and becouse the hooks are hashed with the lender order they cannot be removed in the order parameter when calling stopRent
.
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L300 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L176-L179
If the revert on Hook#onStop
happens the rented items become stuck inside the lender wallet.
Even the "GUARD_ADMIN" account which has some control over hooks has no available method to change the end address of the failing hook.
All of the above stands also when doing orders in batch mode.
Manual review
Implement hooks address that are always only proxies so the implementation can be changed by a permissioned account or
When a hook fails in Hook#onStop
implement a option for the lender to retrieve/settle the lent items.
Something like :
+ bytes32 hashedItem = _hashItem(item); try IHook(target).onStop( rentalWallet, item.token, item.identifier, item.amount, hooks[i].extraData ) {} catch Error(string memory revertReason) { + hookOnStopFailed[rentalWallet][hashedItem] = true; // Revert with reason given. revert Errors.Shared_HookFailString(revertReason); } catch Panic(uint256 errorCode) { // Convert solidity panic code to string. string memory stringErrorCode = LibString.toString(errorCode); + hookOnStopFailed[rentalWallet][hashedItem] = true; // Revert with panic code. revert Errors.Shared_HookFailString( string.concat("Hook reverted: Panic code ", stringErrorCode) ); } catch (bytes memory revertData) { + hookOnStopFailed[rentalWallet][hashedItem] = true; // Fallback to an error that returns the byte data. revert Errors.Shared_HookFailBytes(revertData); } }
If hookOnStopFailed[rentalWallet][hashedItem]
becomes true give some other option to retrieve/settle the lent items.
Other
#0 - c4-pre-sort
2024-01-21T19:05:55Z
141345 marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-01-23T13:37:43Z
141345 marked the issue as duplicate of #501
#2 - c4-judge
2024-01-28T19:35:08Z
0xean marked the issue as satisfactory