```\n    function createOrder(\n    DataStore dataStore,\n    EventEmitter eventEmitter,\n    OrderVault orderVault,\n    IReferralStorage referralStorage,\n    address account,\n    BaseOrderUtils.CreateOrderParams memory params\n    ) external returns (bytes32) {\n    ReferralUtils.setTraderReferralCode(referralStorage, account, params.referralCode);\n\n    uint256 initialCollateralDeltaAmount;\n\n    address wnt = TokenUtils.wnt(dataStore);\n\n    bool shouldRecordSeparateExecutionFeeTransfer = true;\n\n    if (\n        params.orderType == Order.OrderType.MarketSwap ||\n        params.orderType == Order.OrderType.LimitSwap ||\n        params.orderType == Order.OrderType.MarketIncrease ||\n        params.orderType == Order.OrderType.LimitIncrease\n    ) {\n        initialCollateralDeltaAmount = orderVault.recordTransferIn(params.addresses.initialCollateralToken);\n        if (params.addresses.initialCollateralToken == wnt) {\n            if (initialCollateralDeltaAmount < params.numbers.executionFee) {\n                revert InsufficientWntAmountForExecutionFee(initialCollateralDeltaAmount, params.numbers.executionFee);\n            }\n            initialCollateralDeltaAmount -= params.numbers.executionFee;\n            shouldRecordSeparateExecutionFeeTransfer = false;\n        }\n    } else if (\n        params.orderType == Order.OrderType.MarketDecrease ||\n        params.orderType == Order.OrderType.LimitDecrease ||\n        params.orderType == Order.OrderType.StopLossDecrease\n    ) {\n        initialCollateralDeltaAmount = params.numbers.initialCollateralDeltaAmount;\n    } else {\n        revert OrderTypeCannotBeCreated(params.orderType);\n    }\n\n    if (shouldRecordSeparateExecutionFeeTransfer) {\n        uint256 wntAmount = orderVault.recordTransferIn(wnt);\n        if (wntAmount < params.numbers.executionFee) {\n            revert InsufficientWntAmountForExecutionFee(wntAmount, params.numbers.executionFee);\n        }\n\n        GasUtils.handleExcessExecutionFee(\n            dataStore,\n            orderVault,\n            wntAmount,\n            params.numbers.executionFee\n        );\n    }\n\n    // validate swap path markets\n    MarketUtils.getEnabledMarkets(\n        dataStore,\n        params.addresses.swapPath\n    );\n\n    Order.Props memory order;\n\n    order.setAccount(account);\n    order.setReceiver(params.addresses.receiver);\n    order.setCallbackContract(params.addresses.callbackContract);\n    order.setMarket(params.addresses.market);\n    order.setInitialCollateralToken(params.addresses.initialCollateralToken);\n    order.setSwapPath(params.addresses.swapPath);\n    order.setOrderType(params.orderType);\n    order.setDecreasePositionSwapType(params.decreasePositionSwapType);\n    order.setSizeDeltaUsd(params.numbers.sizeDeltaUsd);\n    order.setInitialCollateralDeltaAmount(initialCollateralDeltaAmount);\n    order.setTriggerPrice(params.numbers.triggerPrice);\n    order.setAcceptablePrice(params.numbers.acceptablePrice);\n    order.setExecutionFee(params.numbers.executionFee);\n    order.setCallbackGasLimit(params.numbers.callbackGasLimit);\n    order.setMinOutputAmount(params.numbers.minOutputAmount);\n    order.setIsLong(params.isLong);\n    order.setShouldUnwrapNativeToken(params.shouldUnwrapNativeToken);\n\n    ReceiverUtils.validateReceiver(order.receiver());\n\n    if (order.initialCollateralDeltaAmount() == 0 && order.sizeDeltaUsd() == 0) {\n        revert BaseOrderUtils.EmptyOrder();\n    }\n\n    CallbackUtils.validateCallbackGasLimit(dataStore, order.callbackGasLimit());\n\n    uint256 estimatedGasLimit = GasUtils.estimateExecuteOrderGasLimit(dataStore, order);\n    GasUtils.validateExecutionFee(dataStore, estimatedGasLimit, order.executionFee());\n\n    bytes32 key = NonceUtils.getNextKey(dataStore);\n\n    order.touch();\n    OrderStoreUtils.set(dataStore, key, order);\n\n    OrderEventUtils.emitOrderCreated(eventEmitter, key, order);\n\n    return key;\n}\n```\n