one of the points of the article is wrong, fp isn't stateless at all it just tends to represent state in a different way - look at monads in haskell.
You will know if there's state in a language if you can build a function that returns different results given the same values over time; IORef does not allow you to do that.
As to your broader claim here, I while I understand what you're getting at (and probably wouldn't have bothered responding, but for the above) I think it's most precise to say that IORef is an encoding of state. This does not have to mean that state gets updated by means of side effects.