Gas effective deployment method secure?

I'm currently working on a dex project that allows users to create contracts for the trading pairs and wanted to reduce the cost of deployment. Came up with the solution below, a very small proxy (51 bytes, 64 with constructor).

The function buildSlimProxyBytecode build the proxy contract bytecode, the function buildSlimProxyConstructor concatenates the bytecode to a constructor and deploySlimProxy deploys it, returning the address of the new contract. This method requires the contract to be initialized with an initialize method instead of a constructor.

Any comments on this method would be appreciated, security related or not.

pragma solidity ^0.8.0;


contract SlimProxyDeployer {
    function buildSlimProxyBytecode(address impl) internal pure returns (bytes memory) {
        // calldatacopy(0, 0, calldatasize())
        // 3660008037

        // 0x36 CALLDATASIZE
        // 0x60 PUSH1 0x00
        // 0x80 DUP1
        // 0x37 CALLDATACOPY


        // let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
        // 600080368173xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx5af4

        // 0x60 PUSH1 0x00
        // 0x80 DUP1
        // 0x36 CALLDATASIZE
        // 0x81 DUP2
        // 0x73 PUSH20 <concat-address-here>
        // 0x5A GAS
        // 0xF4 DELEGATECALL


        // returndatacopy(0, 0, returndatasize())
        // 3d6000803e

        // 0x3D RETURNDATASIZE
        // 0x60 PUSH1 0x00
        // 0x80 DUP1
        // 0x3E RETURNDATACOPY


        // switch result
        // case 0 { revert(0, returndatasize()) }
        // case 1 { return(0, returndatasize()) }
        // 60003d91600114603157fd5bf3

        // 0x60 PUSH1 0x00
        // 0x3D RETURNDATASIZE
        // 0x91 SWAP2
        // 0x60 PUSH1 0x01
        // 0x14 EQ
        // 0x60 PUSH1 0x31
        // 0x57 JUMPI
        // 0xFD REVERT
        // 0x5B JUMPEST
        // 0xF3 RETURN

        return bytes.concat(
            bytes(hex"3660008037600080368173"),
            bytes20(impl),
            bytes(hex"5af43d6000803e60003d91600114603157fd5bf3")
        );
    }

    function buildSlimProxyConstructor(address impl) internal pure returns (bytes memory) {
        // codecopy(0, ofs, codesize() - ofs)
        // return(0, codesize() - ofs)

        // 0x60 PUSH1 0x0D
        // 0x80 DUP1
        // 0x38 CODESIZE
        // 0x03 SUB
        // 0x80 DUP1
        // 0x91 SWAP2
        // 0x60 PUSH1 0x00
        // 0x39 CODECOPY
        // 0x60 PUSH1 0x00
        // 0xF3 RETURN
        // <concat-contract-code-here>

        // 0x600D80380380916000396000F3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        return bytes.concat(
            hex"600D80380380916000396000F3",
            buildSlimProxyBytecode(impl)
        );
    }

    function deploySlimProxy(address impl) internal returns (address deploymentAddr) {
        bytes memory code = buildSlimProxyConstructor(impl);
        assembly { deploymentAddr := create(callvalue(), add(code, 0x20), mload(code)) }
        require(deploymentAddr != address(0), "deployment failed");
    }
}

interface IDeployment {
    function initialize() external;
}

contract ExampleFactory is SlimProxyDeployer {
    address[] public deployments;

    function deploy(address _impl) external {
        address a = deploySlimProxy(_impl);
        deployments.push(a);
        IDeployment(a).initialize();
    }
}