Open code423n4 opened 1 year ago
HickupHH3 marked the issue as satisfactory
HickupHH3 marked the issue as primary issue
Agree with High severity. Solution is to move orderHash
to Listing struct so that active and proposed listings can have separate order hashes
mehtaculous marked the issue as sponsor confirmed
HickupHH3 marked the issue as selected for report
Lines of code
https://github.com/code-423n4/2022-12-tessera/blob/f37a11407da2af844bbfe868e1422e3665a5f8e4/src/seaport/modules/OptimisticListingSeaport.sol#L428
Vulnerability details
Description
_constructOrder is called in propose(), OptimisticListingSeaport.sol. It fills the order params stored in proposedListings[_vault].
Importantly, it updates the order hash associated with the vault:
vaultOrderHash[_vault] = _getOrderHash(orderParams, counter);
There is only one other use of
vaultOrderHash
, in _verifySale().This function gets order information from the order hash, and makes sure the order is completely fulfilled.
After NFT sell has completed, cash() is used to distribute income ETH:
As long as sale is not complete, cash() can't be called as highlighted. The issue is that
vaultOrderHash[_vault]
is not protected during the lifetime of an active proposal. If another proposal is proposed and then the sell using active proposal takes place, cash() will keep reverting. Funds are stuck in listing contract.We can try to be clever and call propose() again with the same parameters to create an identical orderID, which will make
vaultOrderHash[_vault]
fine again and allow cash() to go through. But order params contain block.timestamp which will certainly be different which will make the hash different.Impact
Funds are permanently stuck in OptimisticListingSeaport.sol contract if active proposal is executed after new proposal is pending.
Proof of Concept
Tools Used
Manual audit
Recommended Mitigation Steps
Keep the order hash in the Listing structure rather than a single one per vault.