Submitted by MiloTruck, also found by Robert (1, 2, 3) and 0xDING99YA
In WildcatMarketControllerFactory.sol, registered borrowers can call deployController() to deploy a WildcatMarketController contract for themselves.
The function checks if the codehash of the controller address is bytes32(0) to determine if the controller has already been deployed:
WildcatMarketControllerFactory.sol#L287-L296
This same check is also used in deployMarket(), which is called by borrowers to deploy markets:
WildcatMarketController.sol#L349-L353
This check also exists in createEscrow(), which is called by markets to deploy an escrow contract whenever a sanctioned lender gets blocked:
WildcatSanctionsSentinel.sol#L104-L106
However, this <address>.codehash != bytes32(0) check is insufficient to determine if an address has existing code. According to EIP-1052, addresses without code only return a 0x0 codehash when they are empty:
As seen from above, addresses without code can also return keccak256("") as its codehash if it is non-empty. EIP-161 states that an address must have a zero ETH balance for it to be empty:
As such, if anyone transfers 1 wei to an address, .codehash will return keccak256("") instead of bytes32(0), making the checks shown above pass incorrectly.
Since all contract deployments in the protocol use CREATE2, a malicious attacker can harm users by doing the following:
Note that for controller deployments, since the salt is fixed to the borrower address and cannot be varied, the DOS for deployController() is permanent. This effectively locks the borrower out of all protocol functionality forever since they can never deploy a market controller for themselves.
An attacker can do the following at the cost of 1 wei and some gas:
The code below contains three tests:
Consider checking if the codehash of an address is not keccak256("") as well:
WildcatMarketControllerFactory.sol#L294-L296
WildcatMarketController.sol#L351-L353
WildcatSanctionsSentinel.sol#L106
Alternatively, use <address>.code.length != 0 to check if an address has code instead.
Invalid Validation
laurenceday (Wildcat) commented:
laurenceday (Wildcat) confirmed
