Operator-gated forwarder that checks the transaction origin against an exchange operator list before passing the call through to a target contract.
Historical Significance
The tx.origin check dates this contract. It was a common way to let an operator drive a wallet through arbitrary intermediate contracts, and it was already being argued against by the time this was deployed because it treats any contract the operator touches as trusted. The contract is also a study in how little a forwarder needs: no selectors, no events, no owner, just a registry lookup and a call.
Key Facts
Description
A fallback-only contract with no function dispatcher at all. Every call reads the operator registry held in its first storage slot, asks it whether the transaction origin is a registered operator, and reverts if not. It then loads the forwarding target from the second slot, copies the incoming calldata into memory, and issues a plain call with the free memory pointer as the return buffer. The result is returned or reverted verbatim.
Because the authorisation is on tx.origin rather than msg.sender, the check follows the human who signed the transaction rather than whatever contract happens to sit in between.
Source Verified
Byzantium Era
First Metropolis hard fork. Added zk-SNARK precompiles, REVERT opcode, and staticcall.
Bytecode Overview
Verified Source Available
This contract has verified source code.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
pragma solidity ^0.4.18;
contract Exchange {
function operators(address _operator) public view returns (bool);
}
contract Wallet {
Exchange exchange;
address target;
function () public {
address t;
bytes memory data;
require(exchange.operators(tx.origin));
t = target;
data = msg.data;
assembly {
let ptr := mload(0x40)
let result := call(gas, t, 0, add(data, 0x20), mload(data), ptr, 0)
let size := returndatasize
returndatacopy(ptr, 0, size)
switch result
case 0 { revert(ptr, size) }
default { return(ptr, size) }
}
}
}