function _nonSystemDeployOnAddress() should try another nonces when getNewAddressCreate() result is in kernel space otherwise some logics would be broken
Audit: 2023-03-zksync-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-03-zksync/blob/21d9a364a4a75adfa6f1e038232d8c0f39858a64/contracts/ContractDeployer.sol#L181-L193
https://github.com/code-423n4/2023-03-zksync/blob/21d9a364a4a75adfa6f1e038232d8c0f39858a64/contracts/ContractDeployer.sol#L110-L121
https://github.com/code-423n4/2023-03-zksync/blob/21d9a364a4a75adfa6f1e038232d8c0f39858a64/contracts/ContractDeployer.sol#L249-L267


# Vulnerability details

## Impact
Function `createAccount()` Deploys a contract account with similar address derivation rules to the EVM's `CREATE` opcode. the deployed contract address is calculated based on sender deployed nonce. code uses `_nonSystemDeployOnAddress()` to deploy the contract to new address but it won't allow deploying to the kernel space addresses. This can create an issue for factory contracts that deploys new contracts and the calculated address is in kernel space, then those contracts transaction would revert always and they can't create new contract as deployment nonce won't increase and the calculated address would always be in kernel space.

## Proof of Concept
This is `_nonSystemDeployOnAddress()` code:
```solidity
    function _nonSystemDeployOnAddress(
        bytes32 _bytecodeHash,
        address _newAddress,
        AccountAbstractionVersion _aaVersion,
        bytes calldata _input
    ) internal {
        require(_bytecodeHash != bytes32(0x0), "BytecodeHash can not be zero");
        require(uint160(_newAddress) > MAX_SYSTEM_CONTRACT_ADDRESS, "Can not deploy contracts in kernel space");

        // We do not allow deploying twice on the same address.
        require(
            ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))) == 0x0,
            "Code hash is non-zero"
        );
        // Do not allow deploying contracts to default accounts that have already executed transactions.
        require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) == 0x00, "Account is occupied");

        _performDeployOnAddress(_bytecodeHash, _newAddress, _aaVersion, _input);
    }
```
As you can see code checks that `uint160(_newAddress) > MAX_SYSTEM_CONTRACT_ADDRESS` and makes sure that the calculated address for deployed contract is not in kernel space. 
This is `createAccount()` code:
```solidity
    function createAccount(
        bytes32, // salt
        bytes32 _bytecodeHash,
        bytes calldata _input,
        AccountAbstractionVersion _aaVersion
    ) public payable override onlySystemCall returns (address) {
        uint256 senderNonce = NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender);
        address newAddress = getNewAddressCreate(msg.sender, senderNonce);

        _nonSystemDeployOnAddress(_bytecodeHash, newAddress, _aaVersion, _input);

        return newAddress;
    }
```
As you can see it uses `getNewAddressCreate(msg.sender, senderNonce)` to calculate address for deployed contract address and the calculated address only is based on the `msg.sender`