delegatecall关键字在代理合约中的妙用
就感觉很很神奇~
逻辑合约
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| contract Logic { address owner; uint public a = 8; constructor() { owner = msg.sender; }
// 0x069265cd function increate() external { require(owner == address(0), "owner != address(0)"); a++; }
function calSelector() external returns (bytes4 selector, bytes memory data) { selector = Logic.increate.selector; data = abi.encodeWithSignature("getOwner()"); }
// 0x893d20e8 function getOwner() external returns(address) { a = 100; return owner; } }
|
在 Logic 中如果你想调用 increate
函数,显示是不可能的,该断言限制了该合约自己调用该方法。但是如果通过 delegatecall
来调用就不一样了,代理合约可以自己设置一个同名的变量,并令其等于 address(0)
。这样一来逻辑合约就可以调用此函数了。
代理合约
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| contract Proxy {
address public owner; uint public a; Logic logic;
constructor(address _logic) { logic = Logic(_logic); }
function delegatecall(bytes memory data) public returns (bool, bytes memory ) { (bool success, bytes memory _data) = address(logic).delegatecall(data); return (success, _data); }
function increate() external { a = 222; } }
|
运行结果

可以看到我们成功调用了increate
函数。
此收获来自 damn defi backdoor。