msg.sender Explained in Detail
msg.sender is the direct caller of the current function. If a wallet calls a contract directly, msg.sender is the wallet. If a router calls the contract, msg.sender is the router.
This makes msg.sender the normal starting point for access control, but it is not always the human user behind the transaction. Contracts can call contracts, proxies can delegate execution, and relayers can submit actions on behalf of users.
Smart contract example
The check below only allows the immediate caller to withdraw:
function withdraw() external {
require(msg.sender == owner, "not owner");
payable(owner).transfer(address(this).balance);
}
That is safer than tx.origin authorization, but it still needs context. If owner is expected to be a multisig, proxy admin, or trusted forwarder, the caller path must match that design.
msg.sender in Auditing
Auditors trace every route that can set msg.sender for privileged code: direct calls, routers, callbacks, proxies, relayers, and smart wallets.
msg.sender also behaves differently around delegatecall. A delegated implementation executes in the proxy's storage context while preserving the caller seen by the proxy, so authorization must be reviewed against the full proxy call path.
Red flags in code
-
Authorization that assumes
msg.senderis always an externally owned account. -
Privileged functions callable through routers, callbacks, or relayers without explicit trust checks.
-
msg.senderchecks inside proxy implementations that were not reviewed with the proxy call path. -
Meta-transaction code that uses
msg.senderinstead of the recovered or forwarded user. -
Comments that treat
msg.senderand tx.origin as interchangeable.
How to test or review it
-
Trace every caller that can reach privileged functions.
-
Test direct wallet calls, contract-mediated calls, and proxy calls separately.
-
Confirm whether smart wallets, routers, and relayers should be supported.
-
Review
delegatecallpaths before trustingmsg.senderchecks in implementation code. -
When
msg.senderis only a transport address, require a trusted forwarder, recovered signer, or explicit role holder instead of treating the caller as the user.