# \[Proposal\] Authorize the Batch Relayer

**URL:** https://forum.balancer.fi/t/proposal-authorize-the-batch-relayer/2378
**Category:** General Proposal
**Created:** [December 8, 2021, 1:47pm UTC](https://forum.balancer.fi/t/proposal-authorize-the-batch-relayer/2378 "2021-12-08T13:47:25Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![DavisRamsey](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.balancer.fi/davisramsey/32/973_2.png) [@DavisRamsey](https://forum.balancer.fi/u/DavisRamsey)
#### Post date: [December 8, 2021, 1:47pm UTC](https://forum.balancer.fi/t/proposal-authorize-the-batch-relayer/2378/1 "2021-12-08T13:47:25Z")

</div>

This proposal aims to authorize a relayer capable of atomically combining sequences of `swaps` , `joins` and `exits` , in addition to wrapping and unwrapping stETH and Aave aTokens. The relayer would be granted authority to perform the following tasks on behalf of users **who have opted into using it** :

- Leverage the user’s existing Vault allowances and internal balances to avoid duplicate approvals.
- Swap on the user’s behalf.
- Add and remove liquidity on the user’s behalf.

## Motivation

As [nesting](https://medium.com/balancer-protocol/balancer-launches-metastable-pools-to-further-pool-liquidity-9eade44d73d8) becomes a more relevant piece of the Balancer Ecosystem, executing certain operations requires not only a combination of swaps, but also of joins and exits. The Balancer Vault natively supports batching swaps, but not joins/exits. Consider for example the case of a liquidity provider addding liquidity to a Weighted Pool made of `BAL` and [`staBAL3`](https://app.balancer.fi/#/pool/0x06df3b2bbb68adc8b0e302443692037ed9f91b42000000000000000000000063):

1. use any combination of DAI, USDC and USDT to join the staBAL3 pool, getting `staBAL3` tokens out;
2. join the `BAL/staBAL3` Weighted Pool with `BAL` and `staBAL3` from step 1;

The relayer seeking authorization in this proposal is designed to ease this UX burden by creating an interface by which users can combine swaps, joins, exits, wrappings and unwrappings in any order.

## Risks

This proposal would only grant the required roles to the BalancerRelayer contract. Each user would still be required to opt into the relayer by submitting an approval transaction or signing a message.

The code is a simple wrapper over existing Balancer pool interactions, and it has been thoroughly tested and reviewed by the Balancer Labs team.

The addresses of the BalancerRelayer mentioned in this proposal can be found in the [official repo](https://github.com/balancer-labs/balancer-v2-monorepo/pull/1050/commits/16a224e96f2b6dd65c5a44dbd5fe6ad71161494d).

## Specification

The Balancer governance multisig on each network would submit a transaction to the Authorizer in order to grant the following roles to the BalancerRelayer:

1. `manageUserBalance` : Utilize existing Vault allowances and internal balances so that a user does not have to re-approve the new relayer for each token.
2. `joinPool` : Add liquidity to a pool on the user’s behalf.
3. `exitPool` : Remove liquidity from a pool on the user’s behalf.
4. `swap` : Trade within a single pool on the user’s behalf.
5. `batchSwap` : Make a multihop trade or source liquidity from multiple pools.
6. `setRelayerApproval` : Approve the relayer on the user’s behalf (user must still provide a signed message).

### Ethereum Mainnet

The Gnosis Safe at `0x10A19e7eE7d7F8a52822f6817de8ea18204F2e4f` would send a transaction to the Vault Authorizer at `0xA331D84eC860Bf466b4CdCcFb4aC09a1B43F3aE6` with the following data to authorize the BalancerRelayer at `0xAc9f49eF3ab0BbC929f7b1bb0A17E1Fca5786251` :

```auto
0xfcd7627e0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000ac9f49ef3ab0bbc929f7b1bb0a17e1fca578625100000000000000000000000000000000000000000000000000000000000000060014a06d322ff07fcc02b12f93eb77bb76e28cdee4fc0670b9dec98d24bbfec8eba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b49878ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653c149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d347b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30

```

Which is the ABI-encoded calldata for:

```auto
authorizer.grantRoles(
  [
    0x0014a06d322ff07fcc02b12f93eb77bb76e28cdee4fc0670b9dec98d24bbfec8,
    0xeba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b498,
    0x78ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653,
    0xc149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d34,
    0x7b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff,
    0x1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30,
  ],
  0xAc9f49eF3ab0BbC929f7b1bb0A17E1Fca5786251
);

```

### Polygon

The Gnosis Safe at `0xd2bD536ADB0198f74D5f4f2Bd4Fe68Bae1e1Ba80` would send a transaction to the Vault Authorizer at `0xA331D84eC860Bf466b4CdCcFb4aC09a1B43F3aE6` with the following data to authorize the BalancerRelayer at `0x4574ccBcC09A00C9eE55fB92Fe353699A4fA800e` :

```auto
0xfcd7627e00000000000000000000000000000000000000000000000000000000000000400000000000000000000000004574ccbcc09a00c9ee55fb92fe353699a4fa800e00000000000000000000000000000000000000000000000000000000000000060014a06d322ff07fcc02b12f93eb77bb76e28cdee4fc0670b9dec98d24bbfec8eba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b49878ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653c149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d347b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30

```

Which is the ABI-encoded calldata for:

```auto
authorizer.grantRoles(
  [
    0x0014a06d322ff07fcc02b12f93eb77bb76e28cdee4fc0670b9dec98d24bbfec8,
    0xeba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b498,
    0x78ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653,
    0xc149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d34,
    0x7b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff,
    0x1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30,
  ],
  0x4574ccBcC09A00C9eE55fB92Fe353699A4fA800e
);

```

### Arbitrum

The Gnosis Safe at `0x6207ed574152496c9B072C24FD87cE9cd9E17320` would send a transaction to the Vault Authorizer at `0xA331D84eC860Bf466b4CdCcFb4aC09a1B43F3aE6` with the following data to authorize the BalancerRelayer at `0x466262c2a275aB106E54D95B5B04603e12b58cA1` :

```auto
0xfcd7627e0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000466262c2a275ab106e54d95b5b04603e12b58ca100000000000000000000000000000000000000000000000000000000000000060014a06d322ff07fcc02b12f93eb77bb76e28cdee4fc0670b9dec98d24bbfec8eba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b49878ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653c149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d347b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30

```

Which is the ABI-encoded calldata for:

```auto
authorizer.grantRoles(
  [
    0x0014a06d322ff07fcc02b12f93eb77bb76e28cdee4fc0670b9dec98d24bbfec8,
    0xeba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b498,
    0x78ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653,
    0xc149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d34,
    0x7b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff,
    0x1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30,
  ],
  0x466262c2a275aB106E54D95B5B04603e12b58cA1
);

```

### Final Notes

For transparency, a developer could reproduce the encoded data by computing the following:

```auto
const ethers = require("ethers")

const authorizer = new ethers.utils.Interface([
  "function grantRoles(bytes32[] memory roles, address account)",
]);
const vault = new ethers.utils.Interface([
  "function setRelayerApproval(address, address, bool)",
  "function manageUserBalance((uint8, address, uint256, address, address)[])",
  "function joinPool(bytes32, address, address, (address[], uint256[], bytes, bool))",
  "function exitPool(bytes32, address, address, (address[], uint256[], bytes, bool))",
  "function swap((bytes32, uint8, address, address, uint256, bytes), (address, bool, address, bool), uint256, uint256)",
  "function batchSwap(uint8, (bytes32, uint256, uint256, uint256, bytes)[], address[], (address, bool, address, bool), int256[], uint256)",
]);

function roleId(address, sighash) {
  return ethers.utils.solidityKeccak256(["uint256", "bytes4"], [address, sighash])
}

const roles = ["setRelayerApproval", "manageUserBalance", "joinPool", "exitPool", "swap", "batchSwap"]
  .map(name => roleId("0xBA12222222228d8Ba445958a75a0704d566BF2C8", vault.getSighash(name)));

// Mainnet
let batchRelayer = "0xAc9f49eF3ab0BbC929f7b1bb0A17E1Fca5786251";
let data = authorizer.encodeFunctionData("grantRoles", [roles, batchRelayer]);

console.log(`\n\n\n-*-*-*-*-*-*-MAINNET-*-*-*-*-*-*-`);
console.log(`authorizer.grantRoles(
  [
    ${roles.map(role => `${role},`).join("\n ")}
  ],
  ${batchRelayer}
);`);
console.log(data);

// Polygon
batchRelayer = "0x4574ccBcC09A00C9eE55fB92Fe353699A4fA800e";
data = authorizer.encodeFunctionData("grantRoles", [roles, batchRelayer]);

console.log(`\n\n\n-*-*-*-*-*-*-POLYGON-*-*-*-*-*-*-`);
console.log(`authorizer.grantRoles(
  [
    ${roles.map(role => `${role},`).join("\n ")}
  ],
  ${batchRelayer}
);`);
console.log(data);

// Arbitrum
batchRelayer = "0x466262c2a275aB106E54D95B5B04603e12b58cA1";
data = authorizer.encodeFunctionData("grantRoles", [roles, batchRelayer]);

console.log(`\n\n\n-*-*-*-*-*-*-ARBITRUM-*-*-*-*-*-*-`);
console.log(`authorizer.grantRoles(
  [
    ${roles.map(role => `${role},`).join("\n ")}
  ],
  ${batchRelayer}
);`);
console.log(data);

```

---

<div class="post-metadata">

### Author: ![DavisRamsey](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.balancer.fi/davisramsey/32/973_2.png) [@DavisRamsey](https://forum.balancer.fi/u/DavisRamsey)
#### Post date: [December 8, 2021, 1:48pm UTC](https://forum.balancer.fi/t/proposal-authorize-the-batch-relayer/2378/2 "2021-12-08T13:48:03Z")

</div>

_Poll ([view on site](https://forum.balancer.fi/t/proposal-authorize-the-batch-relayer/2378/2))_

---

<div class="post-metadata">

### Author: ![zekraken](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.balancer.fi/zekraken/32/823_2.png) [@zekraken](https://forum.balancer.fi/u/zekraken)
#### Post date: [December 9, 2021, 3:17am UTC](https://forum.balancer.fi/t/proposal-authorize-the-batch-relayer/2378/3 "2021-12-09T03:17:53Z")

</div>

bring on the nesting!

---

<div class="post-metadata">

### Author: ![Blackfyre](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.balancer.fi/blackfyre/32/918_2.png) [@Blackfyre](https://forum.balancer.fi/u/Blackfyre)
#### Post date: [December 10, 2021, 12:05am UTC](https://forum.balancer.fi/t/proposal-authorize-the-batch-relayer/2378/4 "2021-12-10T00:05:31Z")

</div>

Not sure about this.
