DSProxy 2.0
New primitive Wand
aka DSProxy 2.0
A Wand
is a variation of the Proxy pattern with some differences and extra features
canCast
authorizationDSAuth
to access control the proxy object itself,root
(owner) retains sole access to true "root" functions (transfer and update authority),cast
applies the canCast
access control table to the spell being cast. Concretely:canCall(address caller, address object, bytes4 sig) -> (bool)
which was used like
function exec(address target, bytes calldata data) returns (bytes ret) {
assert authority.canCall(msg.sender, address(this), msg.sig)`
...
}
becomes
`canCast(address caller, address spell, bytes4 sig)`
which is called like
function cast(address spell, bytes calldata data) returns (bool ok, bytes ret) {
assert auth.canCast(msg.sender, spell, data[0:4]);
...
}
root
and auth
root
) and permission table (auth
) makes spellsaddress root_ = root;
address auth_ = auth;
// this is in a fresh context, the local execution stack is not visible
(bit, ret) = spell.delegatecall(data);
require(auth == auth_, 'ERR_SUDO');
require(root == root_, 'ERR_SUDO')
(The remaining loss of root control danger lies in SELFDESTRUCT
,
which is easier to statically detect
(mitigated in future by
https://eips.ethereum.org/EIPS/eip-2937,
or any way to detect that code has been scheduled for selfdestruct)
lock
and caller referencelock = msg.sender;
...
lock = ZERO;
code
referencecast
) is also savedcode = spell;
...
code = ZERO;