tx.origin Explained in Detail
tx.origin returns the original wallet that started a transaction. msg.sender returns the immediate caller of the current function.
That difference matters when contracts call other contracts. A privileged wallet may start a transaction through a malicious contract, and the target contract may still see the privileged wallet as tx.origin.
Smart contract example
The check below is unsafe:
function withdrawAll() external {
require(tx.origin == owner, "not owner");
payable(msg.sender).transfer(address(this).balance);
}
If the owner calls a malicious contract, that contract can call withdrawAll(). The tx.origin check still passes because the original wallet is the owner.
tx.origin in Auditing
Using tx.origin for authorization can turn a normal wallet interaction into an access control bypass. It is especially risky around external calls, wallet flows, phishing, and meta-transaction assumptions.
Red flags in code
-
require(tx.origin == owner)or similar authorization checks. -
Privileged functions that compare
tx.originto an admin, multisig, or role holder. -
Security logic that assumes
tx.origin == msg.sender. -
Calls from routers, relayers, smart wallets, or account-abstraction flows.
-
Comments that describe
tx.originas the user or caller without explaining the trust boundary.
How to test or review it
-
Replace
tx.originauthorization withmsg.senderor explicit signature-based authorization. -
Build a malicious intermediary contract and call the target through it.
-
Check every privileged path for indirect calls through delegatecall, routers, or callbacks.
-
Review whether the flow should support smart contract wallets.
-
Treat any
tx.originauthorization as audit-critical until proven harmless.
Keep learning this topic
Access Control Vulnerability
An access control vulnerability lets an unauthorized caller perform privileged actions such as moving funds, changing roles, upgrading contracts, or changing protocol settings.
External Call
An external call is an interaction where one smart contract calls another address, creating a trust boundary and possible control-flow risk.
Delegatecall
Delegatecall executes code from another contract while reading and writing the caller's storage, preserving the original caller context.
Access Control Attacks
Access control attacks in Solidity: broken authorization patterns, privilege escalation paths, and secure role and ownership design.
Phishing Attacks
Phishing attacks targeting smart contract users and teams: common social-engineering vectors, wallet risks, and practical prevention controls.
Delegatecall & Call Injection Attacks
Delegatecall and call injection attacks in Solidity: storage collision exploits, proxy vulnerabilities like Parity, and secure upgrade patterns.
Smart Contract Audit Checklist
Use this SCH tool to turn the concept into practical audit work.
Practice this in real audit scenarios
Definitions help, but auditors need reps. SCH turns concepts like tx.origin into exploit labs, code review habits, and report-writing practice.
Start the free trial or see the full smart contract auditing course.