Augur's Delegator, which looks its implementation up by name in the Augur controller on every call.
Historical Significance
Augur put every deployed component behind one of these and addressed them by name rather than by address. A registry keyed on names meant the system could be reasoned about as a set of roles, and an upgrade meant pointing a name somewhere new. The early return on an unset key is the detail that shows this was expected to be deployed before it was configured.
Key Facts
Description
The contract stores a controller and a lookup key. Its fallback returns immediately if the key is unset, which is how a delegator that has not been wired up stays inert rather than delegating to the zero address. Otherwise it calls lookup on the controller with the stored key, delegatecalls whatever address comes back with the original calldata, and passes the return data through.
getController and setController come from Augur's Controlled base, with setController restricted to the current controller. controllerLookupName exposes the key, so anyone can see which Augur component a given delegator stands in for.
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.20;
contract IController {
function assertIsWhitelisted(address _target) public view returns(bool);
function lookup(bytes32 _key) public view returns(address);
function stopInEmergency() public view returns(bool);
function onlyInEmergency() public view returns(bool);
function getTimestamp() public view returns (uint256);
function emergencyStop() public returns (bool);
}
contract IControlled {
function getController() public view returns (IController);
function setController(IController _controller) public returns(bool);
}
contract Controlled is IControlled {
IController internal controller;
modifier onlyWhitelistedCallers {
require(controller.assertIsWhitelisted(msg.sender));
_;
}
modifier onlyCaller(bytes32 _key) {
require(msg.sender == controller.lookup(_key));
_;
}
modifier onlyControllerCaller {
require(IController(msg.sender) == controller);
_;
}
modifier onlyInGoodTimes {
require(controller.stopInEmergency());
_;
}
modifier onlyInBadTimes {
require(controller.onlyInEmergency());
_;
}
function Controlled() public {
controller = IController(msg.sender);
}
function getController() public view returns(IController) {
return controller;
}
function setController(IController _controller) public onlyControllerCaller returns(bool) {
controller = _controller;
return true;
}
}
contract DelegationTarget is Controlled {
bytes32 public controllerLookupName;
}
contract Delegator is DelegationTarget {
function Delegator(IController _controller, bytes32 _controllerLookupName) public {
controller = _controller;
controllerLookupName = _controllerLookupName;
}
function() external payable {
// Do nothing if we haven't properly set up the delegator to delegate calls
if (controllerLookupName == 0) {
return;
}
// Get the delegation target contract
address _target = controller.lookup(controllerLookupName);
assembly {
//0x40 is the address where the next free memory slot is stored in Solidity
let _calldataMemoryOffset := mload(0x40)
// new "memory end" including padding. The bitwise operations here ensure we get rounded up to the nearest 32 byte boundary
let _size := and(add(calldatasize, 0x1f), not(0x1f))
// Update the pointer at 0x40 to point at new free memory location so any theoretical allocation doesn't stomp our memory in this call
mstore(0x40, add(_calldataMemoryOffset, _size))
// Copy method signature and parameters of this call into memory
calldatacopy(_calldataMemoryOffset, 0x0, calldatasize)
// Call the actual method via delegation
let _retval := delegatecall(gas, _target, _calldataMemoryOffset, calldatasize, 0, 0)
switch _retval
case 0 {
// 0 == it threw, so we revert
revert(0,0)
} default {
// If the call succeeded return the return data from the delegate call
let _returndataMemoryOffset := mload(0x40)
// Update the pointer at 0x40 again to point at new free memory location so any theoretical allocation doesn't stomp our memory in this call
mstore(0x40, add(_returndataMemoryOffset, returndatasize))
returndatacopy(_returndataMemoryOffset, 0x0, returndatasize)
return(_returndataMemoryOffset, returndatasize)
}
}
}
}