Owner of PrivatePool can steal any NFTs and tokens that the pool has approval for #63
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-184
high quality report
This report is of especially high quality
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2023-04-caviar/blob/cd8a92667bcb6657f70657183769c244d04c015c/src/PrivatePool.sol#L459-L476
Vulnerability details
Impact
The owner of a PrivatePool, i.e. anyone who has the ownership NFT of the pool, can call the
transferFrom
orsafeTransferFrom
method of any token / NFT through the execute method of thePrivatePool
contract.In case a user has given approval (for tokens / NFTs) to the PrivatePool, which is always necessary when interacting directly with the contract's
buy
,sell
orchange
methods, the pool owner can steal those tokens / NFTs or even front-run the aforementioned methods via the execute method.Risks
setApprovalForAll
(puts NFTs at risk that the user doesn't even intend to sell).withdraw
method.execute
are usually protected by a time-lock or multisig wallet.)EthRouter
contract since no direct user approvals are given to the pool. However, the user is not forced to use the router.Severity
The stated risks are my justification to classify this as
High Risk
finding although the execute method has restricted access.Proof of Concept
The following PoC will steal an NFT from a user that has given approval to the PrivatePool. Furthermore, the malicious pool owner will front-run the user's call to the
sell
method in order to make it fail, i.e. additional gas loss for the user.Just add this test case to
test/PrivatePool/Sell.t.sol
and run it:Log:
Tools Used
VS Code, Foundry
Recommended Mitigation Steps
Introduce a whitelist (provided by the
Factory
contract) to restrict which function selectors are allowed to be called fromexecute
.If this is not suitable for you, I suggest a blacklist instead and add the function selectors of
transferFrom
,safeTransferFrom
,approve
andsetApprovalForAll
(according to ERC20 and ERC721 interfaces) per default.The text was updated successfully, but these errors were encountered: