dispatch()
(0xe9c4a3ac
), and appends its view of msg.sender
:CALL
(not DELEGATECALL
).dispatch()
method, the Euler contract looks up its view of msg.sender
, which corresponds to the proxy address.trustedSenders
mapping, which must exist otherwise the call is reverted. It is determined to exist by having a non-zero entry in the moduleId
field (modules must have non-zero IDs).trustedSenders
is if the Euler contract itself creates it (using the _createProxy
function in contracts/Base.sol
).trustedSenders
will also contain an address for the module's implementation. If not (ie multi-proxy modules), then the module implementation must be looked up with an additional lookup in the moduleLookup
mapping. This is because during an upgrade, single-proxy modules just have to update this one spot, whereas multi-proxy modules would otherwise need to update every corresponding entry in trustedSenders
.msg.sender
who invoked a proxy. The length of the calldata is checked. It should be at least 4 + 4 + 20
bytes long, which corresponds to:dispatch()
selector.msg.sender
.dispatch()
selector, and then appends its view of msg.sender
(caller()
in assembly), which corresponds to the proxy's address. This results in the following:DELEGATECALL
, so the module implementation code is executing within the storage context of the main Euler contract.msg.sender
. Instead, they should use the unpackTrailingParamMsgSender()
helper in contracts/BaseModule.sol
which will retrieve the message sender from the trailing calldata.unpackTrailingParams()
that returns both trailing params. msg.sender
is still not allowed to be used for this, since modules can be invoked via a batch dispatch, instead of via the proxy.CALL
to the proxy address.log0
, log1
, etc, depending on the number of topics.