The service account needs permissions to pull messages from Pub/Sub (roles/pubsub.subscriber), write to Cloud Storage (roles/storage.objectCreator), and be able to invoke the function (roles/cloudfunctions.invoker) if the function is triggered via HTTP; however, for event-driven functions, the trigger is Pub/Sub, so the invoker role might not be needed. But to be safe, the invoker role allows the function to be called. The correct three are the essential ones: Pub/Sub subscriber, Cloud Storage object creator, and Cloud Functions invoker (for the function to be invoked by the event).
Actually, for event-driven functions, the Pub/Sub subscription can push to the function without the invoker role if the function's auth is set to allow unauthenticated invocations, but best practice is to use a service account. However, the invoker role is often required when the function uses a service account for authentication. The typical least privilege roles are: roles/pubsub.subscriber (to acknowledge messages), roles/storage.objectCreator (to write objects), and roles/cloudfunctions.invoker (to allow the Pub/Sub push to invoke the function).
Alternatively, roles/iam.serviceAccountUser might be needed to attach the service account. But based on common exam questions, the three are: pubsub.subscriber, storage.objectCreator, cloudfunctions.invoker.