"My response is generally the same to all of them, the maintenance for two function is very small compared to a bad abstraction that can grown into a monster very quickly."
That's a little bit of a red flag. Bad abstractions shouldn't lead to monsters. This is more important than when to abstract! Bad abstractions are going to happen no matter what way you create them, but you should always have a design mindset that leads you to being able to back out of them and change your code. Two very simple design concepts (but often have very deep implications) help with that: composability and modularity. They should guide your refactoring a lot, not just that there is duplication, but if you do extract it, where to? and how will it compose with other things ? you do that well, often your abstractions are easier to change. (Do it badly and often you will see an explosion of types to allow composition that often then make your abstractions much harder to change)