Weights are calculated through total balances of tokens
Description
The contract derives the weights of tokens from the ratio of balances of tokens:
function createPool(bytes32 salt) external nonReentrant whenNotPaused checkDepositEnded {
// (...)
// Determine the normalized weights of the tokens based on the balances of each token
for (uint256 i = 0; i < nAllowedTokens; i++) {
normalizedWeights[i] = amounts[i] * 1e18 / totalTokens;
}
// (...)
}
However, this effectively sets all relative prices of each token to 1, because Weighted Pool of Balancer V2 calculates the spot price between tokens through the following equation:
Also, because the minimum weight of each token is 1% in Balancer V2, if the total deposited amount of a token is less than 1% of the total deposited amount of all tokens, it is impossible to initialize a pool:
library WeightedMath {
// (...)
// A minimum normalized weight imposes a maximum weight ratio. We need this due to limitations in the
// implementation of the power function, as these ratios are often exponents.
uint256 internal constant _MIN_WEIGHT = 0.01e18;
// (...)
}
Impact
The tokens in the pool would be mispriced, providing an arbitrage opportunity to anyone who swaps on the created pool. Also, if the total deposited amount of a token is less than 1% of the total deposited amount of all tokens, it would be impossible to create a pool.
Recommendations
To remediate this issue, consider 1) calculating the weight of the pool in the way the initial spot prices are correctly determined and 2) ensuring all tokens are at least 1% deposited (by enforcing this condition on the deposit
function or depositing at least 1% of the deposit cap for each token).
Remediation
This issue has been acknowledged by Plaza Finance, and fixes were implemented in the following commits: