library LibBootstrap {

    /// @dev Magic bytes returned by the bootstrapper to indicate success.
    ///      This is `keccack('BOOTSTRAP_SUCCESS')`.
    bytes4 internal constant BOOTSTRAP_SUCCESS = 0xd150751b;

    using LibRichErrorsV06 for bytes;

    /// @dev Perform a delegatecall and ensure it returns the magic bytes.
    /// @param target The call target.
    /// @param data The call data.
    function delegatecallBootstrapFunction(
        address target,
        bytes memory data
    )
        internal
    {
        (bool success, bytes memory resultData) = target.delegatecall(data);
        if (!success ||
            resultData.length != 32 ||
            abi.decode(resultData, (bytes4)) != BOOTSTRAP_SUCCESS)
        {
            LibProxyRichErrors.BootstrapCallFailedError(target, resultData).rrevert();
        }
    }
}
function delegatecallBootstrapFunction(
    address target,
    bytes memory data
)
    internal
{
    (bool success, bytes memory resultData) = target.delegatecall(data);
    if (!success ||
        resultData.length != 32 ||
        abi.decode(resultData, (bytes4)) != BOOTSTRAP_SUCCESS)
    {
        LibProxyRichErrors.BootstrapCallFailedError(target, resultData).rrevert();
    }
}

/// @dev Perform a delegatecall and ensure it returns the magic bytes.
/// @param target The call target.
/// @param data The call data.