I cant imagine a case where an immutable variable, that is by design a part of the byte code would produce a security risk or any unwanted side affect. They are by default part of the implementation - byte code - and i cant think of a case other than the one where multiple proxies call the same implementation and somehow need different immutable variables.
I have seen some answers which state that the problem with immutables are they are initialized in the implementation contract constructor and constructors are not allowed in implementations. This makes sense because constructors operate on the implementation's storage and are basically invisible to any delegecall so they are useless for the proxy - hence the initializers. In the immutable case, I dont see the rational of dropping them on implementation contracts since they are meant to be the part of the bytecode and not the storage which fits the bill perfectly.
Can anyone be so kind to explain the rational behind this ? And show any example where it can be dangerous ? I am using immutables for basic numeric constants or contract addresses in my implementation and I would like to keep doing so if there is nothing terrible wrong with this.
Immutables are meant to be declared and then initialized in the constructor. if you are setting a value with the declaration it's a
constant, no point in making it
immutable. The only difference between both is the ability to defer initialization with immutables. You are probably getting an error because of this. As soon the immutable is found in the code, it assumes a constructor exists, instead of parsing for an initialization value.
It may end up looking the same at the bytecode level, but it doesn't look the same to the compiler. A large chunk of your code is compiler information.
I havent mentioned anything about getting an error. I am not even using the ugradable plugins for deploying. I am simply asking why initializing an immutable in the implementation constructor is not supported with open zeppelin tools since it has nothing to do with the storage hence has no effect on proxy & implementation storage segregation.
Let me rephrase: Implementation shouldnt have constructors because they have no effect on the proxy storage. That is fine and makes sense. On the other hand, immutables are not stored on storage and are a part of the implementation which is totally fine. So why not allow immutables on implementation constructor ?
An answer would be: Well, its more work for the plug in to differentiate between constructors with only immutable initialization (which is fine) and constructors with actual storage initialization (which is not fine) so plug in basically forbids all implementation constructors. I would be happy with this answer but i would rather have it confirmed
The answer is more or less the one you sketched. It's mentioned in the FAQ under Why can’t I use immutable variables?.
I would also add that the semantics of immutable variables in the context of proxies may be surprising to people without deep understanding of the proxy model, and since they usually require a constructor that also opens the door to more errors by including code in the constructor that should rather be in an initializer.