Skip to content

Commit

Permalink
Merge pull request #198 from balancer:disclaimers-etc
Browse files Browse the repository at this point in the history
Add page for constants/immutables
  • Loading branch information
mkflow27 authored Dec 13, 2024
2 parents 7f016a4 + c7827ff commit 9525b6f
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 17 deletions.
6 changes: 5 additions & 1 deletion docs/build/build-an-amm/deploy-custom-amm-using-factory.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ title: Deploy a Custom AMM Using a Factory

_This section is for developers looking to deploy a custom pool contract that has already been written. If you are looking to design a custom AMM with a novel invariant, start [here](/build/build-an-amm/create-custom-amm-with-novel-invariant.html)._

Balancer recommends that custom pools be deployed via a factory contract because our off-chain infrastructure uses the factory address as a means to identify the type of pool, which is important for integration into the UI, SDK, and external aggregators.
Balancer recommends that custom pools be deployed via a factory contract because our off-chain infrastructure uses the factory address as a means to identify the type of pool, which is important for integration into the UI, SDK, and external aggregators. Factories also provide important security benefits, mainly guaranteeing the integrity of the setup and preventing front-running. If the contract deploys and registers the factory in one operation, the pool is certain to have the desired configuration.

Although core Balancer pool factories do not do this, as they are meant to be generic and support many different use cases, including separate funding, consider also initializing through the factory (or at least in the same transaction as the create). Factories could even inspect the on-chain conditions during deployment, and revert if they are unfavorable (e.g., nested pool rates have been manipulated), further reducing the risks of front-running or other types of interference. Regarding initialization, it is also recommended to initialize ERC4626 buffers *before* deploying any pools with corresponding wrapped tokens. Initialization is the step that sets the proportion of underlying and wrapped tokens; thereafter, liquidity can only be added proportionally. To ensure the pools work as intended, buffers should be created and funded by sponsors prior to deploying pools designed to use them.

For maximum security, consider using a private node for sensitive / high liquidity operations, to avoid risks associated with the public mempool.

To fully set up a new custom pool so that normal liquidity operations and swaps are enabled, five required steps must be taken:

Expand Down
3 changes: 2 additions & 1 deletion docs/concepts/vault/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ order: 0
---

::: info
The Vault should not be interacted with directly. [Routers](../router/overview.md) serve as the entry point for all user actions.
Retail users should not interact directly with the Vault should not be interacted with directly. [Routers](../router/overview.md) serve as the entry point for all user actions.
:::

# The Vault
Expand All @@ -19,6 +19,7 @@ In v3, the vault more formally defines the requirements of a pool contract, shif
The result is pool contracts that are compact and much easier to reason about.

- [On-chain API](/developer-reference/contracts/vault-api.html)
- [Configuration](/developer-reference/contracts/vault-config.html)
- Features
- [Transient accounting](/concepts/vault/transient-accounting.html)
- [ERC20MultiToken](/concepts/vault/erc20-multi-token.html)
Expand Down
51 changes: 45 additions & 6 deletions docs/concepts/vault/buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,63 @@ A significant benefit of the Vault's liquidity buffers is that Liquidity Provide

It's important to note that ERC4626 liquidity buffers are not Balancer Pools. They are a concept internal to the Vault and only function with tokens that comply with the ERC4626 Standard.

action: this section can use more wording work.
:::info
If your organization is a DAO and you're seeking to enhance liquidity for your ERC4626 compliant token, Balancer's ERC4626 liquidity buffers can be a valuable tool. By providing POL to these buffers, you can enable LPs of your token to gain increased access to yield-bearing tokens. This arrangement allows LPs to concentrate on [boosted pools](/concepts/explore-available-balancer-pools/boosted-pool.html), while your DAO contributes POL to the buffer.
:::


## Adding liquidity to a buffer
Liquidity can be added to a buffer for a specific token pair. This is done by invoking the `addLiquidityToBuffer` function in the [Buffer Router](https://github.com/balancer/balancer-v3-monorepo/blob/main/pkg/vault/contracts/BufferRouter.sol), where you designate the ERC4626 Token as the buffer reference. Note that for security reasons, liquidity can only be added (or removed) proportionally. It's important to note that a buffer can still function with zero liquidity. It can be used to wrap and unwrap assets, meaning that even an empty buffer can facilitate swaps through the Vault.
Liquidity can be added to a buffer for a specific token pair. Buffers must be initialized before use, by invoking the `initializeBuffer` function in the [Buffer Router](https://github.com/balancer/balancer-v3-monorepo/blob/main/pkg/vault/contracts/BufferRouter.sol). Initialization is the only operation that can be done "unbalanced," and sets the initial proportions of wrapped and underlying tokens. Thereafter, liquidity can only be added and removed proportionally. This is for simplicity and security reasons, as allowing ongoing unbalanced adds/removes would mean supporting implicit wrap/unwrap operations (in the same way unbalanced liquidity operations on pools involve an implicit swap).

it is strongly recommended to initialize ERC4626 buffers *before* deploying any pools with corresponding wrapped tokens. To ensure the pools work as intended, buffers should be created and funded by sponsors prior to deploying pools designed to use them.

Note that from an economic perspective, there is no intrinsic benefit to being an LP in a buffer. Buffers aren’t pools, so there are no swap fees, no yield participation (compared to simply HODLing), and no connection to the LM system. Funding them is permissionless, but who would do it?

The general idea is that funding parties would be DAO partners (starting with the Balancer DAO) who are motivated to support the platform and promote use of their protocol or yield-bearing token. Immediate access to Balancer liquidity and gas-efficient trades for community members should be enough to entice DAOs and lending protocols to contribute. They would be potentially sacrificing yield on a relatively small position, in hopes that the UX improvement and gas savings for retail users will attract disproportionately greater trade volume and TVL.

Note also that since buffers are not pools, buffer liquidity is not tokenized. Instead of receiving BPT in return for a buffer deposit, the system calculates buffer "shares," and maintains internal accounting of the total shares issued, and the share balance per LP. An important consequence of this is that these shares cannot be transferred. Only the account (or contract) that added liquidity will be able to remove it, so if a contract is involved in providing liquidity, care must be taken to ensure that contract supports all necessary operations.

Providing liquidity to buffers has no benefit for retail users, who should not be calling these functions. (Accordingly, there is no UI for them.)

```solidity
/**
* @notice Adds liquidity for the first time to an internal ERC4626 buffer in the Vault.
* @dev Calling this method binds the wrapped token to its underlying asset internally; the asset in the wrapper
* cannot change afterwards, or every other operation on that wrapper (add / remove / wrap / unwrap) will fail.
* To avoid unexpected behavior, always initialize buffers before creating or initializing any pools that contain
* the wrapped tokens to be used with them.
*
* @param wrappedToken Address of the wrapped token that implements IERC4626
* @param exactAmountUnderlyingIn Amount of underlying tokens that will be deposited into the buffer
* @param exactAmountWrappedIn Amount of wrapped tokens that will be deposited into the buffer
* @param minIssuedShares Minimum amount of shares to receive from the buffer, expressed in underlying token
* native decimals
* @return issuedShares the amount of tokens sharesOwner has in the buffer, denominated in underlying tokens
* (This is the BPT of the Vault's internal ERC4626 buffer.)
*/
function initializeBuffer(
IERC4626 wrappedToken,
uint256 exactAmountUnderlyingIn,
uint256 exactAmountWrappedIn,
uint256 minIssuedShares
) external returns (uint256 issuedShares);
```

Thereafter, additional liquidity can be added by invoking the `addLiquidityToBuffer` function in the [Buffer Router](https://github.com/balancer/balancer-v3-monorepo/blob/main/pkg/vault/contracts/BufferRouter.sol), where you designate the ERC4626 Token as the buffer reference. Note that for security reasons, liquidity can only be added (or removed) proportionally. It's important to note that a buffer can still function with zero liquidity. It can be used to wrap and unwrap assets, meaning that even an empty buffer can facilitate swaps through the Vault.
```solidity
/**
* @notice Adds liquidity proportionally to an internal ERC4626 buffer in the Vault.
* @dev Requires the buffer to be initialized beforehand. Restricting adds to proportional simplifies the Vault
* code, avoiding rounding issues and minimum amount checks. It is possible to add unbalanced by interacting
* with the wrapper contract directly.
*
* @param wrappedToken Address of the wrapped token that implements IERC4626
* @param maxAmountUnderlyingIn Maximum amount of underlying tokens to add to the buffer. It is expressed in underlying token native decimals
* @param maxAmountWrappedIn Maximum amount of wrapped tokens to add to the buffer. It is expressed in wrapped token native decimals
* @param exactSharesToIssue The amount of shares that `sharesOwner` wants to add to the buffer, in underlying token decimals
* @param maxAmountUnderlyingIn Maximum amount of underlying tokens to add to the buffer. It is expressed in
* underlying token native decimals
* @param maxAmountWrappedIn Maximum amount of wrapped tokens to add to the buffer. It is expressed in wrapped
* token native decimals
* @param exactSharesToIssue The amount of shares that `sharesOwner` wants to add to the buffer, in underlying
* token decimals
* @return amountUnderlyingIn Amount of underlying tokens deposited into the buffer
* @return amountWrappedIn Amount of wrapped tokens deposited into the buffer
*/
Expand All @@ -43,7 +82,7 @@ function addLiquidityToBuffer(
uint256 maxAmountUnderlyingIn,
uint256 maxAmountWrappedIn,
uint256 exactSharesToIssue
) external returns (uint256 amountUnderlyingRaw, uint256 amountWrappedRaw);
) external returns (uint256 amountUnderlyingIn, uint256 amountWrappedIn);
```

## Removing liquidity from a buffer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@

| Name | Address |
| ------------------------- | ------------------------------------------ |
| FeeTakingHookExample | 0x790ae803b6c0467C6A4cbDc6d6d712DE34CfdB76 |
| ExitFeeHookExample | 0x2Aa9D4066DAe16ef001765efF2cA8F41Bde0b019 |
| DirectionalFeeHookExample | 0xD9e535a65eb38F962B84f7BBD2bf60293bA54058 |
| LotteryHookExample | 0x0E85194F9eD75F0EFf2b89B73b6AD3053be03853 |

# Deprecated Contracts

Expand Down
6 changes: 2 additions & 4 deletions docs/developer-reference/contracts/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: Security
# Security

:::info
As the development of Balancer v3 is ongoing, this page will gradually be updated with more information.
This page will gradually be updated with more information.
:::

## Bug Bounty
Expand All @@ -20,10 +20,8 @@ For security reports outside of the scope of the bug bounty program, please reac

## Audits

Once audits for Balancer v3 have been finished, they are accessible here:
See the [audits section](https://github.com/balancer/balancer-v3-monorepo/tree/main/audits) of the repo for the published audit reports.

| Scope | Company | Report |
| --------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------- |

## Code Immutability
The core contracts that make up the Balancer v2 Protocol, such as the Vault and Pools (Weighted, Stable, LBP, Managed, Linear, etc), are immutable by design. Any pool updates are made by deploying brand new factories/pools and require users to electively migrate.
Expand Down
2 changes: 1 addition & 1 deletion docs/developer-reference/contracts/vault-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ This `VaultExtension` function retrieves the reserve (i.e., total Vault balance)
```solidity
function getAddLiquidityCalledFlag(address pool) external view returns (bool);
```
This `VaultExtension` function retrieves the value of the falg used to detect and tax "round trip" transactions (adding and removing liquidity in the same pool).
This `VaultExtension` function retrieves the value of the flag used to detect and tax "round trip" transactions (adding and removing liquidity in the same pool).

**Parameters:**

Expand Down
Loading

0 comments on commit 9525b6f

Please sign in to comment.