> For the complete documentation index, see [llms.txt](https://calnix.gitbook.io/eth-dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://calnix.gitbook.io/eth-dev/solidity-patterns/router-batch.md).

# Router // batch

### Msg.sender

**Pool**

```solidity
contract Pool {

    uint256 public num;
    address public msgSender;

    function setVars(uint256 _num, address onBehalfOf) public {
        num = _num;
        msgSender = onBehalfOf;
    }
}
```

* msgSender here will be empty `0x0`, on deployment

**Router**

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.22;

contract Router {

    Pool public pool;

    /// @dev Helper function to extract a useful revert message from a failed call.
    /// If the returned data is malformed or not correctly abi encoded then this call can fail itself.
    function getRevertMsg(bytes memory returnData) internal pure returns (string memory)
    {
        // If the _res length is less than 68, then the transaction failed silently (without a revert message)
        if (returnData.length < 68) return "Transaction reverted silently";

        assembly {
            // Slice the sighash.
            returnData := add(returnData, 0x04)
        }

        return abi.decode(returnData, (string)); // All that remains is the revert string
    }

    /// @dev Allows batched call to self (this contract).
    /// @param calls An array of inputs for each call.
    function batch(bytes[] memory calls) public payable returns(bytes[] memory results) {

        results = new bytes[](calls.length);

        for (uint256 i; i < calls.length; i++) {

            (bool success, bytes memory result) = address(this).delegatecall(calls[i]);
            if (!success) revert(getRevertMsg(result));
            results[i] = result;
        }
    }


    function test(uint _num, address onBehalfOf) public {

        bytes memory payload = abi.encodeWithSignature("setVars(uint256,address)", _num, onBehalfOf);
        
        bytes[] memory allCalls = new bytes[](1);
        allCalls[0] = payload;

        batch(allCalls);
    }


    function setVars(uint _num, address onBehalfOf) external payable {
        pool.setVars(_num, onBehalfOf);
    }

    function setPool(address pool_) public {
        pool = Pool(pool_);
    }
}
```

* First we connect the Router to the Pool contract by calling **setPool** on the Router.
* Then we call `test`, passing in values for num and some address of choice.
* Notice that **`msgSender`** in Pool was updated with our input value.

Hence, the batch fn in Router, does pass on the correct input values through delegateCall.

### Use of msg.sender in Router

What if we pass msg.sender in batch, instead of defining it as an input address?

In this example, we modify **`test()`** to use msg.sender

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.22;

contract Router {

    Pool public pool;


    /// @dev Helper function to extract a useful revert message from a failed call.
    /// If the returned data is malformed or not correctly abi encoded then this call can fail itself.
    function getRevertMsg(bytes memory returnData) internal pure returns (string memory)
    {
        // If the _res length is less than 68, then the transaction failed silently (without a revert message)
        if (returnData.length < 68) return "Transaction reverted silently";

        assembly {
            // Slice the sighash.
            returnData := add(returnData, 0x04)
        }

        return abi.decode(returnData, (string)); // All that remains is the revert string
    }

    /// @dev Allows batched call to self (this contract).
    /// @param calls An array of inputs for each call.
    function batch(bytes[] memory calls) public payable returns(bytes[] memory results) {

        results = new bytes[](calls.length);

        for (uint256 i; i < calls.length; i++) {

            (bool success, bytes memory result) = address(this).delegatecall(calls[i]);

            if (!success) revert(getRevertMsg(result));

            results[i] = result;
        }

    }


    function test(uint _num) public {

        bytes memory payload = abi.encodeWithSignature("setVars(uint256,address)", _num, msg.sender);
        
        bytes[] memory allCalls = new bytes[](1);
        allCalls[0] = payload;

        batch(allCalls);
    }


    function setVars(uint _num, address onBehalfOf) external payable {
        pool.setVars(_num, onBehalfOf);
    }

    function setPool(address pool_) public {
        pool = Pool(pool_);
    }
}
```

```
contract Pool {

    uint256 public num;
    address public msgSender;

    function setVars(uint256 _num, address onBehalfOf) public {
        num = _num;
        msgSender = onBehalfOf;
    }
}
```

* msgSender in Pool reflects the wallet address that initiated the function.
* meaning to say, **`batch()`** in Router does forward the correct msg.sender value to Pool.&#x20;


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://calnix.gitbook.io/eth-dev/solidity-patterns/router-batch.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
