Skip to main content

BalancerPoolTokenPrice

Git Source

Inherits: PriceSubmodule

Title: BalancerPoolTokenPrice

Author: 0xJem

forge-lint: disable-start(mixed-case-function,screaming-snake-case-immutable)

Provides prices related to Balancer pools

State Variables

BASE_10_MAX_EXPONENT

Any token or pool with a decimal scale greater than this would result in an overflow

uint8 internal constant BASE_10_MAX_EXPONENT = 50

WEIGHTED_POOL_POW_DECIMALS

Used when calculating the value of a token in a weighted pool

uint8 internal constant WEIGHTED_POOL_POW_DECIMALS = 18

POOL_PARAMS_LENGTH

The expected length of the encoded pool parameters (1 address = 32 bytes)

uint256 internal constant POOL_PARAMS_LENGTH = 32

balVault

Address of the Balancer vault

IVault public immutable balVault

Functions

constructor

constructor(Module parent_, IVault balVault_) Submodule(parent_);

SUBKEYCODE

20 byte identifier for the submodule. First 5 bytes must match PARENT().

function SUBKEYCODE() public pure override returns (SubKeycode);

VERSION

function VERSION() public pure override returns (uint8 major, uint8 minor);

_convertERC20Decimals

Converts value_ from the ERC20 token's decimals to outputDecimals_

This function will revert if:

  • Converting the token's decimals would result in an overflow.
function _convertERC20Decimals(uint256 value_, address token_, uint8 outputDecimals_)
internal
view
returns (uint256);

Parameters

NameTypeDescription
value_uint256Value in native ERC20 token decimals
token_addressThe address of the ERC20 token
outputDecimals_uint8The desired number of decimals

Returns

NameTypeDescription
<none>uint256uint256 Value in the scale of outputDecimals_

_getTokenBalanceWeighting

Obtains the balance/weight ratio of the token at index index_ in the pool

This function will revert if:

  • Converting the pool's decimals would result in an overflow.

As this function is accessing the balances of the pool, ensure that VaultReentrancyLib

is called in order to prevent re-entrancy attacks.

function _getTokenBalanceWeighting(BalancerWeightedPoolCache memory cache, uint256 index_, uint8 outputDecimals_)
internal
view
returns (uint256);

Parameters

NameTypeDescription
cacheBalancerWeightedPoolCacheCached data related to the Balancer weighted pool
index_uint256Index of the token in the Balancer pool
outputDecimals_uint8The desired number of decimals

Returns

NameTypeDescription
<none>uint256uint256 Value in the scale of outputDecimals_

_getTokenValueInWeightedPool

Calculates the value of a token in a Balancer weighted pool

This function will revert if:

  • The provided token is address(0)

  • The provided weight is 0

function _getTokenValueInWeightedPool(
address token_,
uint256 weight_,
uint8 poolDecimals_,
uint8 outputDecimals_,
bytes32 poolId_,
uint256 index_
) internal view returns (uint256);

Parameters

NameTypeDescription
token_addressAddress of the token
weight_uint256Weight of the token in the Balancer pool
poolDecimals_uint8The number of decimals of the Balancer pool
outputDecimals_uint8The desired number of decimals
poolId_bytes32id of the Balancer pool
index_uint256Index of the token in the Balancer pool

Returns

NameTypeDescription
<none>uint256uint256 Value in the scale of outputDecimals_

_getWeightedPoolRawValue

Calculates the value of a Balancer weighted pool

This function calculates the value of each token and returns the sum.

function _getWeightedPoolRawValue(
address[] memory tokens_,
uint256[] memory weights_,
uint8 poolDecimals_,
uint8 outputDecimals_,
bytes32 poolId_
) internal view returns (uint256);

Parameters

NameTypeDescription
tokens_address[]Array of tokens in the Balancer pool
weights_uint256[]Array of weights of the tokens in the Balancer pool
poolDecimals_uint8The number of decimals of the Balancer pool
outputDecimals_uint8The desired number of decimals
poolId_bytes32

Returns

NameTypeDescription
<none>uint256uint256 Value in the scale of outputDecimals_

getWeightedPoolTokenPrice

Determines the unit price of the pool token for the Balancer weighted pool specified in params_.

To avoid price manipulation, this function calculated the pool token price in the manner recommended by

Balancer at https://docs.balancer.fi/concepts/advanced/valuing-bpt/valuing-bpt.html#on-chain-price-evaluation :

  • Obtains the prices of all tokens in the pool from PRICE (usually using price feeds)

  • Applies a guard to protect against re-entrancy attacks on the Balancer pool

This function will revert if:

  • The scale of outputDecimals_ or the pool's decimals is too high

  • The pool is mis-configured

  • If the pool is not a weighted pool

function getWeightedPoolTokenPrice(address, uint8 outputDecimals_, bytes calldata params_)
external
view
returns (uint256);

Parameters

NameTypeDescription
<none>address
outputDecimals_uint8The number of output decimals (assumed to be the same as PRICE decimals)
params_bytesBalancer pool parameters of type BalancerWeightedPoolParams

Returns

NameTypeDescription
<none>uint256uint256 Price in the scale of outputDecimals_

getStablePoolTokenPrice

Determines the unit price of the pool token for the Balancer stable pool specified in params_.

To avoid price manipulation, this function calculated the pool token price in the following manner:

This function will revert if:

  • The scale of outputDecimals_ or the pool's decimals is too high

  • The pool is mis-configured

  • If the pool is not a stable pool or is a composable stable pool (determined by the absence of the getLastInvariant() function)

NOTE: If there is a significant de-peg between the prices of constituent assets, the token price will be inaccurate. See the now-deleted mention of this: https://github.com/balancer/docs/pull/112/files

function getStablePoolTokenPrice(address, uint8 outputDecimals_, bytes calldata params_)
external
view
returns (uint256);

Parameters

NameTypeDescription
<none>address
outputDecimals_uint8The number of output decimals (assumed to be the same as PRICE decimals)
params_bytesBalancer pool parameters of type BalancerStablePoolParams

Returns

NameTypeDescription
<none>uint256uint256 Price in the scale of outputDecimals_

getTokenPriceFromWeightedPool

Determines the spot price of the specified token from the Balancer pool specified in params_.

It does this by:

  • Determining the price and reserves of the token paired with lookupToken_

  • Determining the corresponding price of lookupToken_

Will revert upon the following:

  • If outputDecimals_ or the pool's decimals are too high

  • If the transaction involves reentrancy on the Balancer pool

  • If the pool is not a weighted pool

NOTE: as the reserves of Balancer pools can be manipulated using flash loans, the spot price

can also be manipulated. Price feeds are a preferred source of price data. Use this function with caution.

function getTokenPriceFromWeightedPool(address lookupToken_, uint8 outputDecimals_, bytes calldata params_)
external
view
returns (uint256);

Parameters

NameTypeDescription
lookupToken_addressThe token to determine the price of
outputDecimals_uint8The number of output decimals (assumed to be the same as PRICE decimals)
params_bytesBalancer pool parameters of type BalancerWeightedPoolParams

Returns

NameTypeDescription
<none>uint256uint256 Price in the scale of outputDecimals_

getTokenPriceFromStablePool

Determines the spot price of the specified token from the Balancer pool specified in params_.

It does this by:

  • Using the Balancer StableMath library to determine the quantity of lookupToken_ returned for 1 of

any token paired with lookupToken_ for which a price is available

Will revert upon the following:

  • If the transaction involves reentrancy on the Balancer pool

  • If the pool is not a stable pool or is a composable stable pool (determined by the absence of the getLastInvariant() function)

NOTE: as the reserves of Balancer pools can be manipulated using flash loans, the spot price

can also be manipulated. Price feeds are a preferred source of price data. Use this function with caution.

function getTokenPriceFromStablePool(address lookupToken_, uint8 outputDecimals_, bytes calldata params_)
external
view
returns (uint256);

Parameters

NameTypeDescription
lookupToken_addressThe token to determine the price of
outputDecimals_uint8The number of output decimals (assumed to be the same as PRICE decimals)
params_bytesBalancer pool parameters of type BalancerStablePoolParams

Returns

NameTypeDescription
<none>uint256uint256 Price in the scale of outputDecimals_

Errors

Balancer_ParamsInvalid

The provided parameters are invalid

error Balancer_ParamsInvalid(bytes params_);

Parameters

NameTypeDescription
params_bytesThe encoded parameters

Balancer_AssetDecimalsOutOfBounds

The number of decimals of the asset is greater than the maximum allowed

error Balancer_AssetDecimalsOutOfBounds(address asset_, uint8 decimals_, uint8 maxDecimals_);

Parameters

NameTypeDescription
asset_addressThe address of the asset
decimals_uint8The number of decimals of the asset
maxDecimals_uint8The maximum number of decimals allowed

Balancer_LookupTokenNotFound

The provided token was not found in the Balancer pool

error Balancer_LookupTokenNotFound(bytes32 poolId_, address asset_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
asset_addressThe address of the token

Balancer_OutputDecimalsOutOfBounds

The desired number of output decimals is greater than the maximum allowed

error Balancer_OutputDecimalsOutOfBounds(uint8 outputDecimals_, uint8 maxDecimals_);

Parameters

NameTypeDescription
outputDecimals_uint8The desired number of output decimals
maxDecimals_uint8The maximum number of decimals allowed

Balancer_PoolDecimalsOutOfBounds

The number of decimals of the pool is greater than the maximum allowed

error Balancer_PoolDecimalsOutOfBounds(bytes32 poolId_, uint8 poolDecimals_, uint8 maxDecimals_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
poolDecimals_uint8The number of decimals of the pool
maxDecimals_uint8The maximum number of decimals allowed

Balancer_PoolStableRateInvalid

The stable rate returned by the pool is invalid

This currently only occurs if the rate is 0

error Balancer_PoolStableRateInvalid(bytes32 poolId_, uint256 rate_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
rate_uint256The stable rate returned by the pool

Balancer_PoolSupplyInvalid

The total supply returned by the pool is invalid

This currently only occurs if the total supply is 0

error Balancer_PoolSupplyInvalid(bytes32 poolId_, uint256 supply_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
supply_uint256The total supply returned by the pool

Balancer_PoolTokenInvalid

A token in the pool is invalid

This currently only occurs if the token address is 0

error Balancer_PoolTokenInvalid(bytes32 poolId_, uint256 index_, address token_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
index_uint256The index of the token in the pool
token_addressThe address of the token

Balancer_PoolValueZero

The value of the Balancer pool is zero

This currently only occurs if the number of tokens is 0

error Balancer_PoolValueZero(bytes32 poolId_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool

Balancer_PoolTokenWeightMismatch

There is a mismatch between the number of tokens and weights

This is unlikely to occur, but is in place to be defensive

error Balancer_PoolTokenWeightMismatch(bytes32 poolId_, uint256 tokenCount_, uint256 weightCount_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
tokenCount_uint256The number of tokens in the Balancer pool
weightCount_uint256The number of weights in the Balancer pool

Balancer_PoolTokenBalanceMismatch

There is a mismatch between the number of tokens and balances

This is unlikely to occur, but is in place to be defensive

error Balancer_PoolTokenBalanceMismatch(bytes32 poolId_, uint256 tokenCount_, uint256 balanceCount_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
tokenCount_uint256The number of tokens in the Balancer pool
balanceCount_uint256The number of balances in the Balancer pool

Balancer_PoolTokenBalanceWeightMismatch

There is a mismatch between the number of tokens, balances and weights

This is unlikely to occur, but is in place to be defensive

error Balancer_PoolTokenBalanceWeightMismatch(
bytes32 poolId_, uint256 tokenCount_, uint256 balanceCount_, uint256 weightCount_
);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
tokenCount_uint256The number of tokens in the Balancer pool
balanceCount_uint256The number of balances in the Balancer pool
weightCount_uint256The number of weights in the Balancer pool

Balancer_PoolTypeNotStable

The pool is not a stable pool

error Balancer_PoolTypeNotStable(bytes32 poolId_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool

Balancer_PoolTypeNotWeighted

The pool is not a weighted pool

error Balancer_PoolTypeNotWeighted(bytes32 poolId_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool

Balancer_PoolWeightInvalid

A weight in the pool is invalid

This currently only occurs if the weight is 0

error Balancer_PoolWeightInvalid(bytes32 poolId_, uint256 index_, uint256 weight_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
index_uint256The index of the weight in the pool
weight_uint256The value of the weight

Balancer_PriceNotFound

The price of a corresponding token could not be found

This occurs if there are no asset definitions in PRICE

for the other tokens in the Balancer pool, and hence

the price of the lookup token cannot be determined

error Balancer_PriceNotFound(bytes32 poolId_, address lookupToken_);

Parameters

NameTypeDescription
poolId_bytes32The id of the Balancer pool
lookupToken_addressThe token to determine the price of

Structs

BalancerWeightedPoolParams

Parameters for a Balancer weighted pool

struct BalancerWeightedPoolParams {
IWeightedPool pool;
}

Properties

NameTypeDescription
poolIWeightedPoolAddress of the Balancer pool

BalancerStablePoolParams

Parameters for a Balancer stable pool

struct BalancerStablePoolParams {
IStablePool pool;
}

Properties

NameTypeDescription
poolIStablePoolAddress of the Balancer pool

BalancerWeightedPoolCache

Struct to cache data related to a Balancer weighted pool

This is not persisted between calls, and is only used to reduce the number of parameters

struct BalancerWeightedPoolCache {
address[] tokens;
uint256[] weights;
uint256[] balances;
uint8 decimals;
bytes32 poolId;
}