Skip to content

Commit

Permalink
update custom pool examples to match latest changes to v3 docs
Browse files Browse the repository at this point in the history
  • Loading branch information
MattPereira committed Dec 22, 2024
1 parent e56765f commit 02236a4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 41 deletions.
55 changes: 31 additions & 24 deletions packages/foundry/contracts/pools/ConstantProductPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,29 @@ contract ConstantProductPool is BalancerPoolToken, IBasePool {

/**
* @notice Computes and returns the pool's invariant.
* @dev This function computes the invariant based on current balances
* @param balancesLiveScaled18 Array of current pool balances for each token in the pool, scaled to 18 decimals
*
* @dev This function computes the invariant based on current balances.
* @param balancesLiveScaled18 Token balances after paying yield fees, applying decimal scaling and rates
* @param rounding Rounding direction to consider when computing the invariant
* @return invariant The calculated invariant of the pool, represented as a uint256
*/
function computeInvariant(uint256[] memory balancesLiveScaled18, Rounding) public pure returns (uint256 invariant) {
// scale the invariant to 1e18
function computeInvariant(
uint256[] memory balancesLiveScaled18,
Rounding rounding
) public pure returns (uint256 invariant) {
// expected to work with 2 tokens only.
invariant = FixedPoint.ONE;
invariant = invariant.mulDown(balancesLiveScaled18[0]).mulDown(balancesLiveScaled18[1]);
invariant = Math.sqrt(invariant) * 1e9; // maintain the 1e18 scale
for (uint256 i = 0; i < balancesLiveScaled18.length; ++i) {
invariant = rounding == Rounding.ROUND_DOWN
? invariant.mulDown(balancesLiveScaled18[i])
: invariant.mulUp(balancesLiveScaled18[i]);
}
// scale the invariant to 1e18
invariant = Math.sqrt(invariant) * 1e9;
}

/**
* @dev Computes the new balance of a token after an operation, given the invariant growth ratio and all other balances.
* @notice Computes the new balance of a token after an operation.
* @dev This takes into account the invariant growth ratio and all other balances.
* @param balancesLiveScaled18 Current live balances (adjusted for decimals, rates, etc.)
* @param tokenInIndex The index of the token we're computing the balance for, in token registration order
* @param invariantRatio The ratio of the new invariant (after an operation) to the old
Expand All @@ -71,32 +80,30 @@ contract ConstantProductPool is BalancerPoolToken, IBasePool {
uint256 tokenInIndex,
uint256 invariantRatio
) external pure returns (uint256 newBalance) {
uint256 newInvariant = computeInvariant(balancesLiveScaled18, Rounding.ROUND_DOWN).mulDown(invariantRatio);
uint256 otherTokenIndex = tokenInIndex == 0 ? 1 : 0;
uint256 poolBalanceOtherToken = balancesLiveScaled18[otherTokenIndex];

newBalance = ((newInvariant * newInvariant) / poolBalanceOtherToken);
}
uint256 newInvariant = computeInvariant(balancesLiveScaled18, Rounding.ROUND_DOWN).mulDown(invariantRatio);

// Invariant shrink limit: non-proportional remove cannot cause the invariant to decrease by less than this ratio.
/// @return minimumInvariantRatio The minimum invariant ratio for a pool during unbalanced remove liquidity
function getMinimumInvariantRatio() external pure returns (uint256) {
return _MIN_INVARIANT_RATIO;
newBalance = ((newInvariant * newInvariant) / balancesLiveScaled18[otherTokenIndex]);
}

// Invariant growth limit: non-proportional add cannot cause the invariant to increase by more than this ratio.
/// @return maximumInvariantRatio The maximum invariant ratio for a pool during unbalanced add liquidity
function getMaximumInvariantRatio() external pure returns (uint256) {
return _MAX_INVARIANT_RATIO;
}

/// @return minimumSwapFeePercentage The minimum swap fee percentage for a pool
//The minimum swap fee percentage for a pool
function getMinimumSwapFeePercentage() external pure returns (uint256) {
return _MIN_SWAP_FEE_PERCENTAGE;
}

/// @return maximumSwapFeePercentage The maximum swap fee percentage for a pool
// The maximum swap fee percentage for a pool
function getMaximumSwapFeePercentage() external pure returns (uint256) {
return _MAX_SWAP_FEE_PERCENTAGE;
}

// Invariant shrink limit: non-proportional remove cannot cause the invariant to decrease by less than this ratio
function getMinimumInvariantRatio() external pure returns (uint256) {
return _MIN_INVARIANT_RATIO;
}

// Invariant growth limit: non-proportional add cannot cause the invariant to increase by more than this ratio
function getMaximumInvariantRatio() external pure returns (uint256) {
return _MAX_INVARIANT_RATIO;
}
}
36 changes: 19 additions & 17 deletions packages/foundry/contracts/pools/ConstantSumPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import { BalancerPoolToken } from "@balancer-labs/v3-vault/contracts/BalancerPoo
import { IBasePool } from "@balancer-labs/v3-interfaces/contracts/vault/IBasePool.sol";
import { PoolSwapParams, Rounding } from "@balancer-labs/v3-interfaces/contracts/vault/VaultTypes.sol";
import { IVault } from "@balancer-labs/v3-interfaces/contracts/vault/IVault.sol";
import { FixedPoint } from "@balancer-labs/v3-solidity-utils/contracts/math/FixedPoint.sol";

/**
* @title Constant Sum Pool
* @notice This custom pool example is based on the Constant Sum Pool from the Balancer v3 Docs
* https://docs-v3.balancer.fi/build-a-custom-amm/build-an-amm/create-custom-amm-with-novel-invariant.html
*/
contract ConstantSumPool is IBasePool, BalancerPoolToken {
using FixedPoint for uint256;

uint256 private constant _MIN_INVARIANT_RATIO = 70e16; // 70%
uint256 private constant _MAX_INVARIANT_RATIO = 300e16; // 300%
uint256 private constant _MIN_SWAP_FEE_PERCENTAGE = 1e12; // 0.0001%
Expand Down Expand Up @@ -39,9 +42,10 @@ contract ConstantSumPool is IBasePool, BalancerPoolToken {
}

/**
* @dev Computes the new balance of a token after an operation, given the invariant growth ratio and all other balances
* @dev Computes the new balance of a token after an operation, given the invariant growth ratio and all other
* balances.
* @param balancesLiveScaled18 Current live balances (adjusted for decimals, rates, etc.)
* @param tokenInIndex The index of the token we're computing the balance for, in token registration order
* @param tokenInIndex The index of the token we're computing the balance for (tokens are sorted alphanumerically)
* @param invariantRatio The ratio of the new invariant (after an operation) to the old
* @return newBalance The new balance of the selected token, after the operation
*/
Expand All @@ -52,28 +56,26 @@ contract ConstantSumPool is IBasePool, BalancerPoolToken {
) external pure returns (uint256 newBalance) {
uint256 invariant = computeInvariant(balancesLiveScaled18, Rounding.ROUND_DOWN);

newBalance = (balancesLiveScaled18[tokenInIndex] + invariant * (invariantRatio)) - invariant;
}

// Invariant shrink limit: non-proportional remove cannot cause the invariant to decrease by less than this ratio.
/// @return minimumInvariantRatio The minimum invariant ratio for a pool during unbalanced remove liquidity
function getMinimumInvariantRatio() external pure returns (uint256) {
return _MIN_INVARIANT_RATIO;
}

// Invariant growth limit: non-proportional add cannot cause the invariant to increase by more than this ratio.
/// @return maximumInvariantRatio The maximum invariant ratio for a pool during unbalanced add liquidity
function getMaximumInvariantRatio() external pure returns (uint256) {
return _MAX_INVARIANT_RATIO;
newBalance = (balancesLiveScaled18[tokenInIndex] + invariant.mulDown(invariantRatio)) - invariant;
}

/// @return minimumSwapFeePercentage The minimum swap fee percentage for a pool
//The minimum swap fee percentage for a pool
function getMinimumSwapFeePercentage() external pure returns (uint256) {
return _MIN_SWAP_FEE_PERCENTAGE;
}

/// @return maximumSwapFeePercentage The maximum swap fee percentage for a pool
// The maximum swap fee percentage for a pool
function getMaximumSwapFeePercentage() external pure returns (uint256) {
return _MAX_SWAP_FEE_PERCENTAGE;
}

// Invariant shrink limit: non-proportional remove cannot cause the invariant to decrease by less than this ratio
function getMinimumInvariantRatio() external pure returns (uint256) {
return _MIN_INVARIANT_RATIO;
}

// Invariant growth limit: non-proportional add cannot cause the invariant to increase by more than this ratio
function getMaximumInvariantRatio() external pure returns (uint256) {
return _MAX_INVARIANT_RATIO;
}
}

0 comments on commit 02236a4

Please sign in to comment.