Platform: Code4rena
Start Date: 16/10/2023
Pot Size: $60,500 USDC
Total HM: 16
Participants: 131
Period: 10 days
Judge: 0xTheC0der
Total Solo HM: 3
Id: 296
League: ETH
Rank: 5/131
Findings: 2
Award: $866.18
š Selected for report: 0
š Solo Findings: 0
š Selected for report: MiloTruck
Also found by: 0xDING99YA, Robert
647.6492 USDC - $647.65
Any escrow contract can be DoSed by sending a 1 wei transaction to the escrow address that will be created for a user.
When an account has no code and has never been interacted with, the codehash will be bytes32(0).
This will result in escrow creation succeeding at this line https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatSanctionsSentinel.sol#L106
However, when an account has had a transaction sent to it, the codehash changes to keccak256(āā) (c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470). The require statement then fails because codehash does not equal bytes32(0) and creation will be reverted despite no code being at that address.
This is a high impact because you can stop any escrow contracts from ever being created.
contract CodehashTest {
function notZeroCodeHash() external payable returns(bytes32 firstCodeHash, bytes32 secondCodeHash) { // Random address that has had 0 interactions firstCodeHash = address(0xc93356BdeAf3ceA6284A6Cc747fa52DD04AfB2A7).codehash; payable(0xc93356BdeAf3ceA6284A6Cc747fa52DD04AfB2A7).transfer(1); secondCodeHash = address(0xc93356BdeAf3ceA6284A6Cc747fa52DD04AfB2A7).codehash; }
}
Manual
Add && != bytes32(c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470)
to the require.
DoS
#0 - c4-pre-sort
2023-10-28T14:53:06Z
minhquanym marked the issue as duplicate of #531
#1 - c4-judge
2023-11-07T10:12:29Z
MarioPoneder marked the issue as duplicate of #491
#2 - c4-judge
2023-11-07T10:20:28Z
MarioPoneder marked the issue as partial-25
#3 - c4-judge
2023-11-07T10:20:33Z
MarioPoneder marked the issue as satisfactory
#4 - MarioPoneder
2023-11-07T10:20:40Z
found 1/3 instances, see primary
#5 - c4-judge
2023-11-07T10:21:43Z
MarioPoneder marked the issue as partial-25
š Selected for report: MiloTruck
Also found by: 0xDING99YA, Robert
647.6492 USDC - $647.65
Any controller contract can be DoSed by sending a 1 wei transaction to the controller address that will be created for a user.
When an account has no code and has never been interacted with, the codehash will be bytes32(0).
This will result in controller creation succeeding at this line https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatMarketControllerFactory.sol#L294
However, when an account has had a transaction sent to it, the codehash changes to keccak256(āā) (c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470). The require statement then fails because codehash does not equal bytes32(0) and creation will be reverted despite no code being at that address.
This is a high impact because you can stop any controller contracts from ever being created.
contract CodehashTest {
function notZeroCodeHash() external payable returns(bytes32 firstCodeHash, bytes32 secondCodeHash) { // Random address that has had 0 interactions firstCodeHash = address(0xc93356BdeAf3ceA6284A6Cc747fa52DD04AfB2A7).codehash; payable(0xc93356BdeAf3ceA6284A6Cc747fa52DD04AfB2A7).transfer(1); secondCodeHash = address(0xc93356BdeAf3ceA6284A6Cc747fa52DD04AfB2A7).codehash; }
}
Manual
Add && != bytes32(c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470)
to the require.
DoS
#0 - c4-pre-sort
2023-10-28T14:52:46Z
minhquanym marked the issue as duplicate of #531
#1 - c4-judge
2023-11-07T10:14:19Z
MarioPoneder marked the issue as duplicate of #491
#2 - c4-judge
2023-11-07T10:20:05Z
MarioPoneder marked the issue as partial-25
#3 - c4-judge
2023-11-07T10:20:11Z
MarioPoneder marked the issue as satisfactory
#4 - MarioPoneder
2023-11-07T10:20:14Z
found 1/3 instances, see primary
#5 - c4-judge
2023-11-07T10:21:39Z
MarioPoneder marked the issue as partial-25
š Selected for report: MiloTruck
Also found by: 0xDING99YA, Robert
647.6492 USDC - $647.65
Any market contract can be DoSed by sending a 1 wei transaction to the market address that will be created for a user.
When an account has no code and has never been interacted with, the codehash will be bytes32(0).
This will result in market creation succeeding at this line https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatMarketController.sol#L351
However, when an account has had a transaction sent to it, the codehash changes to keccak256(āā) (c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470). The require statement then fails because codehash does not equal bytes32(0) and creation will be reverted despite no code being at that address.
This is a high impact because you can stop any market contracts from ever being created.
contract CodehashTest {
function notZeroCodeHash() external payable returns(bytes32 firstCodeHash, bytes32 secondCodeHash) { // Random address that has had 0 interactions firstCodeHash = address(0xc93356BdeAf3ceA6284A6Cc747fa52DD04AfB2A7).codehash; payable(0xc93356BdeAf3ceA6284A6Cc747fa52DD04AfB2A7).transfer(1); secondCodeHash = address(0xc93356BdeAf3ceA6284A6Cc747fa52DD04AfB2A7).codehash; }
}
Manual
Add && != bytes32(c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470)
to the require.
DoS
#0 - c4-pre-sort
2023-10-28T14:52:25Z
minhquanym marked the issue as duplicate of #531
#1 - c4-judge
2023-11-07T10:14:20Z
MarioPoneder marked the issue as duplicate of #491
#2 - c4-judge
2023-11-07T10:18:34Z
MarioPoneder marked the issue as partial-25
#3 - c4-judge
2023-11-07T10:18:39Z
MarioPoneder marked the issue as satisfactory
#4 - MarioPoneder
2023-11-07T10:19:38Z
found 1/3 instances, see primary
#5 - c4-judge
2023-11-07T10:21:23Z
MarioPoneder marked the issue as partial-25
š Selected for report: MiloTruck
Also found by: 0xCiphky, LokiThe5th, Madalad, Robert, ZdravkoHr, nonseodion
218.5317 USDC - $218.53
Permanent DoS of creating a market if anything fails in the market constructor.
Within a create2 call, instead of failing when a revert occurs in the constructor being run, it just returns address(0).
If this occurs within a market that's being created the transaction will not revert in the controller and instead will register the address as a valid market, despite nothing having been created.
Once this is registered, it will block any future attempts at registration, so any more attempts at creating the market will fail despite it never having been created.
contract FactoryAssembly { event Deployed(address addr, uint salt);
// 1. Get bytecode of contract to be deployed // NOTE: _owner and _foo are arguments of the TestContract's constructor function getBytecode(address _owner, uint _foo) public pure returns (bytes memory) { bytes memory bytecode = type(TestContract).creationCode; return abi.encodePacked(bytecode, abi.encode(_owner, _foo)); } // 2. Compute the address of the contract to be deployed // NOTE: _salt is a random number used to create an address function getAddress( bytes memory bytecode, uint _salt ) public view returns (address) { bytes32 hash = keccak256( abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode)) ); // NOTE: cast last 20 bytes of hash to address return address(uint160(uint(hash))); } // 3. Deploy the contract // NOTE: // Check the event log Deployed which contains the address of the deployed TestContract. // The address in the log should equal the address computed from above. function deploy(bytes memory bytecode, uint _salt) public payable { address addr; /* NOTE: How to call create2 create2(v, p, n, s) create new contract with code at memory p to p + n and send v wei and return the new address where new address = first 20 bytes of keccak256(0xff + address(this) + s + keccak256(mem[pā¦(p+n))) s = big-endian 256-bit value */ assembly { addr := create2( callvalue(), // wei sent with current call // Actual code starts after skipping the first 32 bytes add(bytecode, 0x20), mload(bytecode), // Load the size of code contained in the first 32 bytes _salt // Salt from function arguments ) if iszero(extcodesize(addr)) { revert(0, 0) } } emit Deployed(addr, _salt); }
}
contract TestContract { address public owner; uint public foo;
constructor(address _owner, uint _foo) payable { owner = _owner; foo = _foo; revert(); } function getBalance() public view returns (uint) { return address(this).balance; }
}
TestContract in this PoC should revert the transaction when being created, but instead the transaction succeeds without TestContract having been created.
Manual
Add the same check that the normal create has: https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/libraries/LibStoredInitCode.sol#L35
DoS
#0 - c4-pre-sort
2023-10-27T04:44:53Z
minhquanym marked the issue as duplicate of #28
#1 - c4-judge
2023-11-07T15:00:47Z
MarioPoneder changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-11-07T15:00:56Z
MarioPoneder marked the issue as satisfactory