Deploy; PartyPoolBalancedPair as separate contract

This commit is contained in:
tim
2025-09-29 18:05:04 -04:00
parent a43c893609
commit 43fb62c47c
9 changed files with 324 additions and 81 deletions

View File

@@ -9,7 +9,7 @@ remappings = [
optimizer=true
optimizer_runs=999999999
viaIR=true
gas_reports = ['PartyPool', 'PartyPlanner']
gas_reports = ['PartyPlanner', 'PartyPoolBalancedPair', 'PartyPool', ]
fs_permissions = [{ access = "write", path = "chain.json"}]
[lint]

30
src/Deploy.sol Normal file
View File

@@ -0,0 +1,30 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.30;
import "./PartyPoolBalancedPair.sol";
import {PartyPlanner} from "./PartyPlanner.sol";
import {PartyPool} from "./PartyPool.sol";
library Deploy {
function newPartyPlanner() internal returns (PartyPlanner) {
return new PartyPlanner();
}
function newPartyPool(
string memory name_,
string memory symbol_,
IERC20[] memory tokens_,
uint256[] memory bases_,
int128 kappa_,
uint256 swapFeePpm_,
uint256 flashFeePpm_,
bool stablePair_
) internal returns (PartyPool) {
return stablePair_ ?
new PartyPoolBalancedPair(name_, symbol_, tokens_, bases_, kappa_, swapFeePpm_, flashFeePpm_) :
new PartyPool(name_, symbol_, tokens_, bases_, kappa_, swapFeePpm_, flashFeePpm_);
}
}

View File

@@ -2,8 +2,9 @@
pragma solidity ^0.8.30;
import "./IPartyPlanner.sol";
import "./PartyPool.sol";
import "./LMSRStabilized.sol";
import "./PartyPool.sol";
import "./PartyPoolBalancedPair.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
@@ -48,16 +49,9 @@ contract PartyPlanner is IPartyPlanner {
require(_kappa > int128(0), "Planner: kappa must be > 0");
// Create a new PartyPool instance (kappa-based constructor)
pool = new PartyPool(
name_,
symbol_,
_tokens,
_bases,
_kappa,
_swapFeePpm,
_flashFeePpm,
_stable
);
pool = _stable && _tokens.length == 2 ?
new PartyPoolBalancedPair(name_, symbol_, _tokens, _bases, _kappa, _swapFeePpm, _flashFeePpm) :
new PartyPool(name_, symbol_, _tokens, _bases, _kappa, _swapFeePpm, _flashFeePpm);
_allPools.push(pool);
_poolSupported[pool] = true;

View File

@@ -32,9 +32,6 @@ contract PartyPool is PoolBase, IPartyPool {
/// @notice Flash-loan fee in parts-per-million (ppm) applied to flash borrow amounts.
uint256 public immutable flashFeePpm;
/// @notice If true and there are exactly two assets, an optimized 2-asset stable-pair path is used for some computations.
bool private immutable _stablePair; // if true, the optimized LMSRStabilizedBalancedPair optimization path is enabled
/// @inheritdoc IPartyPool
function tokens(uint256 i) external view returns (IERC20) { return s.tokens[i]; }
@@ -65,7 +62,6 @@ contract PartyPool is PoolBase, IPartyPool {
/// @param kappa_ liquidity parameter κ (Q64.64) used to derive b = κ * S(q)
/// @param swapFeePpm_ fee in parts-per-million, taken from swap input amounts before LMSR calculations
/// @param flashFeePpm_ fee in parts-per-million, taken for flash loans
/// @param stable_ if true and assets.length==2, then the optimization for 2-asset stablecoin pools is activated.
constructor(
string memory name_,
string memory symbol_,
@@ -73,15 +69,13 @@ contract PartyPool is PoolBase, IPartyPool {
uint256[] memory bases_,
int128 kappa_,
uint256 swapFeePpm_,
uint256 flashFeePpm_,
bool stable_
uint256 flashFeePpm_
) ERC20(name_, symbol_) {
kappa = kappa_;
require(swapFeePpm_ < 1_000_000, "Pool: fee >= ppm");
swapFeePpm = swapFeePpm_;
require(flashFeePpm_ < 1_000_000, "Pool: flash fee >= ppm");
flashFeePpm = flashFeePpm_;
_stablePair = stable_ && tokens_.length == 2;
// Initialize state using library
s.initialize(tokens_, bases_);
@@ -155,8 +149,8 @@ contract PartyPool is PoolBase, IPartyPool {
uint256 outputTokenIndex,
uint256 maxAmountIn,
int128 limitPrice
) external view returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
return s.swapAmounts(inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, swapFeePpm, _stablePair);
) virtual external view returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
return s.swapAmounts(inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, swapFeePpm);
}
/// @inheritdoc IPartyPool
@@ -176,17 +170,7 @@ contract PartyPool is PoolBase, IPartyPool {
return s.swapMintAmounts(inputTokenIndex, maxAmountIn, swapFeePpm, totalSupply());
}
/// @notice Swap input token i -> token j. Payer must approve token i.
/// @dev This function transfers the exact gross input (including fee) from payer and sends the computed output to receiver.
/// Non-standard tokens (fee-on-transfer, rebasers) are rejected via balance checks.
/// @param payer address of the account that pays for the swap
/// @param receiver address that will receive the output tokens
/// @param inputTokenIndex index of input asset
/// @param outputTokenIndex index of output asset
/// @param maxAmountIn maximum amount of token i (uint256) to transfer in (inclusive of fees)
/// @param limitPrice maximum acceptable marginal price (64.64 fixed point). Pass 0 to ignore.
/// @param deadline timestamp after which the transaction will revert. Pass 0 to ignore.
/// @return amountIn actual input used (uint256), amountOut actual output sent (uint256), fee fee taken from the input (uint256)
/// @inheritdoc IPartyPool
function swap(
address payer,
address receiver,
@@ -195,8 +179,8 @@ contract PartyPool is PoolBase, IPartyPool {
uint256 maxAmountIn,
int128 limitPrice,
uint256 deadline
) external nonReentrant returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
return s.swap(payer, receiver, inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, deadline, swapFeePpm, _stablePair);
) virtual external nonReentrant returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
return s.swap(payer, receiver, inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, deadline, swapFeePpm);
}
/// @notice Swap up to the price limit; computes max input to reach limit then performs swap.

View File

@@ -0,0 +1,42 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.30;
import "./PartyPool.sol";
import {PoolLibBalancedPair} from "./PoolLibBalancedPair.sol";
contract PartyPoolBalancedPair is PartyPool {
constructor(
string memory name_,
string memory symbol_,
IERC20[] memory tokens_,
uint256[] memory bases_,
int128 kappa_,
uint256 swapFeePpm_,
uint256 flashFeePpm_
) PartyPool(name_, symbol_, tokens_, bases_, kappa_, swapFeePpm_, flashFeePpm_) {
}
function swapAmounts(
uint256 inputTokenIndex,
uint256 outputTokenIndex,
uint256 maxAmountIn,
int128 limitPrice
) virtual override external view returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
return PoolLibBalancedPair.swapAmounts(
s, inputTokenIndex, outputTokenIndex,
maxAmountIn, limitPrice, swapFeePpm);
}
function swap(
address payer,
address receiver,
uint256 inputTokenIndex,
uint256 outputTokenIndex,
uint256 maxAmountIn,
int128 limitPrice,
uint256 deadline
) virtual override external nonReentrant returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
return PoolLibBalancedPair.swap(s, payer, receiver, inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, deadline, swapFeePpm);
}
}

View File

@@ -51,7 +51,7 @@ library PoolLib {
/// @param tokens_ Array of token addresses
/// @param bases_ Array of base denominators for each token
function initialize(
State storage state,
PoolLib.State storage state,
IERC20[] memory tokens_,
uint256[] memory bases_
) internal {
@@ -78,7 +78,7 @@ library PoolLib {
/// @notice Get deposit amounts needed for minting LP tokens
function mintDepositAmounts(
State storage state,
PoolLib.State storage state,
uint256 lpTokenAmount,
uint256 totalSupply
) internal view returns (uint256[] memory depositAmounts) {
@@ -102,7 +102,7 @@ library PoolLib {
/// @notice Initial mint to set up pool for the first time
function initialMint(
State storage state,
PoolLib.State storage state,
address receiver,
uint256 lpTokens,
int128 kappa,
@@ -142,7 +142,7 @@ library PoolLib {
/// @notice Proportional mint for existing pool
function mint(
State storage state,
PoolLib.State storage state,
address payer,
address receiver,
uint256 lpTokenAmount,
@@ -209,7 +209,7 @@ library PoolLib {
/// @notice Get withdrawal amounts for burning LP tokens
function burnReceiveAmounts(
State storage state,
PoolLib.State storage state,
uint256 lpTokenAmount,
uint256 totalSupply
) internal view returns (uint256[] memory withdrawAmounts) {
@@ -230,7 +230,7 @@ library PoolLib {
/// @notice Burn LP tokens and withdraw proportional basket
function burn(
State storage state,
PoolLib.State storage state,
address payer,
address receiver,
uint256 lpAmount,
@@ -293,23 +293,22 @@ library PoolLib {
/// @notice Get swap amounts for exact input swap
function swapAmounts(
State storage state,
PoolLib.State storage state,
uint256 inputTokenIndex,
uint256 outputTokenIndex,
uint256 maxAmountIn,
int128 limitPrice,
uint256 swapFeePpm,
bool stablePair
uint256 swapFeePpm
) internal view returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
(uint256 grossIn, uint256 outUint,,,, uint256 feeUint) = _quoteSwapExactIn(
state, inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, swapFeePpm, stablePair
state, inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, swapFeePpm
);
return (grossIn, outUint, feeUint);
}
/// @notice Get swap amounts for swap to price limit
function swapToLimitAmounts(
State storage state,
PoolLib.State storage state,
uint256 inputTokenIndex,
uint256 outputTokenIndex,
int128 limitPrice,
@@ -323,7 +322,7 @@ library PoolLib {
/// @notice Get amounts for swapMint operation
function swapMintAmounts(
State storage state,
PoolLib.State storage state,
uint256 inputTokenIndex,
uint256 maxAmountIn,
uint256 swapFeePpm,
@@ -381,7 +380,7 @@ library PoolLib {
/// @notice Execute exact input swap
function swap(
State storage state,
PoolLib.State storage state,
address payer,
address receiver,
uint256 inputTokenIndex,
@@ -389,8 +388,7 @@ library PoolLib {
uint256 maxAmountIn,
int128 limitPrice,
uint256 deadline,
uint256 swapFeePpm,
bool stablePair
uint256 swapFeePpm
) internal returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
uint256 n = state.tokens.length;
require(inputTokenIndex < n && outputTokenIndex < n, "swap: idx");
@@ -403,7 +401,7 @@ library PoolLib {
// Compute amounts
(uint256 totalTransferAmount, uint256 amountOutUint, int128 amountInInternalUsed, int128 amountOutInternal, , uint256 feeUint) =
_quoteSwapExactIn(state, inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, swapFeePpm, stablePair);
_quoteSwapExactIn(state, inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, swapFeePpm);
// Transfer exact amount from payer
state.tokens[inputTokenIndex].safeTransferFrom(payer, address(this), totalTransferAmount);
@@ -429,7 +427,7 @@ library PoolLib {
/// @notice Execute swap to price limit
function swapToLimit(
State storage state,
PoolLib.State storage state,
address payer,
address receiver,
uint256 inputTokenIndex,
@@ -475,7 +473,7 @@ library PoolLib {
/// @notice Get amounts for burnSwap operation
function burnSwapAmounts(
State storage state,
PoolLib.State storage state,
uint256 lpAmount,
uint256 inputTokenIndex,
uint256 swapFeePpm,
@@ -508,7 +506,7 @@ library PoolLib {
/// @notice Single-token mint (swapMint)
function swapMint(
State storage state,
PoolLib.State storage state,
address payer,
address receiver,
uint256 inputTokenIndex,
@@ -557,7 +555,7 @@ library PoolLib {
/// @notice Burn LP tokens and swap to single asset (burnSwap)
function burnSwap(
State storage state,
PoolLib.State storage state,
address payer,
address receiver,
uint256 lpAmount,
@@ -607,7 +605,7 @@ library PoolLib {
/// @notice Calculate flash loan repayment amounts
function flashRepaymentAmounts(
State storage state,
PoolLib.State storage state,
uint256[] memory loanAmounts,
uint256 flashFeePpm
) internal view returns (uint256[] memory repaymentAmounts) {
@@ -622,7 +620,7 @@ library PoolLib {
/// @notice Execute flash loan
function flash(
State storage state,
PoolLib.State storage state,
address recipient,
uint256[] memory amounts,
bytes calldata data,
@@ -683,7 +681,7 @@ library PoolLib {
/// @notice Get marginal price between two tokens
function price(
State storage state,
PoolLib.State storage state,
uint256 baseTokenIndex,
uint256 quoteTokenIndex
) internal view returns (int128) {
@@ -695,7 +693,7 @@ library PoolLib {
/// @notice Get price of one LP token in quote asset
function poolPrice(
State storage state,
PoolLib.State storage state,
uint256 quoteTokenIndex,
uint256 totalSupply
) internal view returns (int128) {
@@ -747,13 +745,12 @@ library PoolLib {
/// @notice Internal quote for exact-input swap
function _quoteSwapExactIn(
State storage state,
PoolLib.State storage state,
uint256 inputTokenIndex,
uint256 outputTokenIndex,
uint256 maxAmountIn,
int128 limitPrice,
uint256 swapFeePpm,
bool stablePair
uint256 swapFeePpm
)
internal
view
@@ -779,9 +776,64 @@ library PoolLib {
require(deltaInternalI > int128(0), "swap: input too small after fee");
// Compute internal amounts using LMSR
(amountInInternalUsed, amountOutInternal) =
stablePair ? LMSRStabilizedBalancedPair.swapAmountsForExactInput(state.lmsr, inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice)
: state.lmsr.swapAmountsForExactInput(inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice);
(amountInInternalUsed, amountOutInternal) = state.lmsr.swapAmountsForExactInput(
inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice);
// Convert actual used input internal -> uint (ceil)
amountInUintNoFee = _internalToUintCeil(amountInInternalUsed, state.bases[inputTokenIndex]);
require(amountInUintNoFee > 0, "swap: input zero");
// Compute gross transfer including fee
feeUint = 0;
grossIn = amountInUintNoFee;
if (swapFeePpm > 0) {
feeUint = _ceilFee(amountInUintNoFee, swapFeePpm);
grossIn += feeUint;
}
// Ensure within user max
require(grossIn <= maxAmountIn, "swap: transfer exceeds max");
// Compute output (floor)
amountOutUint = _internalToUintFloor(amountOutInternal, state.bases[outputTokenIndex]);
require(amountOutUint > 0, "swap: output zero");
}
/// @notice Internal quote for exact-input swap
function _quoteSwapExactIn_BalancedPair(
PoolLib.State storage state,
uint256 inputTokenIndex,
uint256 outputTokenIndex,
uint256 maxAmountIn,
int128 limitPrice,
uint256 swapFeePpm
)
internal
view
returns (
uint256 grossIn,
uint256 amountOutUint,
int128 amountInInternalUsed,
int128 amountOutInternal,
uint256 amountInUintNoFee,
uint256 feeUint
)
{
uint256 n = state.tokens.length;
require(inputTokenIndex < n && outputTokenIndex < n, "swap: idx");
require(maxAmountIn > 0, "swap: input zero");
require(state.lmsr.nAssets > 0, "swap: empty pool");
// Estimate max net input
(, uint256 netUintForSwap) = _computeFee(maxAmountIn, swapFeePpm);
// Convert to internal (floor)
int128 deltaInternalI = _uintToInternalFloor(netUintForSwap, state.bases[inputTokenIndex]);
require(deltaInternalI > int128(0), "swap: input too small after fee");
// Compute internal amounts using LMSR
(amountInInternalUsed, amountOutInternal) = LMSRStabilizedBalancedPair.swapAmountsForExactInput(
state.lmsr, inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice);
// Convert actual used input internal -> uint (ceil)
amountInUintNoFee = _internalToUintCeil(amountInInternalUsed, state.bases[inputTokenIndex]);
@@ -805,7 +857,7 @@ library PoolLib {
/// @notice Internal quote for swap-to-limit
function _quoteSwapToLimit(
State storage state,
PoolLib.State storage state,
uint256 inputTokenIndex,
uint256 outputTokenIndex,
int128 limitPrice,

139
src/PoolLibBalancedPair.sol Normal file
View File

@@ -0,0 +1,139 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.30;
import "@abdk/ABDKMath64x64.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./LMSRStabilized.sol";
import "./LMSRStabilizedBalancedPair.sol";
import "./IPartyFlashCallback.sol";
import {PoolLib} from "./PoolLib.sol";
/// @title PoolLibBalancedPair - Library with optimized functions for stablecoin pair pools
/// @dev All functions are internal and accept State as the first parameter
library PoolLibBalancedPair {
using ABDKMath64x64 for int128;
using LMSRStabilized for LMSRStabilized.State;
using PoolLib for PoolLib.State;
using SafeERC20 for IERC20;
/// @notice Get swap amounts for exact input swap
function swapAmounts(
PoolLib.State storage state,
uint256 inputTokenIndex,
uint256 outputTokenIndex,
uint256 maxAmountIn,
int128 limitPrice,
uint256 swapFeePpm
) internal view returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
(uint256 grossIn, uint256 outUint,,,, uint256 feeUint) = _quoteSwapExactIn(
state, inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, swapFeePpm
);
return (grossIn, outUint, feeUint);
}
/// @notice Internal quote for exact-input swap
function _quoteSwapExactIn(
PoolLib.State storage state,
uint256 inputTokenIndex,
uint256 outputTokenIndex,
uint256 maxAmountIn,
int128 limitPrice,
uint256 swapFeePpm
)
internal
view
returns (
uint256 grossIn,
uint256 amountOutUint,
int128 amountInInternalUsed,
int128 amountOutInternal,
uint256 amountInUintNoFee,
uint256 feeUint
)
{
uint256 n = state.tokens.length;
require(inputTokenIndex < n && outputTokenIndex < n, "swap: idx");
require(maxAmountIn > 0, "swap: input zero");
require(state.lmsr.nAssets > 0, "swap: empty pool");
// Estimate max net input
(, uint256 netUintForSwap) = PoolLib._computeFee(maxAmountIn, swapFeePpm);
// Convert to internal (floor)
int128 deltaInternalI = PoolLib._uintToInternalFloor(netUintForSwap, state.bases[inputTokenIndex]);
require(deltaInternalI > int128(0), "swap: input too small after fee");
// Compute internal amounts using LMSR
(amountInInternalUsed, amountOutInternal) = LMSRStabilizedBalancedPair.swapAmountsForExactInput(state.lmsr,
inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice);
// Convert actual used input internal -> uint (ceil)
amountInUintNoFee = PoolLib._internalToUintCeil(amountInInternalUsed, state.bases[inputTokenIndex]);
require(amountInUintNoFee > 0, "swap: input zero");
// Compute gross transfer including fee
feeUint = 0;
grossIn = amountInUintNoFee;
if (swapFeePpm > 0) {
feeUint = PoolLib._ceilFee(amountInUintNoFee, swapFeePpm);
grossIn += feeUint;
}
// Ensure within user max
require(grossIn <= maxAmountIn, "swap: transfer exceeds max");
// Compute output (floor)
amountOutUint = PoolLib._internalToUintFloor(amountOutInternal, state.bases[outputTokenIndex]);
require(amountOutUint > 0, "swap: output zero");
}
/// @notice Execute exact input swap
function swap(
PoolLib.State storage state,
address payer,
address receiver,
uint256 inputTokenIndex,
uint256 outputTokenIndex,
uint256 maxAmountIn,
int128 limitPrice,
uint256 deadline,
uint256 swapFeePpm
) internal returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
uint256 n = state.tokens.length;
require(inputTokenIndex < n && outputTokenIndex < n, "swap: idx");
require(maxAmountIn > 0, "swap: input zero");
require(deadline == 0 || block.timestamp <= deadline, "swap: deadline exceeded");
// Read previous balances
uint256 prevBalI = IERC20(state.tokens[inputTokenIndex]).balanceOf(address(this));
uint256 prevBalJ = IERC20(state.tokens[outputTokenIndex]).balanceOf(address(this));
// Compute amounts
(uint256 totalTransferAmount, uint256 amountOutUint, int128 amountInInternalUsed, int128 amountOutInternal, , uint256 feeUint) =
_quoteSwapExactIn(state, inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, swapFeePpm);
// Transfer exact amount from payer
state.tokens[inputTokenIndex].safeTransferFrom(payer, address(this), totalTransferAmount);
uint256 balIAfter = IERC20(state.tokens[inputTokenIndex]).balanceOf(address(this));
require(balIAfter == prevBalI + totalTransferAmount, "swap: non-standard tokenIn");
// Transfer output to receiver
state.tokens[outputTokenIndex].safeTransfer(receiver, amountOutUint);
uint256 balJAfter = IERC20(state.tokens[outputTokenIndex]).balanceOf(address(this));
require(balJAfter == prevBalJ - amountOutUint, "swap: non-standard tokenOut");
// Update cached balances
state.cachedUintBalances[inputTokenIndex] = balIAfter;
state.cachedUintBalances[outputTokenIndex] = balJAfter;
// Apply swap to LMSR state
state.lmsr.applySwap(inputTokenIndex, outputTokenIndex, amountInInternalUsed, amountOutInternal);
emit PoolLib.Swap(payer, receiver, state.tokens[inputTokenIndex], state.tokens[outputTokenIndex], totalTransferAmount, amountOutUint);
return (totalTransferAmount, amountOutUint, feeUint);
}
}

View File

@@ -1,14 +1,15 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.30;
import "forge-std/Test.sol";
import "@abdk/ABDKMath64x64.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "../src/Deploy.sol";
import "../src/IPartyFlashCallback.sol";
import "../src/LMSRStabilized.sol";
import "../src/PartyPool.sol";
import "@abdk/ABDKMath64x64.sol";
// Import the flash callback interface
import "../src/IPartyFlashCallback.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "forge-std/Test.sol";
/// @notice Test contract that implements the flash callback for testing flash loans
contract FlashBorrower is IPartyFlashCallback {
@@ -172,7 +173,7 @@ contract GasTest is Test {
}
// Compute kappa from slippage params and number of tokens, then construct pool with kappa
int128 computedKappa = LMSRStabilized.computeKappaFromSlippage(ierc20Tokens.length, tradeFrac, targetSlippage);
PartyPool newPool = new PartyPool(poolName, poolName, ierc20Tokens, bases, computedKappa, feePpm, feePpm, false);
PartyPool newPool = Deploy.newPartyPool(poolName, poolName, ierc20Tokens, bases, computedKappa, feePpm, feePpm, false);
// Transfer initial deposit amounts into pool before initial mint
for (uint256 i = 0; i < numTokens; i++) {
@@ -212,7 +213,7 @@ contract GasTest is Test {
ierc20Tokens[i] = IERC20(tokens[i]);
}
int128 computedKappa = LMSRStabilized.computeKappaFromSlippage(ierc20Tokens.length, tradeFrac, targetSlippage);
PartyPool newPool = new PartyPool(poolName, poolName, ierc20Tokens, bases, computedKappa, feePpm, feePpm, true);
PartyPool newPool = Deploy.newPartyPool(poolName, poolName, ierc20Tokens, bases, computedKappa, feePpm, feePpm, true);
// Transfer initial deposit amounts into pool before initial mint
for (uint256 i = 0; i < numTokens; i++) {

View File

@@ -1,14 +1,15 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.30;
import "forge-std/Test.sol";
import "@abdk/ABDKMath64x64.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "../src/Deploy.sol";
import "../src/IPartyFlashCallback.sol";
import "../src/LMSRStabilized.sol";
import "../src/PartyPool.sol";
import "@abdk/ABDKMath64x64.sol";
// Import the flash callback interface
import "../src/IPartyFlashCallback.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "forge-std/Test.sol";
/// @notice Test contract that implements the flash callback for testing flash loans
contract FlashBorrower is IPartyFlashCallback {
@@ -197,7 +198,7 @@ contract PartyPoolTest is Test {
uint256 feePpm = 1000;
int128 kappa3 = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage);
pool = new PartyPool("LP", "LP", tokens, bases, kappa3, feePpm, feePpm, false);
pool = Deploy.newPartyPool("LP", "LP", tokens, bases, kappa3, feePpm, feePpm, false);
// Transfer initial deposit amounts into pool before initial mint (pool expects tokens already in contract)
// We deposit equal amounts INIT_BAL for each token
@@ -227,7 +228,7 @@ contract PartyPoolTest is Test {
}
int128 kappa10 = LMSRStabilized.computeKappaFromSlippage(tokens10.length, tradeFrac, targetSlippage);
pool10 = new PartyPool("LP10", "LP10", tokens10, bases10, kappa10, feePpm, feePpm, false);
pool10 = Deploy.newPartyPool("LP10", "LP10", tokens10, bases10, kappa10, feePpm, feePpm, false);
// Mint additional tokens for pool10 initial deposit
token0.mint(address(this), INIT_BAL);
@@ -1231,11 +1232,11 @@ contract PartyPoolTest is Test {
// Pool with default initialization (lpTokens = 0)
int128 kappaDefault = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage);
PartyPool poolDefault = new PartyPool("LP_DEFAULT", "LP_DEFAULT", tokens, bases, kappaDefault, feePpm, feePpm, false);
PartyPool poolDefault = Deploy.newPartyPool("LP_DEFAULT", "LP_DEFAULT", tokens, bases, kappaDefault, feePpm, feePpm, false);
// Pool with custom initialization (lpTokens = custom amount)
int128 kappaCustom = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage);
PartyPool poolCustom = new PartyPool("LP_CUSTOM", "LP_CUSTOM", tokens, bases, kappaCustom, feePpm, feePpm, false);
PartyPool poolCustom = Deploy.newPartyPool("LP_CUSTOM", "LP_CUSTOM", tokens, bases, kappaCustom, feePpm, feePpm, false);
// Mint additional tokens for both pools
token0.mint(address(this), INIT_BAL * 2);
@@ -1307,9 +1308,9 @@ contract PartyPoolTest is Test {
uint256 feePpm = 1000;
int128 kappaDefault2 = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage);
PartyPool poolDefault = new PartyPool("LP_DEFAULT", "LP_DEFAULT", tokens, bases, kappaDefault2, feePpm, feePpm, false);
PartyPool poolDefault = Deploy.newPartyPool("LP_DEFAULT", "LP_DEFAULT", tokens, bases, kappaDefault2, feePpm, feePpm, false);
int128 kappaCustom2 = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage);
PartyPool poolCustom = new PartyPool("LP_CUSTOM", "LP_CUSTOM", tokens, bases, kappaCustom2, feePpm, feePpm, false);
PartyPool poolCustom = Deploy.newPartyPool("LP_CUSTOM", "LP_CUSTOM", tokens, bases, kappaCustom2, feePpm, feePpm, false);
// Mint additional tokens
token0.mint(address(this), INIT_BAL * 4);