Hi everyone. A question about Proxy contracts.
I have a contract A that makes calls to contract B, and B accepts only calls from A.
Now i want to add a proxy contract to A in order to make it upgradeable. All user transactions will be made to Proxy-A and delegated to Logic-A.
The address in msg.sender when contract B is reached, will be Proxy-A or Logic-A?
2 Likes
Hey @AlexanderPoschenried! Good question
So, most proxy contract tend to use delegateCall
meaning the msg.sender
is maintained thoughout the transasction. So if I have a proxy to a contract, through using delegateCall
the msg.sender
stays as the original sender, not the proxy. This still works if its a proxy => proxy => logic.
Does that answer your question?
2 Likes
Thanks. But in my case the way is Proxy (A) => Logic (A) => Logic (B).
Logic(A) calls Logic (B) through a normal call, not a delegate call.
So i assume there the msg.sender changes from Proxy A address to Logic A address. Right?
Oh, my bad.
Yes, if delegateCall is not used then msg.sender changes to the actual contract that called it.
Hey @AlexanderPoschenried! If I understand correctly, then contract B will see ProxyA as msg.sender
when it receives the call. Let's say you have the following scenario:
contract A {
B b;
function callB() public {
b.run();
}
}
contract B {
event Called(address caller);
function run() {
emit Called(msg.sender);
}
}
Let's say you deploy logic contracts A and B, and set up a proxy for A (called ProxyA, as you say). Then, when you call ProxyA.callB()
, the event emitted in that transaction will be Called(ProxyA)
.
This is because delegatecall
preserves the entire context except for the code, so any calls made from LogicA, if they were originated from ProxyA, will actually be advertised as having ProxyA for msg.sender.
Let me know if this is clear!
1 Like
@spalladino very clear, that example was very usefull.
Thanks both of you.
2 Likes