Skip to content

Commit

Permalink
advanced sections, bounty pages, updated deployments
Browse files Browse the repository at this point in the history
  • Loading branch information
mikemcdonald committed Feb 8, 2023
1 parent 6d0d668 commit 83b3718
Show file tree
Hide file tree
Showing 18 changed files with 333 additions and 159 deletions.
2 changes: 2 additions & 0 deletions docs/.vuepress/configs/navbar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const navbar: NavbarConfig = [
text: 'APIs',
link: '/reference/contracts/apis/vault',
},
'/reference/contracts/security',
'/reference/contracts/error-codes',
'/reference/contracts/query-functions',
],
Expand Down Expand Up @@ -85,6 +86,7 @@ export const navbar: NavbarConfig = [
children: [
'/reference/math/weighted-math',
'/reference/math/stable-math',
'/reference/math/linear-math',
],
},
{
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 9 additions & 1 deletion docs/concepts/advanced/preminted-bpt.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# Preminted BPT
# Preminted BPT

## Overview

Preminted BPT is a relatively new concept in the evolution of Balancer pool design. As [pool composability](/concepts/pools/#pool-composability) became more commonplace with nested pools, the need to go from an asset in a pool to the BPT (normally referred to as a `join`) grew. This not only makes it difficult to include as part of a complex multihop `batchSwap` but also introduced additional gas costs since a `join` will mint new BPT.

Preminted BPT means that the pool mints the max `2**(111)` BPT upon creation and the BPT is included as one of the tokens in the pool itself. The pool's arithmetic behaves as if it didn't exist, and the BPT total supply is not a useful value. Instead a `virtual supply` (how much BPT is actually owned outside the Vault) is used.

Pools with Preminted BPTs like [Composable Stable Pools](/concepts/pools/composable-stable.md) can then allow an user to `swap` from a token in the pool to the BPT of the pool, while previously this was only possible with a `join` operation.
67 changes: 67 additions & 0 deletions docs/concepts/advanced/relayers.md
Original file line number Diff line number Diff line change
@@ -1 +1,68 @@
# Relayers

## Overview

A relayer is a contract that is authorized by the protocol and allows users to make calls to the Vault on behalf of the users. It can use the sender’s ERC20 vault allowance, internal balance, and BPTs on their behalf. Multiple actions (such as exit/join pools, swaps, etc.) can be chained together, improving the UX.

For security reasons, a Relayer has to be authorized by the Balancer DAO before it can be used, and even after authorization, each user would still be required to opt into the relayer by submitting an approval transaction or signing a message.

## How it Works

### Contracts

The Balancer Relayers are composed of two contracts, [BalancerRelayer](https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/standalone-utils/contracts/relayer/BalancerRelayer.sol), which is the single point of entry via the multicall function, and a library contract, such as the [VaultActions](https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/standalone-utils/contracts/relayer/VaultActions.sol), which defines the allowed behavior of the relayer, for example — [VaultActions](https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/standalone-utils/contracts/relayer/VaultActions.sol), [LidoWrapping](https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/standalone-utils/contracts/relayer/LidoWrapping.sol), [GaugeActions](https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/standalone-utils/contracts/relayer/GaugeActions.sol).

Having the multicall single point of entry prevents reentrancy. The library contract cannot be called directly, but the multicall can repeatedly delegatecall into the library code to perform a chain of actions.

Some pseudocode demonstrating how an authorization, exitPool and swap can be chained and called via the multicall function:

```ts
const approval = buildApproval(signature); // setRelayerApproval call
const exitPoolCallData = buildExitPool(poolId, bptAmt); // exitPool call
const swapCallData = buildSwap(); // batchSwap call

const tx = await relayer.multicall([approval, exitPoolCallData, swapCallData]);
```

### Approval

A user has to approve each Relayer before they can use it. To check if a Relayer is approved the [hasApprovedRelayer](/reference/contracts/apis/vault.md#hasapprovedrelayer) on the Vault can be used.

A Relayer can also be approved by using the `setRelayerApproval` function from the [BaseRelayerLibrary](https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/standalone-utils/contracts/relayer/BaseRelayerLibrary.sol) contract. Here a signed authorisation message from the user is passed as an input parameter. This allows the approval to be included at the start of a chain of actions so the user only needs to submit a single transaction creating a better UX.

### Chained References

Output References allow the Relayer to store output values from one action which can then be read and used in another action. This allows us to chain together actions. For example, we could exit a pool, save the exit amounts of each token to a reference and then do a batchSwap using the references as input amounts for each swap:

![Relayer Chained Call](/images/relayer-chained-call.webp)

An [OutputReference](https://github.com/balancer-labs/balancer-v2-monorepo/blob/8ac66717502b00122a3fcdf78e6d555c54528c3c/pkg/standalone-utils/contracts/relayer/VaultActions.sol#L39) consists of an index and a key:

```solidity
struct OutputReference {
uint256 index;
uint256 key;
}
```

Where the key is the slot the value will be stored at. The index indicates which output amount should be stored. For example, if exitPool exits to 3 tokens, DAI (index 0), USDC (1), USDT (2), we would want to use index 0 to store DAI, 1 for USDC, etc.

## Example Use Case - Pool Migration

### Intro

Balancer aims for the best capital efficiency for LPs so it made sense to offer the option to migrate from the old “staBal3” pool consisting of DAI, USDC and USDT to a new “boosted” stable pool which is more capital efficient because it uses yield bearing assets.

Migrating between these pools would take multiple steps:

1. Unstake from staBal3 gauge -> staBalBpt
2. `exitPool` from staBal, staBalBpt -> DAI, USDC, USDT
3. join the bb-a-usd pool using `batchSwaps`
a. DAI -> bbausdBpt
b. USDC -> bbausdBpt
c. USDT -> bbausdBpt
4. stake bbausdBpt in gauge

This would be quite an ordeal for a user to do manually but the Relayer can be used to combine all these actions into a single transaction for the user.

A full example of this can be found [here](https://github.com/balancer-labs/balancer-sdk/blob/develop/balancer-js/src/modules/zaps/bbausd2-migrations/stabal3.integration.spec.ts#L120-L183)
14 changes: 13 additions & 1 deletion docs/concepts/advanced/smart-order-router.md
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
# Smart Order Router
# Smart Order Router

## Overview

The Smart Order Router (SOR) finds the best prices for Balancer traders. For given input and output tokens, the SOR finds the optimal trades whether that is a direct swap in one pool, or a combination of trades hopping through multiple pools.

![SOR Path Split Example](/images/sor-path-example.png)

::: tip Under Development

The current SOR is being upgraded with a new alogrithm and architecture to improve speed and reliability. This page will be filled out upon release

:::
Loading

0 comments on commit 83b3718

Please sign in to comment.