From reading the comments it seems that a lot of people don't realize what it means for an abstraction to be "leaky".
An abstraction is a simplification or reduction in the rules of an underlying system.
For an abstraction to be leaky simply means that there will be some cases where actions that, according to the abstraction, are equivalent (i.e. they should be exactly the same thing) but will behave differently. Because the abstraction defines them as equivalent but they aren't when actually used, they demonstrate that the abstraction is not "reality", but only a simplification of it.
If an abstraction were not leaky - if all actions that are equivalent according to the abstraction behaved identically - then it would be indistinguishable from the underlying system and thus considered to be equivalent to it (which by definition, is not abstract).
So all abstractions are leaky by definition, because if they aren't leaky then they include all rules of the underlying system, which makes them the same as the underlying system.
Another affect of this is that the more you reduce the "leakiness" of an abstraction, the closer and closer it reflects the underlying system, and thus the more complicated and less useful it becomes as an abstraction - since the purpose of an abstraction is to simplify the underlying system.
Personally, I feel that the ideal solution is to understand the underlying system, and to define multiple abstractions that each handle a subset of the underlying system, but that together have 99% coverage. This results in smaller abstractions that can remain relatively simple, and the remaining 1% can be handled by directly using the underlying system (which will be complicated and a pain in the butt, but still possible).