diff --git a/script/DeployMock.sol b/script/DeployMock.sol index 48992bb..318cdb5 100644 --- a/script/DeployMock.sol +++ b/script/DeployMock.sol @@ -19,7 +19,7 @@ contract DeployMock is Script { function run() public { vm.startBroadcast(); - // create mock tokens + // create mock _tokens usxd = new MockERC20('Joke Currency', 'USXD', 6); fusd = new MockERC20('Fake USD', 'FUSD', 6); dive = new MockERC20('DAI Virtually Equal', 'DIVE', 18); @@ -41,7 +41,7 @@ contract DeployMock is Script { // deploy a PartyPlanner factory and create the pool via factory PartyPlanner planner = Deploy.newPartyPlanner(); - // prepare initial deposits (10_000 units of each token, scaled by bases) + // prepare initial deposits (10_000 units of each token, scaled by _bases) uint256[] memory initialDeposits = new uint256[](3); initialDeposits[0] = _bases[0] * 10_000; initialDeposits[1] = _bases[1] * 10_000; @@ -49,7 +49,7 @@ contract DeployMock is Script { uint256 initialLpAmount = 0; uint256 deadline = 0; - // mint tokens to the deployer so it can fund the initial deposits and approve the factory + // mint _tokens to the deployer so it can fund the initial deposits and approve the factory mintAll(msg.sender, 10_000); // approve factory to move initial deposits @@ -75,7 +75,7 @@ contract DeployMock is Script { deadline ); - // give tokens to dev7 for later use + // give _tokens to dev7 for later use mintAll(DEV_ACCOUNT_7, 1_000_000); vm.stopBroadcast(); diff --git a/src/ERC20External.sol b/src/ERC20External.sol index 2ed0606..d716dcc 100644 --- a/src/ERC20External.sol +++ b/src/ERC20External.sol @@ -38,7 +38,7 @@ contract ERC20External is ERC20Internal, IERC20Metadata { /** * @dev Returns the number of decimals used to get its user representation. - * For example, if `decimals` equals `2`, a balance of `505` tokens should + * For example, if `decimals` equals `2`, a balance of `505` _tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between @@ -111,7 +111,7 @@ contract ERC20External is ERC20Internal, IERC20Metadata { * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. - * - the caller must have allowance for ``from``'s tokens of at least + * - the caller must have allowance for ``from``'s _tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { diff --git a/src/ERC20Internal.sol b/src/ERC20Internal.sol index a42a488..1bb37d6 100644 --- a/src/ERC20Internal.sol +++ b/src/ERC20Internal.sol @@ -16,7 +16,7 @@ abstract contract ERC20Internal is Context, IERC20Errors { /** - * @dev Moves a `value` amount of tokens from `from` to `to`. + * @dev Moves a `value` amount of _tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. @@ -36,7 +36,7 @@ abstract contract ERC20Internal is Context, IERC20Errors { } /** - * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` + * @dev Transfers a `value` amount of _tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * @@ -73,7 +73,7 @@ abstract contract ERC20Internal is Context, IERC20Errors { } /** - * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). + * @dev Creates a `value` amount of _tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. @@ -88,7 +88,7 @@ abstract contract ERC20Internal is Context, IERC20Errors { } /** - * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. + * @dev Destroys a `value` amount of _tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. @@ -103,7 +103,7 @@ abstract contract ERC20Internal is Context, IERC20Errors { } /** - * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens. + * @dev Sets `value` as the allowance of `spender` over the `owner`'s _tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. diff --git a/src/IPartyPlanner.sol b/src/IPartyPlanner.sol index 96b6510..8bf6d08 100644 --- a/src/IPartyPlanner.sol +++ b/src/IPartyPlanner.sol @@ -17,18 +17,18 @@ interface IPartyPlanner { /// @param name_ LP token name /// @param symbol_ LP token symbol /// @param _tokens token addresses (n) - /// @param _bases scaling bases for each token (n) - used when converting to/from internal 64.64 amounts + /// @param _bases scaling _bases for each token (n) - used when converting to/from internal 64.64 amounts /// @param _tradeFrac trade fraction in 64.64 fixed-point (as used by LMSR) /// @param _targetSlippage target slippage in 64.64 fixed-point (as used by LMSR) /// @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 /// @param payer address that provides the initial token deposits - /// @param receiver address that receives the minted LP tokens + /// @param receiver address that receives the minted LP _tokens /// @param initialDeposits amounts of each token to deposit initially /// @param deadline Reverts if nonzero and the current blocktime is later than the deadline /// @return pool Address of the newly created and initialized PartyPool - /// @return lpAmount Amount of LP tokens minted to the receiver + /// @return lpAmount Amount of LP _tokens minted to the receiver function newPool( // Pool constructor args (legacy) string memory name_, @@ -52,17 +52,17 @@ interface IPartyPlanner { /// @param name_ LP token name /// @param symbol_ LP token symbol /// @param _tokens token addresses (n) - /// @param _bases scaling bases for each token (n) - used when converting to/from internal 64.64 amounts + /// @param _bases scaling _bases for each token (n) - used when converting to/from internal 64.64 amounts /// @param _kappa liquidity parameter κ in 64.64 fixed-point 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 /// @param payer address that provides the initial token deposits - /// @param receiver address that receives the minted LP tokens + /// @param receiver address that receives the minted LP _tokens /// @param initialDeposits amounts of each token to deposit initially /// @param deadline Reverts if nonzero and the current blocktime is later than the deadline /// @return pool Address of the newly created and initialized PartyPool - /// @return lpAmount Amount of LP tokens minted to the receiver + /// @return lpAmount Amount of LP _tokens minted to the receiver function newPool( // Pool constructor args (kappa-based) string memory name_, @@ -96,8 +96,8 @@ interface IPartyPlanner { /// @return pools Array of pool addresses for the requested page function getAllPools(uint256 offset, uint256 limit) external view returns (IPartyPool[] memory pools); - /// @notice Returns the total number of unique tokens - /// @return The total count of unique tokens + /// @notice Returns the total number of unique _tokens + /// @return The total count of unique _tokens function tokenCount() external view returns (uint256); /// @notice Retrieves a page of token addresses diff --git a/src/IPartyPool.sol b/src/IPartyPool.sol index 0b8f356..924fc85 100644 --- a/src/IPartyPool.sol +++ b/src/IPartyPool.sol @@ -11,12 +11,12 @@ import {IERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20 /// @notice A multi-asset liquidity pool backed by the LMSRStabilized pricing model. /// The pool issues an ERC20 LP token representing proportional ownership. /// It supports: -/// - Proportional minting and burning of LP tokens, +/// - Proportional minting and burning of LP _tokens, /// - Single-token mint (swapMint) and single-asset withdrawal (burnSwap), /// - Exact-input swaps and swaps-to-price-limits, /// - Flash loans via a callback interface. /// -/// @dev The contract stores per-token uint "bases" used to scale token units into the internal Q64.64 +/// @dev The contract stores per-token uint "_bases" used to scale token units into the internal Q64.64 /// representation used by the LMSR library. Cached on-chain uint balances are kept to reduce balanceOf calls. /// The contract uses ceiling/floor rules described in function comments to bias rounding in favor of the pool /// (i.e., floor outputs to users, ceil inputs/fees where appropriate). @@ -44,7 +44,7 @@ interface IPartyPool is IERC20Metadata { address indexed payer, address indexed receiver, uint256 indexed inputTokenIndex, - uint256 grossTransfer, // total tokens transferred (net + fee) + uint256 grossTransfer, // total _tokens transferred (net + fee) uint256 netInput, // net input credited to swaps (after fee) uint256 feeTaken // fee taken (ceil) ); @@ -62,10 +62,10 @@ interface IPartyPool is IERC20Metadata { function LMSR() external view returns (LMSRStabilized.State memory); /// @notice Token addresses comprising the pool. Effectively immutable after construction. - /// @dev tokens[i] corresponds to the i-th asset and maps to index i in the internal LMSR arrays. + /// @dev _tokens[i] corresponds to the i-th asset and maps to index i in the internal LMSR arrays. function getToken(uint256) external view returns (IERC20); // get single token - /// @notice Returns the number of tokens (n) in the pool. + /// @notice Returns the number of _tokens (n) in the pool. function numTokens() external view returns (uint256); /// @notice Returns the list of all token addresses in the pool (copy). @@ -75,7 +75,7 @@ interface IPartyPool is IERC20Metadata { function wrapperToken() external view returns (IWETH9); /// @notice Per-token uint base denominators used to convert uint token amounts <-> internal Q64.64 representation. - /// @dev denominators()[i] is the base for tokens[i]. These bases are chosen by deployer and must match token decimals. + /// @dev denominators()[i] is the base for _tokens[i]. These _bases are chosen by deployer and must match token decimals. function denominators() external view returns (uint256[] memory); /// @notice Per-swap fee in parts-per-million (ppm). Fee is taken from input amounts before LMSR computations. @@ -88,10 +88,10 @@ interface IPartyPool is IERC20Metadata { /// @dev This is the fraction (in ppm) of the pool-collected fees that are owed to the protocol. function protocolFeePpm() external view returns (uint256); - /// @notice Address that will receive collected protocol tokens when collectProtocolFees() is called. + /// @notice Address that will receive collected protocol _tokens when collectProtocolFees() is called. function protocolFeeAddress() external view returns (address); - /// @notice Protocol fee ledger accessor. Returns tokens owed (raw uint token units) from this pool as protocol fees + /// @notice Protocol fee ledger accessor. Returns _tokens owed (raw uint token units) from this pool as protocol fees /// that have not yet been transferred out. function allProtocolFeesOwed() external view returns (uint256[] memory); @@ -105,28 +105,28 @@ interface IPartyPool is IERC20Metadata { // Initialization / Mint / Burn (LP token managed) /// @notice Initial mint to set up pool for the first time. - /// @dev Assumes tokens have already been transferred to the pool prior to calling. - /// Can only be called when the pool is uninitialized (totalSupply() == 0 or lmsr.nAssets == 0). - /// @param receiver address that receives the LP tokens - /// @param lpTokens The number of LP tokens to issue for this mint. If 0, then the number of tokens returned will equal the LMSR internal q total + /// @dev Assumes _tokens have already been transferred to the pool prior to calling. + /// Can only be called when the pool is uninitialized (totalSupply() == 0 or _lmsr.nAssets == 0). + /// @param receiver address that receives the LP _tokens + /// @param lpTokens The number of LP _tokens to issue for this mint. If 0, then the number of _tokens returned will equal the LMSR internal q total function initialMint(address receiver, uint256 lpTokens) external payable returns (uint256 lpMinted); /// @notice Proportional mint (or initial supply if first call). - /// @dev - For initial supply: assumes tokens have already been transferred to the pool prior to calling. + /// @dev - For initial supply: assumes _tokens have already been transferred to the pool prior to calling. /// - For subsequent mints: payer must approve the required token amounts before calling. /// Rounds follow the pool-favorable conventions documented in helpers (ceil inputs, floor outputs). - /// @param payer address that provides the input tokens (ignored for initial deposit) - /// @param receiver address that receives the LP tokens - /// @param lpTokenAmount desired amount of LP tokens to mint (ignored for initial deposit) + /// @param payer address that provides the input _tokens (ignored for initial deposit) + /// @param receiver address that receives the LP _tokens + /// @param lpTokenAmount desired amount of LP _tokens to mint (ignored for initial deposit) /// @param deadline timestamp after which the transaction will revert. Pass 0 to ignore. /// @return lpMinted the actual amount of lpToken minted function mint(address payer, address receiver, uint256 lpTokenAmount, uint256 deadline) external payable returns (uint256 lpMinted); - /// @notice Burn LP tokens and withdraw the proportional basket to receiver. + /// @notice Burn LP _tokens and withdraw the proportional basket to receiver. /// @dev This function forwards the call to the burn implementation via delegatecall - /// @param payer address that provides the LP tokens to burn - /// @param receiver address that receives the withdrawn tokens - /// @param lpAmount amount of LP tokens to burn (proportional withdrawal) + /// @param payer address that provides the LP _tokens to burn + /// @param receiver address that receives the withdrawn _tokens + /// @param lpAmount amount of LP _tokens to burn (proportional withdrawal) /// @param deadline timestamp after which the transaction will revert. Pass 0 to ignore. /// @param unwrap if true and the native token is being withdrawn, it is unwraped and sent as native currency function burn(address payer, address receiver, uint256 lpAmount, uint256 deadline, bool unwrap) external returns (uint256[] memory withdrawAmounts); @@ -149,9 +149,9 @@ interface IPartyPool is IERC20Metadata { /// @notice Swap input token inputTokenIndex -> token outputTokenIndex. Payer must approve token inputTokenIndex. /// @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. + /// 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 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 inputTokenIndex (uint256) to transfer in (inclusive of fees) @@ -173,7 +173,7 @@ interface IPartyPool is IERC20Metadata { /// @dev If balances prevent fully reaching the limit, the function caps and returns actuals. /// The payer must transfer the exact gross input computed by the view. /// @param payer address of the account that pays for the swap - /// @param receiver address that will receive the output tokens + /// @param receiver address that will receive the output _tokens /// @param inputTokenIndex index of input asset /// @param outputTokenIndex index of output asset /// @param limitPrice target marginal price to reach (must be > 0) @@ -193,7 +193,7 @@ interface IPartyPool is IERC20Metadata { /// @dev swapMint executes as an exact-in planned swap followed by proportional scaling of qInternal. /// The function emits SwapMint (gross, net, fee) and also emits Mint for LP issuance. /// @param payer who transfers the input token - /// @param receiver who receives the minted LP tokens + /// @param receiver who receives the minted LP _tokens /// @param inputTokenIndex index of the input token /// @param maxAmountIn maximum uint token input (inclusive of fee) /// @param deadline optional deadline @@ -206,11 +206,11 @@ interface IPartyPool is IERC20Metadata { uint256 deadline ) external payable returns (uint256 lpMinted); - /// @notice Burn LP tokens then swap the redeemed proportional basket into a single asset `inputTokenIndex` and send to receiver. - /// @dev The function burns LP tokens (authorization via allowance if needed), sends the single-asset payout and updates LMSR state. - /// @param payer who burns LP tokens + /// @notice Burn LP _tokens then swap the redeemed proportional basket into a single asset `inputTokenIndex` and send to receiver. + /// @dev The function burns LP _tokens (authorization via allowance if needed), sends the single-asset payout and updates LMSR state. + /// @param payer who burns LP _tokens /// @param receiver who receives the single asset - /// @param lpAmount amount of LP tokens to burn + /// @param lpAmount amount of LP _tokens to burn /// @param inputTokenIndex index of target asset to receive /// @param deadline optional deadline /// @return amountOutUint uint amount of asset inputTokenIndex sent to receiver @@ -225,9 +225,9 @@ interface IPartyPool is IERC20Metadata { /** * @dev Initiate a flash loan. - * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. + * @param receiver The receiver of the _tokens in the loan, and the receiver of the callback. * @param token The loan currency. - * @param amount The amount of tokens lent. + * @param amount The amount of _tokens lent. * @param data Arbitrary data structure, intended to contain user-defined parameters. */ function flashLoan( diff --git a/src/IPartyPoolViewer.sol b/src/IPartyPoolViewer.sol index 2935c6d..8a3be17 100644 --- a/src/IPartyPoolViewer.sol +++ b/src/IPartyPoolViewer.sol @@ -22,9 +22,9 @@ interface IPartyPoolViewer { /// @notice Calculate the proportional deposit amounts required for a given LP token amount /// @dev Returns the minimum token amounts (rounded up) that must be supplied to receive lpTokenAmount - /// LP tokens at current pool proportions. If the pool is empty (initial deposit) returns zeros - /// because the initial deposit is handled by transferring tokens then calling mint(). - /// @param lpTokenAmount The amount of LP tokens desired + /// LP _tokens at current pool proportions. If the pool is empty (initial deposit) returns zeros + /// because the initial deposit is handled by transferring _tokens then calling mint(). + /// @param lpTokenAmount The amount of LP _tokens desired /// @return depositAmounts Array of token amounts to deposit (rounded up) function mintAmounts(IPartyPool pool, uint256 lpTokenAmount) external view returns (uint256[] memory depositAmounts); @@ -51,7 +51,7 @@ interface IPartyPoolViewer { /// @notice Calculate the amounts for a burn swap operation /// @dev This is a pure view function that computes burn swap amounts from provided state - /// @param lpAmount amount of LP tokens to burn + /// @param lpAmount amount of LP _tokens to burn /// @param inputTokenIndex index of target asset to receive function burnSwapAmounts(IPartyPool pool, uint256 lpAmount, uint256 inputTokenIndex) external view returns (uint256 amountOut); @@ -71,7 +71,7 @@ interface IPartyPoolViewer { /** * @dev The fee to be charged for a given loan. - * @param amount The amount of tokens lent. + * @param amount The amount of _tokens lent. * @return fee The amount of `token` to be charged for the loan, on top of the returned principal. */ function flashFee(IPartyPool pool, address token, uint256 amount) external view returns (uint256 fee); diff --git a/src/PartyPlanner.sol b/src/PartyPlanner.sol index d77a034..424b0e1 100644 --- a/src/PartyPlanner.sol +++ b/src/PartyPlanner.sol @@ -119,7 +119,7 @@ contract PartyPlanner is IPartyPlanner { _allPools.push(pool); _poolSupported[pool] = true; - // Track tokens and populate mappings + // Track _tokens and populate mappings for (uint256 i = 0; i < _tokens.length; i++) { IERC20 token = _tokens[i]; @@ -135,7 +135,7 @@ contract PartyPlanner is IPartyPlanner { emit PartyStarted(pool, name_, symbol_, _tokens); - // Transfer initial tokens from payer to the pool + // Transfer initial _tokens from payer to the pool for (uint256 i = 0; i < _tokens.length; i++) { if (initialDeposits[i] > 0) { IERC20(_tokens[i]).safeTransferFrom(payer, address(pool), initialDeposits[i]); @@ -143,7 +143,7 @@ contract PartyPlanner is IPartyPlanner { } } - // Call mint on the new pool to initialize it with the transferred tokens + // Call mint on the new pool to initialize it with the transferred _tokens lpAmount = pool.initialMint(receiver, initialLpAmount); } @@ -240,7 +240,7 @@ contract PartyPlanner is IPartyPlanner { return new address[](0); } - // Calculate actual number of tokens to return (respecting bounds) + // Calculate actual number of _tokens to return (respecting bounds) uint256 itemsToReturn = (offset + limit > totalTokens) ? (totalTokens - offset) : limit; // Create result array of appropriate size diff --git a/src/PartyPool.sol b/src/PartyPool.sol index 431a0d9..a5b07ba 100644 --- a/src/PartyPool.sol +++ b/src/PartyPool.sol @@ -23,12 +23,12 @@ import {IWETH9} from "./IWETH9.sol"; /// @notice A multi-asset liquidity pool backed by the LMSRStabilized pricing model. /// The pool issues an ERC20 LP token representing proportional ownership. /// It supports: -/// - Proportional minting and burning of LP tokens, +/// - Proportional minting and burning of LP _tokens, /// - Single-token mint (swapMint) and single-asset withdrawal (burnSwap), /// - Exact-input swaps and swaps-to-price-limits, /// - Flash loans via a callback interface. /// -/// @dev The contract stores per-token uint "bases" used to scale token units into the internal Q64.64 +/// @dev The contract stores per-token uint "_bases" used to scale token units into the internal Q64.64 /// representation used by the LMSR library. Cached on-chain uint balances are kept to reduce balanceOf calls. /// The contract uses ceiling/floor rules described in function comments to bias rounding in favor of the pool /// (i.e., floor outputs to users, ceil inputs/fees where appropriate). @@ -59,12 +59,12 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { uint256 private immutable PROTOCOL_FEE_PPM; function protocolFeePpm() external view returns (uint256) { return PROTOCOL_FEE_PPM; } - /// @notice Address to which collected protocol tokens will be sent on collectProtocolFees() + /// @notice Address to which collected protocol _tokens will be sent on collectProtocolFees() address private immutable PROTOCOL_FEE_ADDRESS; function protocolFeeAddress() external view returns (address) { return PROTOCOL_FEE_ADDRESS; } // @inheritdoc IPartyPool - function allProtocolFeesOwed() external view returns (uint256[] memory) { return protocolFeesOwed; } + function allProtocolFeesOwed() external view returns (uint256[] memory) { return _protocolFeesOwed; } /// @notice Address of the Mint implementation contract for delegatecall PartyPoolMintImpl private immutable MINT_IMPL; @@ -76,24 +76,24 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { /// @inheritdoc IPartyPool - function getToken(uint256 i) external view returns (IERC20) { return tokens[i]; } + function getToken(uint256 i) external view returns (IERC20) { return _tokens[i]; } /// @inheritdoc IPartyPool - function numTokens() external view returns (uint256) { return tokens.length; } + function numTokens() external view returns (uint256) { return _tokens.length; } /// @inheritdoc IPartyPool - function allTokens() external view returns (IERC20[] memory) { return tokens; } + function allTokens() external view returns (IERC20[] memory) { return _tokens; } /// @inheritdoc IPartyPool - function denominators() external view returns (uint256[] memory) { return bases; } + function denominators() external view returns (uint256[] memory) { return _bases; } - function LMSR() external view returns (LMSRStabilized.State memory) { return lmsr; } + function LMSR() external view returns (LMSRStabilized.State memory) { return _lmsr; } /// @param name_ LP token name /// @param symbol_ LP token symbol /// @param tokens_ token addresses (n) - /// @param bases_ scaling bases for each token (n) - used when converting to/from internal 64.64 amounts + /// @param bases_ scaling _bases for each token (n) - used when converting to/from internal 64.64 amounts /// @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 @@ -107,8 +107,8 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { int128 kappa_, uint256 swapFeePpm_, uint256 flashFeePpm_, - uint256 protocolFeePpm_, // NEW: protocol share of fees (ppm) - address protocolFeeAddress_, // NEW: recipient for collected protocol tokens + uint256 protocolFeePpm_, + address protocolFeeAddress_, IWETH9 wrapperToken_, PartyPoolSwapImpl swapImpl_, PartyPoolMintImpl mintImpl_ @@ -118,14 +118,16 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { { require(tokens_.length > 1, "Pool: need >1 asset"); require(tokens_.length == bases_.length, "Pool: lengths mismatch"); - tokens = tokens_; - bases = bases_; + _tokens = tokens_; + _bases = bases_; KAPPA = kappa_; require(swapFeePpm_ < 1_000_000, "Pool: fee >= ppm"); SWAP_FEE_PPM = swapFeePpm_; require(flashFeePpm_ < 1_000_000, "Pool: flash fee >= ppm"); FLASH_FEE_PPM = flashFeePpm_; require(protocolFeePpm_ < 1_000_000, "Pool: protocol fee >= ppm"); + // If the protocolFeePpm_ is set, then also require the fee address to be nonzero + require(protocolFeePpm_ == 0 || protocolFeeAddress_ != address(0)); PROTOCOL_FEE_PPM = protocolFeePpm_; PROTOCOL_FEE_ADDRESS = protocolFeeAddress_; SWAP_IMPL = swapImpl_; @@ -134,17 +136,17 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { uint256 n = tokens_.length; // Initialize LMSR state nAssets; full init occurs on first mint when quantities are known. - lmsr.nAssets = n; + _lmsr.nAssets = n; // Initialize token address to index mapping for (uint i = 0; i < n;) { - tokenAddressToIndexPlusOne[tokens_[i]] = i + 1; + _tokenAddressToIndexPlusOne[tokens_[i]] = i + 1; unchecked {i++;} } // Initialize caches to zero and protocol ledger - cachedUintBalances = new uint256[](n); - protocolFeesOwed = new uint256[](n); + _cachedUintBalances = new uint256[](n); + _protocolFeesOwed = new uint256[](n); } @@ -167,9 +169,9 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { /// @notice Proportional mint for existing pool. /// @dev This function forwards the call to the mint implementation via delegatecall - /// @param payer address that provides the input tokens - /// @param receiver address that receives the LP tokens - /// @param lpTokenAmount desired amount of LP tokens to mint + /// @param payer address that provides the input _tokens + /// @param receiver address that receives the LP _tokens + /// @param lpTokenAmount desired amount of LP _tokens to mint /// @param deadline timestamp after which the transaction will revert. Pass 0 to ignore. function mint(address payer, address receiver, uint256 lpTokenAmount, uint256 deadline) external payable returns (uint256 lpMinted) { @@ -231,36 +233,36 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { _quoteSwapExactIn(inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice); // Cache token references for fewer SLOADs - IERC20 tokenIn = tokens[inputTokenIndex]; - IERC20 tokenOut = tokens[outputTokenIndex]; + IERC20 tokenIn = _tokens[inputTokenIndex]; + IERC20 tokenOut = _tokens[outputTokenIndex]; - // Transfer tokens in via centralized helper + // Transfer _tokens in via centralized helper _receiveTokenFrom(payer, tokenIn, totalTransferAmount); // Compute on-chain balances as: onchain = cached + owed (+/- transfer) - uint256 balIAfter = cachedUintBalances[inputTokenIndex] + protocolFeesOwed[inputTokenIndex] + totalTransferAmount; - uint256 balJAfter = cachedUintBalances[outputTokenIndex] + protocolFeesOwed[outputTokenIndex] - amountOutUint; - - // Transfer output to receiver via centralized helper - _sendTokenTo(tokenOut, receiver, amountOutUint, unwrap); + uint256 balIAfter = _cachedUintBalances[inputTokenIndex] + _protocolFeesOwed[inputTokenIndex] + totalTransferAmount; + uint256 balJAfter = _cachedUintBalances[outputTokenIndex] + _protocolFeesOwed[outputTokenIndex] - amountOutUint; // Accrue protocol share (floor) from the fee on input token if (PROTOCOL_FEE_PPM > 0 && feeUint > 0) { uint256 protoShare = (feeUint * PROTOCOL_FEE_PPM) / 1_000_000; // floor if (protoShare > 0) { - protocolFeesOwed[inputTokenIndex] += protoShare; + _protocolFeesOwed[inputTokenIndex] += protoShare; } } // Inline _recordCachedBalance: ensure onchain >= owed then set cached = onchain - owed - require(balIAfter >= protocolFeesOwed[inputTokenIndex], "balance < protocol owed"); - cachedUintBalances[inputTokenIndex] = balIAfter - protocolFeesOwed[inputTokenIndex]; + require(balIAfter >= _protocolFeesOwed[inputTokenIndex], "balance < protocol owed"); + _cachedUintBalances[inputTokenIndex] = balIAfter - _protocolFeesOwed[inputTokenIndex]; - require(balJAfter >= protocolFeesOwed[outputTokenIndex], "balance < protocol owed"); - cachedUintBalances[outputTokenIndex] = balJAfter - protocolFeesOwed[outputTokenIndex]; + require(balJAfter >= _protocolFeesOwed[outputTokenIndex], "balance < protocol owed"); + _cachedUintBalances[outputTokenIndex] = balJAfter - _protocolFeesOwed[outputTokenIndex]; // Apply swap to LMSR state with the internal amounts actually used - lmsr.applySwap(inputTokenIndex, outputTokenIndex, amountInInternalUsed, amountOutInternal); + _lmsr.applySwap(inputTokenIndex, outputTokenIndex, amountInInternalUsed, amountOutInternal); + + // Transfer output to receiver near the end + _sendTokenTo(tokenOut, receiver, amountOutUint, unwrap); emit Swap(payer, receiver, tokenIn, tokenOut, totalTransferAmount, amountOutUint); @@ -289,13 +291,13 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { uint256 feeUint ) { - uint256 n = tokens.length; + uint256 n = _tokens.length; // Estimate max net input (fee on gross rounded up, then subtract) (, uint256 netUintForSwap) = _computeFee(maxAmountIn, SWAP_FEE_PPM); // Convert to internal (floor) - int128 deltaInternalI = _uintToInternalFloor(netUintForSwap, bases[inputTokenIndex]); + int128 deltaInternalI = _uintToInternalFloor(netUintForSwap, _bases[inputTokenIndex]); require(deltaInternalI > int128(0), "swap: input too small after fee"); // Compute internal amounts using LMSR (exact-input with price limit) @@ -303,7 +305,7 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { (amountInInternalUsed, amountOutInternal) = _swapAmountsForExactInput(inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice); // Convert actual used input internal -> uint (ceil) - amountInUintNoFee = _internalToUintCeil(amountInInternalUsed, bases[inputTokenIndex]); + amountInUintNoFee = _internalToUintCeil(amountInInternalUsed, _bases[inputTokenIndex]); // Compute gross transfer including fee on the used input (ceil) feeUint = 0; @@ -317,7 +319,7 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { require(grossIn <= maxAmountIn, "swap: transfer exceeds max"); // Compute output (floor) - amountOutUint = _internalToUintFloor(amountOutInternal, bases[outputTokenIndex]); + amountOutUint = _internalToUintFloor(amountOutInternal, _bases[outputTokenIndex]); } @@ -351,7 +353,7 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { /// @notice Single-token mint: deposit a single token, charge swap-LMSR cost, and mint LP. /// @dev This function forwards the call to the swapMint implementation via delegatecall /// @param payer who transfers the input token - /// @param receiver who receives the minted LP tokens + /// @param receiver who receives the minted LP _tokens /// @param inputTokenIndex index of the input token /// @param maxAmountIn maximum uint token input (inclusive of fee) /// @param deadline optional deadline @@ -378,11 +380,11 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { return abi.decode(result, (uint256)); } - /// @notice Burn LP tokens then swap the redeemed proportional basket into a single asset `inputTokenIndex` and send to receiver. + /// @notice Burn LP _tokens then swap the redeemed proportional basket into a single asset `inputTokenIndex` and send to receiver. /// @dev This function forwards the call to the burnSwap implementation via delegatecall - /// @param payer who burns LP tokens + /// @param payer who burns LP _tokens /// @param receiver who receives the single asset - /// @param lpAmount amount of LP tokens to burn + /// @param lpAmount amount of LP _tokens to burn /// @param inputTokenIndex index of target asset to receive /// @param deadline optional deadline /// @return amountOutUint uint amount of asset i sent to receiver @@ -414,10 +416,10 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { bytes32 internal constant FLASH_CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan"); /** - * @dev Loan `amount` tokens to `receiver`, and takes it back plus a `flashFee` after the callback. - * @param receiver The contract receiving the tokens, needs to implement the `onFlashLoan(address user, uint256 amount, uint256 fee, bytes calldata)` interface. + * @dev Loan `amount` _tokens to `receiver`, and takes it back plus a `flashFee` after the callback. + * @param receiver The contract receiving the _tokens, needs to implement the `onFlashLoan(address user, uint256 amount, uint256 fee, bytes calldata)` interface. * @param tokenAddr The loan currency. - * @param amount The amount of tokens lent. + * @param amount The amount of _tokens lent. * @param data A data parameter to be passed on to the `receiver` for any custom use. */ function flashLoan( @@ -429,26 +431,28 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { { IERC20 token = IERC20(tokenAddr); require(amount <= token.balanceOf(address(this))); - uint256 tokenIndex = tokenAddressToIndexPlusOne[token] - 1; + uint256 tokenIndex = _tokenAddressToIndexPlusOne[token]; + require(tokenIndex != 0, 'flash: token not in pool'); + tokenIndex -= 1; (uint256 fee, ) = _computeFee(amount, FLASH_FEE_PPM); // Compute protocol share of flash fee if (PROTOCOL_FEE_PPM > 0 && fee > 0) { uint256 protoShare = (fee * PROTOCOL_FEE_PPM) / 1_000_000; // floor if (protoShare > 0) { - protocolFeesOwed[tokenIndex] += protoShare; + _protocolFeesOwed[tokenIndex] += protoShare; } } _sendTokenTo(token, address(receiver), amount, false); - require(receiver.onFlashLoan(msg.sender, address(token), amount, fee, data) == FLASH_CALLBACK_SUCCESS); + require(receiver.onFlashLoan(address(receiver), address(token), amount, fee, data) == FLASH_CALLBACK_SUCCESS); _receiveTokenFrom(address(receiver), token, amount + fee); // Update cached balance for the borrowed token uint256 balAfter = token.balanceOf(address(this)); // Inline _recordCachedBalance logic - require(balAfter >= protocolFeesOwed[tokenIndex], "balance < protocol owed"); - cachedUintBalances[tokenIndex] = balAfter - protocolFeesOwed[tokenIndex]; + require(balAfter >= _protocolFeesOwed[tokenIndex], "balance < protocol owed"); + _cachedUintBalances[tokenIndex] = balAfter - _protocolFeesOwed[tokenIndex]; return true; } @@ -460,23 +464,23 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { address dest = PROTOCOL_FEE_ADDRESS; require(dest != address(0), "collect: zero addr"); - uint256 n = tokens.length; + uint256 n = _tokens.length; for (uint256 i = 0; i < n; i++) { - uint256 owed = protocolFeesOwed[i]; + uint256 owed = _protocolFeesOwed[i]; if (owed == 0) continue; - uint256 bal = IERC20(tokens[i]).balanceOf(address(this)); + uint256 bal = IERC20(_tokens[i]).balanceOf(address(this)); require(bal >= owed, "collect: fee > bal"); - protocolFeesOwed[i] = 0; - // transfer owed tokens to protocol destination via centralized helper - _sendTokenTo(tokens[i], dest, owed, false); + _protocolFeesOwed[i] = 0; // update cached to effective onchain minus owed - cachedUintBalances[i] = bal - owed; + _cachedUintBalances[i] = bal - owed; + // transfer owed _tokens to protocol destination via centralized helper + _sendTokenTo(_tokens[i], dest, owed, false); } } function _swapAmountsForExactInput(uint256 i, uint256 j, int128 a, int128 limitPrice) internal virtual view returns (int128 amountIn, int128 amountOut) { - return lmsr.swapAmountsForExactInput(i, j, a, limitPrice); + return _lmsr.swapAmountsForExactInput(i, j, a, limitPrice); } } diff --git a/src/PartyPoolBalancedPair.sol b/src/PartyPoolBalancedPair.sol index 256ab38..6f92b5f 100644 --- a/src/PartyPoolBalancedPair.sol +++ b/src/PartyPoolBalancedPair.sol @@ -28,6 +28,6 @@ contract PartyPoolBalancedPair is PartyPool { function _swapAmountsForExactInput(uint256 i, uint256 j, int128 a, int128 limitPrice) internal virtual override view returns (int128 amountIn, int128 amountOut) { - return LMSRStabilizedBalancedPair.swapAmountsForExactInput(lmsr, i, j, a, limitPrice); + return LMSRStabilizedBalancedPair.swapAmountsForExactInput(_lmsr, i, j, a, limitPrice); } } diff --git a/src/PartyPoolBase.sol b/src/PartyPoolBase.sol index 3fc7ffb..3284734 100644 --- a/src/PartyPoolBase.sol +++ b/src/PartyPoolBase.sol @@ -37,31 +37,31 @@ abstract contract PartyPoolBase is ERC20Internal, ReentrancyGuard, PartyPoolHelp // // LMSR internal state - LMSRStabilized.State internal lmsr; + LMSRStabilized.State internal _lmsr; /// @notice Scale factor used when converting LMSR Q64.64 totals to LP token units (uint). - /// @dev LP tokens are minted in units equal to ABDK.mulu(lastTotalQ64x64, LP_SCALE). + /// @dev LP _tokens are minted in units equal to ABDK.mulu(lastTotalQ64x64, LP_SCALE). uint256 internal constant LP_SCALE = 1e18; // Scale used to convert LMSR lastTotal (Q64.64) into LP token units (uint) /// @notice Token addresses comprising the pool. Effectively immutable after construction. - /// @dev tokens[i] corresponds to the i-th asset and maps to index i in the internal LMSR arrays. - IERC20[] internal tokens; // effectively immutable since there is no interface to change the tokens + /// @dev _tokens[i] corresponds to the i-th asset and maps to index i in the internal LMSR arrays. + IERC20[] internal _tokens; // effectively immutable since there is no interface to change the _tokens /// @notice Amounts of token owed as protocol fees but not yet collected. Subtract this amount from the pool's token - /// balances to compute the tokens owned by LP's. - uint256[] internal protocolFeesOwed; + /// balances to compute the _tokens owned by LP's. + uint256[] internal _protocolFeesOwed; /// @notice Per-token uint base denominators used to convert uint token amounts <-> internal Q64.64 representation. - /// @dev denominators()[i] is the base for tokens[i]. These bases are chosen by deployer and must match token decimals. - uint256[] internal bases; // per-token uint base used to scale token amounts <-> internal + /// @dev denominators()[i] is the base for _tokens[i]. These _bases are chosen by deployer and must match token decimals. + uint256[] internal _bases; // per-token uint base used to scale token amounts <-> internal /// @notice Mapping from token address => (index+1). A zero value indicates the token is not in the pool. - /// @dev Use index = tokenAddressToIndexPlusOne[token] - 1 when non-zero. - mapping(IERC20=>uint) internal tokenAddressToIndexPlusOne; // Uses index+1 so a result of 0 indicates a failed lookup + /// @dev Use index = _tokenAddressToIndexPlusOne[token] - 1 when non-zero. + mapping(IERC20=>uint) internal _tokenAddressToIndexPlusOne; // Uses index+1 so a result of 0 indicates a failed lookup // Cached on-chain balances (uint) and internal 64.64 representation // balance / base = internal - uint256[] internal cachedUintBalances; + uint256[] internal _cachedUintBalances; /* ---------------------- @@ -100,9 +100,9 @@ abstract contract PartyPoolBase is ERC20Internal, ReentrancyGuard, PartyPoolHelp Token transfer helpers (includes autowrap) ---------------------- */ - /// @notice Receive tokens from `payer` into the pool (address(this)) using SafeERC20 semantics. + /// @notice Receive _tokens from `payer` into the pool (address(this)) using SafeERC20 semantics. /// @dev Note: this helper does NOT query the on-chain balance after transfer to save gas. - /// Callers should query the balance themselves when they need it (e.g., to detect fee-on-transfer tokens). + /// Callers should query the balance themselves when they need it (e.g., to detect fee-on-transfer _tokens). function _receiveTokenFrom(address payer, IERC20 token, uint256 amount) internal { if( token == WRAPPER_TOKEN && msg.value >= amount ) WRAPPER_TOKEN.deposit{value:amount}(); @@ -110,9 +110,9 @@ abstract contract PartyPoolBase is ERC20Internal, ReentrancyGuard, PartyPoolHelp token.safeTransferFrom(payer, address(this), amount); } - /// @notice Send tokens from the pool to `receiver` using SafeERC20 semantics. + /// @notice Send _tokens from the pool to `receiver` using SafeERC20 semantics. /// @dev Note: this helper does NOT query the on-chain balance after transfer to save gas. - /// Callers should query the balance themselves when they need it (e.g., to detect fee-on-transfer tokens). + /// Callers should query the balance themselves when they need it (e.g., to detect fee-on-transfer _tokens). function _sendTokenTo(IERC20 token, address receiver, uint256 amount, bool unwrap) internal { if( unwrap && token == WRAPPER_TOKEN ) { WRAPPER_TOKEN.withdraw(amount); diff --git a/src/PartyPoolHelpers.sol b/src/PartyPoolHelpers.sol index dafecf8..337ec1c 100644 --- a/src/PartyPoolHelpers.sol +++ b/src/PartyPoolHelpers.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.30; import {ABDKMath64x64} from "../lib/abdk-libraries-solidity/ABDKMath64x64.sol"; - abstract contract PartyPoolHelpers { using ABDKMath64x64 for int128; @@ -27,21 +26,12 @@ abstract contract PartyPoolHelpers { netUint = gross - feeUint; } - /// @notice Convenience: return gross = net + fee(net) using ceiling for fee. - /// @param netUint net amount - /// @param feePpm fee in ppm to apply - function _addFee(uint256 netUint, uint256 feePpm) internal pure returns (uint256 gross) { - if (feePpm == 0) return netUint; - uint256 fee = _ceilFee(netUint, feePpm); - return netUint + fee; - } - /// @notice Helper to compute size metric (sum of all asset quantities) from internal balances - /// @dev Returns the sum of all provided qInternal_ entries as a Q64.64 value. - function _computeSizeMetric(int128[] memory qInternal_) internal pure returns (int128) { + /// @dev Returns the sum of all provided qInternal entries as a Q64.64 value. + function _computeSizeMetric(int128[] memory qInternal) internal pure returns (int128) { int128 total = int128(0); - for (uint i = 0; i < qInternal_.length; ) { - total = total.add(qInternal_[i]); + for (uint i = 0; i < qInternal.length; ) { + total = total.add(qInternal[i]); unchecked { i++; } } return total; diff --git a/src/PartyPoolMintImpl.sol b/src/PartyPoolMintImpl.sol index 1ff3310..2571ddc 100644 --- a/src/PartyPoolMintImpl.sol +++ b/src/PartyPoolMintImpl.sol @@ -27,27 +27,27 @@ contract PartyPoolMintImpl is PartyPoolBase { function initialMint(address receiver, uint256 lpTokens, int128 KAPPA) external payable native nonReentrant returns (uint256 lpMinted) { - uint256 n = tokens.length; + uint256 n = _tokens.length; // Check if this is initial deposit - revert if not - bool isInitialDeposit = _totalSupply == 0 || lmsr.nAssets == 0; + bool isInitialDeposit = _totalSupply == 0 || _lmsr.nAssets == 0; require(isInitialDeposit, "initialMint: pool already initialized"); // Update cached balances for all assets int128[] memory newQInternal = new int128[](n); uint256[] memory depositAmounts = new uint256[](n); for (uint i = 0; i < n; ) { - uint256 bal = IERC20(tokens[i]).balanceOf(address(this)); - cachedUintBalances[i] = bal; - newQInternal[i] = _uintToInternalFloor(bal, bases[i]); + uint256 bal = IERC20(_tokens[i]).balanceOf(address(this)); + _cachedUintBalances[i] = bal; + newQInternal[i] = _uintToInternalFloor(bal, _bases[i]); depositAmounts[i] = bal; unchecked { i++; } } // Initialize the stabilized LMSR state with provided kappa - lmsr.init(newQInternal, KAPPA); + _lmsr.init(newQInternal, KAPPA); - // Compute actual LP tokens to mint based on size metric (scaled) + // Compute actual LP _tokens to mint based on size metric (scaled) if( lpTokens != 0 ) lpMinted = lpTokens; else { @@ -68,24 +68,24 @@ contract PartyPoolMintImpl is PartyPoolBase { function mint(address payer, address receiver, uint256 lpTokenAmount, uint256 deadline) external payable native nonReentrant returns (uint256 lpMinted) { require(deadline == 0 || block.timestamp <= deadline, "mint: deadline exceeded"); - uint256 n = tokens.length; + uint256 n = _tokens.length; // Check if this is NOT initial deposit - revert if it is - bool isInitialDeposit = _totalSupply == 0 || lmsr.nAssets == 0; + bool isInitialDeposit = _totalSupply == 0 || _lmsr.nAssets == 0; require(!isInitialDeposit, "mint: use initialMint for pool initialization"); require(lpTokenAmount > 0, "mint: zero LP amount"); // Capture old pool size metric (scaled) by computing from current balances - int128 oldTotal = _computeSizeMetric(lmsr.qInternal); + int128 oldTotal = _computeSizeMetric(_lmsr.qInternal); uint256 oldScaled = ABDKMath64x64.mulu(oldTotal, LP_SCALE); - // Calculate required deposit amounts for the desired LP tokens - uint256[] memory depositAmounts = mintAmounts(lpTokenAmount, lmsr.nAssets, _totalSupply, cachedUintBalances); + // Calculate required deposit amounts for the desired LP _tokens + uint256[] memory depositAmounts = mintAmounts(lpTokenAmount, _lmsr.nAssets, _totalSupply, _cachedUintBalances); // Transfer in all token amounts for (uint i = 0; i < n; ) { if (depositAmounts[i] > 0) { - _receiveTokenFrom(payer, tokens[i], depositAmounts[i]); + _receiveTokenFrom(payer, _tokens[i], depositAmounts[i]); } unchecked { i++; } } @@ -93,16 +93,16 @@ contract PartyPoolMintImpl is PartyPoolBase { // Update cached balances and internal q for all assets using depositAmounts int128[] memory newQInternal = new int128[](n); for (uint i = 0; i < n; ) { - uint256 newBal = cachedUintBalances[i] + depositAmounts[i]; - cachedUintBalances[i] = newBal; - newQInternal[i] = _uintToInternalFloor(newBal, bases[i]); + uint256 newBal = _cachedUintBalances[i] + depositAmounts[i]; + _cachedUintBalances[i] = newBal; + newQInternal[i] = _uintToInternalFloor(newBal, _bases[i]); unchecked { i++; } } // Update for proportional change - lmsr.updateForProportionalChange(newQInternal); + _lmsr.updateForProportionalChange(newQInternal); - // Compute actual LP tokens to mint based on change in size metric (scaled) + // Compute actual LP _tokens to mint based on change in size metric (scaled) // floor truncation rounds in favor of the pool int128 newTotal = _computeSizeMetric(newQInternal); uint256 newScaled = ABDKMath64x64.mulu(newTotal, LP_SCALE); @@ -131,18 +131,18 @@ contract PartyPoolMintImpl is PartyPoolBase { return actualLpToMint; } - /// @notice Burn LP tokens and withdraw the proportional basket to receiver. - /// @dev Payer must own or approve the LP tokens being burned. The function updates LMSR state + /// @notice Burn LP _tokens and withdraw the proportional basket to receiver. + /// @dev Payer must own or approve the LP _tokens being burned. The function updates LMSR state /// proportionally to reflect the reduced pool size after the withdrawal. - /// @param payer address that provides the LP tokens to burn - /// @param receiver address that receives the withdrawn tokens - /// @param lpAmount amount of LP tokens to burn (proportional withdrawal) + /// @param payer address that provides the LP _tokens to burn + /// @param receiver address that receives the withdrawn _tokens + /// @param lpAmount amount of LP _tokens to burn (proportional withdrawal) /// @param deadline timestamp after which the transaction will revert. Pass 0 to ignore. /// @param unwrap if true and the native token is being withdrawn, it is unwraped and sent as native currency function burn(address payer, address receiver, uint256 lpAmount, uint256 deadline, bool unwrap) external nonReentrant returns (uint256[] memory withdrawAmounts) { require(deadline == 0 || block.timestamp <= deadline, "burn: deadline exceeded"); - uint256 n = tokens.length; + uint256 n = _tokens.length; require(lpAmount > 0, "burn: zero lp"); uint256 supply = _totalSupply; @@ -151,12 +151,12 @@ contract PartyPoolMintImpl is PartyPoolBase { // Use cached balances; assume standard ERC20 transfers without external interference // Compute proportional withdrawal amounts for the requested LP amount (rounded down) - withdrawAmounts = burnAmounts(lpAmount, lmsr.nAssets, _totalSupply, cachedUintBalances); + withdrawAmounts = burnAmounts(lpAmount, _lmsr.nAssets, _totalSupply, _cachedUintBalances); - // Transfer underlying tokens out to receiver according to computed proportions + // Transfer underlying _tokens out to receiver according to computed proportions for (uint i = 0; i < n; ) { if (withdrawAmounts[i] > 0) { - _sendTokenTo(tokens[i], receiver, withdrawAmounts[i], unwrap); + _sendTokenTo(_tokens[i], receiver, withdrawAmounts[i], unwrap); } unchecked { i++; } } @@ -164,9 +164,9 @@ contract PartyPoolMintImpl is PartyPoolBase { // Update cached balances and internal q for all assets using computed withdrawals int128[] memory newQInternal = new int128[](n); for (uint i = 0; i < n; ) { - uint256 newBal = cachedUintBalances[i] - withdrawAmounts[i]; - cachedUintBalances[i] = newBal; - newQInternal[i] = _uintToInternalFloor(newBal, bases[i]); + uint256 newBal = _cachedUintBalances[i] - withdrawAmounts[i]; + _cachedUintBalances[i] = newBal; + newQInternal[i] = _uintToInternalFloor(newBal, _bases[i]); unchecked { i++; } } @@ -181,9 +181,9 @@ contract PartyPoolMintImpl is PartyPoolBase { } if (allZero) { - lmsr.deinit(); + _lmsr.deinit(); } else { - lmsr.updateForProportionalChange(newQInternal); + _lmsr.updateForProportionalChange(newQInternal); } // Burn exactly the requested LP amount from payer (authorization via allowance) @@ -199,9 +199,9 @@ contract PartyPoolMintImpl is PartyPoolBase { /// @notice Calculate the proportional deposit amounts required for a given LP token amount /// @dev Returns the minimum token amounts (rounded up) that must be supplied to receive lpTokenAmount - /// LP tokens at current pool proportions. If the pool is empty (initial deposit) returns zeros - /// because the initial deposit is handled by transferring tokens then calling mint(). - /// @param lpTokenAmount The amount of LP tokens desired + /// LP _tokens at current pool proportions. If the pool is empty (initial deposit) returns zeros + /// because the initial deposit is handled by transferring _tokens then calling mint(). + /// @param lpTokenAmount The amount of LP _tokens desired /// @return depositAmounts Array of token amounts to deposit (rounded up) function mintAmounts(uint256 lpTokenAmount, uint256 numAssets, uint256 totalSupply, uint256[] memory cachedUintBalances) public pure @@ -209,7 +209,7 @@ contract PartyPoolMintImpl is PartyPoolBase { depositAmounts = new uint256[](numAssets); // If this is the first mint or pool is empty, return zeros - // For first mint, tokens should already be transferred to the pool + // For first mint, _tokens should already be transferred to the pool if (totalSupply == 0 || numAssets == 0) { return depositAmounts; // Return zeros, initial deposit handled differently } @@ -256,11 +256,11 @@ contract PartyPoolMintImpl is PartyPoolBase { /// @param maxAmountIn maximum amount of token to deposit (inclusive of fee) /// @param swapFeePpm fee in parts-per-million /// @param lmsrState current LMSR state - /// @param bases_ scaling bases for each token + /// @param bases_ scaling _bases for each token /// @param totalSupply_ current total LP token supply /// @return amountInUsed actual input amount used (excluding fee) /// @return fee fee amount charged - /// @return lpMinted LP tokens that would be minted + /// @return lpMinted LP _tokens that would be minted function swapMintAmounts( uint256 inputTokenIndex, uint256 maxAmountIn, @@ -311,7 +311,7 @@ contract PartyPoolMintImpl is PartyPoolBase { uint256 newScaled = ABDKMath64x64.mulu(newTotal, LP_SCALE); if (totalSupply_ == 0) { - // If somehow supply zero (shouldn't happen as lmsr.nAssets>0), mint newScaled + // If somehow supply zero (shouldn't happen as _lmsr.nAssets>0), mint newScaled lpMinted = newScaled; } else { require(oldScaled > 0, "swapMintAmounts: oldScaled zero"); @@ -331,7 +331,7 @@ contract PartyPoolMintImpl is PartyPoolBase { /// @dev swapMint executes as an exact-in planned swap followed by proportional scaling of qInternal. /// The function emits SwapMint (gross, net, fee) and also emits Mint for LP issuance. /// @param payer who transfers the input token - /// @param receiver who receives the minted LP tokens + /// @param receiver who receives the minted LP _tokens /// @param inputTokenIndex index of the input token /// @param maxAmountIn maximum uint token input (inclusive of fee) /// @param deadline optional deadline @@ -346,24 +346,24 @@ contract PartyPoolMintImpl is PartyPoolBase { uint256 swapFeePpm, uint256 protocolFeePpm ) external payable native nonReentrant returns (uint256 lpMinted) { - uint256 n = tokens.length; + uint256 n = _tokens.length; require(inputTokenIndex < n, "swapMint: idx"); require(maxAmountIn > 0, "swapMint: input zero"); require(deadline == 0 || block.timestamp <= deadline, "swapMint: deadline"); - require(lmsr.nAssets > 0, "swapMint: uninit pool"); + require(_lmsr.nAssets > 0, "swapMint: uninit pool"); // compute fee on gross maxAmountIn to get an initial net estimate (we'll recompute based on actual used) (, uint256 netUintGuess) = _computeFee(maxAmountIn, swapFeePpm); // Convert the net guess to internal (floor) - int128 netInternalGuess = _uintToInternalFloor(netUintGuess, bases[inputTokenIndex]); + int128 netInternalGuess = _uintToInternalFloor(netUintGuess, _bases[inputTokenIndex]); require(netInternalGuess > int128(0), "swapMint: input too small after fee"); // Use LMSR view to determine actual internal consumed and size-increase (ΔS) for mint - (int128 amountInInternalUsed, int128 sizeIncreaseInternal) = lmsr.swapAmountsForMint(inputTokenIndex, netInternalGuess); + (int128 amountInInternalUsed, int128 sizeIncreaseInternal) = _lmsr.swapAmountsForMint(inputTokenIndex, netInternalGuess); // amountInInternalUsed may be <= netInternalGuess. Convert to uint (ceil) to determine actual transfer - uint256 amountInUint = _internalToUintCeil(amountInInternalUsed, bases[inputTokenIndex]); + uint256 amountInUint = _internalToUintCeil(amountInInternalUsed, _bases[inputTokenIndex]); require(amountInUint > 0, "swapMint: input zero after internal conversion"); // Compute fee on the actual used input and total transfer amount (ceiling) @@ -371,22 +371,22 @@ contract PartyPoolMintImpl is PartyPoolBase { uint256 totalTransfer = amountInUint + feeUintActual; require(totalTransfer > 0 && totalTransfer <= maxAmountIn, "swapMint: transfer exceeds max"); - // Transfer tokens from payer (assume standard ERC20 without transfer fees) via helper - _receiveTokenFrom(payer, tokens[inputTokenIndex], totalTransfer); + // Transfer _tokens from payer (assume standard ERC20 without transfer fees) via helper + _receiveTokenFrom(payer, _tokens[inputTokenIndex], totalTransfer); // Accrue protocol share (floor) from the fee on the input token uint256 protoShare = 0; if (protocolFeePpm > 0 && feeUintActual > 0) { protoShare = (feeUintActual * protocolFeePpm) / 1_000_000; if (protoShare > 0) { - protocolFeesOwed[inputTokenIndex] += protoShare; + _protocolFeesOwed[inputTokenIndex] += protoShare; } } // Update cached effective balance directly: add totalTransfer minus protocol share - cachedUintBalances[inputTokenIndex] += (totalTransfer - protoShare); + _cachedUintBalances[inputTokenIndex] += (totalTransfer - protoShare); // Compute old and new scaled size metrics to determine LP minted - int128 oldTotal = _computeSizeMetric(lmsr.qInternal); + int128 oldTotal = _computeSizeMetric(_lmsr.qInternal); uint256 oldScaled = ABDKMath64x64.mulu(oldTotal, LP_SCALE); int128 newTotal = oldTotal.add(sizeIncreaseInternal); @@ -396,7 +396,7 @@ contract PartyPoolMintImpl is PartyPoolBase { // Use natural ERC20 function since base contract inherits from ERC20 uint256 currentSupply = _totalSupply; if (currentSupply == 0) { - // If somehow supply zero (shouldn't happen as lmsr.nAssets>0), mint newScaled + // If somehow supply zero (shouldn't happen as _lmsr.nAssets>0), mint newScaled actualLpToMint = newScaled; } else { uint256 delta = (newScaled > oldScaled) ? (newScaled - oldScaled) : 0; @@ -414,11 +414,11 @@ contract PartyPoolMintImpl is PartyPoolBase { int128[] memory newQInternal = new int128[](n); for (uint256 idx = 0; idx < n; idx++) { // newQInternal[idx] = qInternal[idx] * (newTotal / oldTotal) - newQInternal[idx] = lmsr.qInternal[idx].mul(newTotal).div(oldTotal); + newQInternal[idx] = _lmsr.qInternal[idx].mul(newTotal).div(oldTotal); } // Update cached internal and kappa via updateForProportionalChange - lmsr.updateForProportionalChange(newQInternal); + _lmsr.updateForProportionalChange(newQInternal); // Use natural ERC20 function since base contract inherits from ERC20 _mint(receiver, actualLpToMint); @@ -435,11 +435,11 @@ contract PartyPoolMintImpl is PartyPoolBase { /// @notice Calculate the amounts for a burn swap operation /// @dev This is a pure view function that computes burn swap amounts from provided state - /// @param lpAmount amount of LP tokens to burn + /// @param lpAmount amount of LP _tokens to burn /// @param inputTokenIndex index of target asset to receive /// @param swapFeePpm fee in parts-per-million /// @param lmsrState current LMSR state - /// @param bases_ scaling bases for each token + /// @param bases_ scaling _bases for each token /// @param totalSupply_ current total LP token supply /// @return amountOut amount of target asset that would be received function burnSwapAmounts( @@ -467,11 +467,11 @@ contract PartyPoolMintImpl is PartyPoolBase { require(amountOut > 0, "burnSwapAmounts: output zero"); } - /// @notice Burn LP tokens then swap the redeemed proportional basket into a single asset `inputTokenIndex` and send to receiver. - /// @dev The function burns LP tokens (authorization via allowance if needed), sends the single-asset payout and updates LMSR state. - /// @param payer who burns LP tokens + /// @notice Burn LP _tokens then swap the redeemed proportional basket into a single asset `inputTokenIndex` and send to receiver. + /// @dev The function burns LP _tokens (authorization via allowance if needed), sends the single-asset payout and updates LMSR state. + /// @param payer who burns LP _tokens /// @param receiver who receives the single asset - /// @param lpAmount amount of LP tokens to burn + /// @param lpAmount amount of LP _tokens to burn /// @param inputTokenIndex index of target asset to receive /// @param deadline optional deadline /// @param swapFeePpm fee in parts-per-million for this pool (may be used for future fee logic) @@ -486,7 +486,7 @@ contract PartyPoolMintImpl is PartyPoolBase { uint256 swapFeePpm, uint256 protocolFeePpm ) external nonReentrant returns (uint256 amountOutUint) { - uint256 n = tokens.length; + uint256 n = _tokens.length; require(inputTokenIndex < n, "burnSwap: idx"); require(lpAmount > 0, "burnSwap: zero lp"); require(deadline == 0 || block.timestamp <= deadline, "burnSwap: deadline"); @@ -499,16 +499,16 @@ contract PartyPoolMintImpl is PartyPoolBase { .mul(ABDKMath64x64.divu(1000000-swapFeePpm, 1000000)); // adjusted for fee // Use LMSR view to compute single-asset payout and burned size-metric - (int128 payoutInternal, ) = lmsr.swapAmountsForBurn(inputTokenIndex, alpha); + (int128 payoutInternal, ) = _lmsr.swapAmountsForBurn(inputTokenIndex, alpha); // Convert payoutInternal -> uint (floor) to favor pool - amountOutUint = _internalToUintFloor(payoutInternal, bases[inputTokenIndex]); + amountOutUint = _internalToUintFloor(payoutInternal, _bases[inputTokenIndex]); require(amountOutUint > 0, "burnSwap: output zero"); // Compute gross payout (no swap fee) so we can determine token-side fee = gross - net int128 alphaGross = ABDKMath64x64.divu(lpAmount, supply); // gross fraction (no swap fee) - (int128 payoutGrossInternal, ) = lmsr.swapAmountsForBurn(inputTokenIndex, alphaGross); - uint256 payoutGrossUint = _internalToUintFloor(payoutGrossInternal, bases[inputTokenIndex]); + (int128 payoutGrossInternal, ) = _lmsr.swapAmountsForBurn(inputTokenIndex, alphaGross); + uint256 payoutGrossUint = _internalToUintFloor(payoutGrossInternal, _bases[inputTokenIndex]); uint256 feeTokenUint = (payoutGrossUint > amountOutUint) ? (payoutGrossUint - amountOutUint) : 0; // Accrue protocol share (floor) from the token-side fee @@ -516,14 +516,14 @@ contract PartyPoolMintImpl is PartyPoolBase { if (protocolFeePpm > 0 && feeTokenUint > 0) { protoShare = (feeTokenUint * protocolFeePpm) / 1_000_000; if (protoShare > 0) { - protocolFeesOwed[inputTokenIndex] += protoShare; + _protocolFeesOwed[inputTokenIndex] += protoShare; } } // Transfer the payout to receiver via centralized helper - _sendTokenTo(tokens[inputTokenIndex], receiver, amountOutUint, unwrap); + _sendTokenTo(_tokens[inputTokenIndex], receiver, amountOutUint, unwrap); - // Burn LP tokens from payer (authorization via allowance) + // Burn LP _tokens from payer (authorization via allowance) if (msg.sender != payer) { uint256 allowed = _allowances[payer][msg.sender]; _approve(payer, msg.sender, allowed - lpAmount); @@ -533,13 +533,13 @@ contract PartyPoolMintImpl is PartyPoolBase { // Update cached balances using computed payout and protocol fee; no on-chain reads int128[] memory newQInternal = new int128[](n); for (uint256 idx = 0; idx < n; idx++) { - uint256 newBal = cachedUintBalances[idx]; + uint256 newBal = _cachedUintBalances[idx]; if (idx == inputTokenIndex) { // Effective LP balance decreases by net payout and increased protocol owed newBal = newBal - amountOutUint - protoShare; } - cachedUintBalances[idx] = newBal; - newQInternal[idx] = _uintToInternalFloor(newBal, bases[idx]); + _cachedUintBalances[idx] = newBal; + newQInternal[idx] = _uintToInternalFloor(newBal, _bases[idx]); } // Emit BurnSwap with public-facing info only (do not expose ΔS or LP burned) @@ -551,9 +551,9 @@ contract PartyPoolMintImpl is PartyPoolBase { if (newQInternal[idx] != int128(0)) { allZero = false; break; } } if (allZero) { - lmsr.deinit(); + _lmsr.deinit(); } else { - lmsr.updateForProportionalChange(newQInternal); + _lmsr.updateForProportionalChange(newQInternal); } emit IPartyPool.Burn(payer, receiver, new uint256[](n), lpAmount); diff --git a/src/PartyPoolSwapImpl.sol b/src/PartyPoolSwapImpl.sol index 73105c6..2fcef47 100644 --- a/src/PartyPoolSwapImpl.sol +++ b/src/PartyPoolSwapImpl.sol @@ -60,49 +60,49 @@ contract PartyPoolSwapImpl is PartyPoolBase { uint256 swapFeePpm, uint256 protocolFeePpm ) external payable native returns (uint256 amountInUsed, uint256 amountOut, uint256 fee) { - uint256 n = tokens.length; + uint256 n = _tokens.length; require(inputTokenIndex < n && outputTokenIndex < n, "swapToLimit: idx"); require(limitPrice > int128(0), "swapToLimit: limit <= 0"); require(deadline == 0 || block.timestamp <= deadline, "swapToLimit: deadline exceeded"); // Read previous balances for affected assets - uint256 prevBalI = IERC20(tokens[inputTokenIndex]).balanceOf(address(this)); - uint256 prevBalJ = IERC20(tokens[outputTokenIndex]).balanceOf(address(this)); + uint256 prevBalI = IERC20(_tokens[inputTokenIndex]).balanceOf(address(this)); + uint256 prevBalJ = IERC20(_tokens[outputTokenIndex]).balanceOf(address(this)); // Compute amounts using the same path as views (uint256 totalTransferAmount, uint256 amountOutUint, int128 amountInInternalMax, int128 amountOutInternal, uint256 amountInUsedUint, uint256 feeUint) = _quoteSwapToLimit(inputTokenIndex, outputTokenIndex, limitPrice, swapFeePpm); // Transfer the exact amount needed from payer and require exact receipt (revert on fee-on-transfer) - _receiveTokenFrom(payer, tokens[inputTokenIndex], totalTransferAmount); - uint256 balIAfter = IERC20(tokens[inputTokenIndex]).balanceOf(address(this)); + _receiveTokenFrom(payer, _tokens[inputTokenIndex], totalTransferAmount); + uint256 balIAfter = IERC20(_tokens[inputTokenIndex]).balanceOf(address(this)); require(balIAfter == prevBalI + totalTransferAmount, "swapToLimit: non-standard tokenIn"); // Transfer output to receiver and verify exact decrease - _sendTokenTo(tokens[outputTokenIndex], receiver, amountOutUint, unwrap); - uint256 balJAfter = IERC20(tokens[outputTokenIndex]).balanceOf(address(this)); + _sendTokenTo(_tokens[outputTokenIndex], receiver, amountOutUint, unwrap); + uint256 balJAfter = IERC20(_tokens[outputTokenIndex]).balanceOf(address(this)); require(balJAfter == prevBalJ - amountOutUint, "swapToLimit: non-standard tokenOut"); // Accrue protocol share (floor) from the fee on input token if (protocolFeePpm > 0 && feeUint > 0 ) { uint256 protoShare = (feeUint * protocolFeePpm) / 1_000_000; // floor if (protoShare > 0) { - protocolFeesOwed[inputTokenIndex] += protoShare; + _protocolFeesOwed[inputTokenIndex] += protoShare; } } // Update caches to effective balances (inline _recordCachedBalance) - require(balIAfter >= protocolFeesOwed[inputTokenIndex], "balance < protocol owed"); - cachedUintBalances[inputTokenIndex] = balIAfter - protocolFeesOwed[inputTokenIndex]; + require(balIAfter >= _protocolFeesOwed[inputTokenIndex], "balance < protocol owed"); + _cachedUintBalances[inputTokenIndex] = balIAfter - _protocolFeesOwed[inputTokenIndex]; - require(balJAfter >= protocolFeesOwed[outputTokenIndex], "balance < protocol owed"); - cachedUintBalances[outputTokenIndex] = balJAfter - protocolFeesOwed[outputTokenIndex]; + require(balJAfter >= _protocolFeesOwed[outputTokenIndex], "balance < protocol owed"); + _cachedUintBalances[outputTokenIndex] = balJAfter - _protocolFeesOwed[outputTokenIndex]; // Apply swap to LMSR state with the internal amounts - lmsr.applySwap(inputTokenIndex, outputTokenIndex, amountInInternalMax, amountOutInternal); + _lmsr.applySwap(inputTokenIndex, outputTokenIndex, amountInInternalMax, amountOutInternal); // Maintain original event semantics (logs input without fee) - emit IPartyPool.Swap(payer, receiver, tokens[inputTokenIndex], tokens[outputTokenIndex], amountInUsedUint, amountOutUint); + emit IPartyPool.Swap(payer, receiver, _tokens[inputTokenIndex], _tokens[outputTokenIndex], amountInUsedUint, amountOutUint); return (amountInUsedUint, amountOutUint, feeUint); } @@ -129,10 +129,10 @@ contract PartyPoolSwapImpl is PartyPoolBase { ) { // Compute internal maxima at the price limit - (amountInInternal, amountOutInternal) = lmsr.swapAmountsForPriceLimit(inputTokenIndex, outputTokenIndex, limitPrice); + (amountInInternal, amountOutInternal) = _lmsr.swapAmountsForPriceLimit(inputTokenIndex, outputTokenIndex, limitPrice); // Convert input to uint (ceil) and output to uint (floor) - amountInUintNoFee = _internalToUintCeil(amountInInternal, bases[inputTokenIndex]); + amountInUintNoFee = _internalToUintCeil(amountInInternal, _bases[inputTokenIndex]); require(amountInUintNoFee > 0, "swapToLimit: input zero"); feeUint = 0; @@ -142,7 +142,7 @@ contract PartyPoolSwapImpl is PartyPoolBase { grossIn += feeUint; } - amountOutUint = _internalToUintFloor(amountOutInternal, bases[outputTokenIndex]); + amountOutUint = _internalToUintFloor(amountOutInternal, _bases[outputTokenIndex]); require(amountOutUint > 0, "swapToLimit: output zero"); } diff --git a/src/PartyPoolViewer.sol b/src/PartyPoolViewer.sol index 7d94932..4cf2027 100644 --- a/src/PartyPoolViewer.sol +++ b/src/PartyPoolViewer.sol @@ -167,7 +167,7 @@ contract PartyPoolViewer is PartyPoolHelpers, IPartyPoolViewer { /** * @dev The fee to be charged for a given loan. - * @param amount The amount of tokens lent. + * @param amount The amount of _tokens lent. * @return fee The amount of `token` to be charged for the loan, on top of the returned principal. */ function flashFee( diff --git a/test/GasTest.sol b/test/GasTest.sol index c43d589..4e72117 100644 --- a/test/GasTest.sol +++ b/test/GasTest.sol @@ -114,9 +114,9 @@ contract GasTest is Test { uint256 constant internal INIT_BAL = 1_000_000; // initial token units for each token (internal==amount when base==1) uint256 constant internal BASE = 1; // use base=1 so internal amounts correspond to raw integers (Q64.64 units) - /// @notice Helper function to create a pool with the specified number of tokens + /// @notice Helper function to create a pool with the specified number of _tokens function createPool(uint256 numTokens) internal returns (PartyPool) { - // Deploy tokens dynamically + // Deploy _tokens dynamically address[] memory tokens = new address[](numTokens); uint256[] memory bases = new uint256[](numTokens); @@ -139,7 +139,7 @@ contract GasTest is Test { for (uint i = 0; i < tokens.length; i++) { ierc20Tokens[i] = IERC20(tokens[i]); } - // Compute kappa from slippage params and number of tokens, then construct pool with kappa + // Compute kappa from slippage params and number of _tokens, then construct pool with kappa int128 computedKappa = LMSRStabilized.computeKappaFromSlippage(ierc20Tokens.length, tradeFrac, targetSlippage); PartyPool newPool = Deploy.newPartyPool(poolName, poolName, ierc20Tokens, bases, computedKappa, feePpm, feePpm, false); @@ -156,7 +156,7 @@ contract GasTest is Test { /// @notice Helper to create a pool with the stable-pair optimization enabled function createPoolStable(uint256 numTokens) internal returns (PartyPool) { - // Deploy tokens dynamically + // Deploy _tokens dynamically address[] memory tokens = new address[](numTokens); uint256[] memory bases = new uint256[](numTokens); @@ -216,7 +216,7 @@ contract GasTest is Test { // Deploy the borrower contract borrower = new FlashBorrower(address(pool2)); - // Mint tokens to alice to be used for repayments and approve borrower + // Mint _tokens to alice to be used for repayments and approve borrower IERC20[] memory tokenAddresses = pool2.allTokens(); vm.startPrank(alice); for (uint256 i = 0; i < tokenAddresses.length; i++) { @@ -226,12 +226,12 @@ contract GasTest is Test { vm.stopPrank(); } - /// @notice Helper function: perform 10 swaps back-and-forth between the first two tokens. + /// @notice Helper function: perform 10 swaps back-and-forth between the first two _tokens. function _performSwapGasTest(PartyPool testPool) internal { IERC20[] memory tokens = testPool.allTokens(); require(tokens.length >= 2, "Pool must have at least 2 tokens"); - // Ensure alice approves pool for both tokens + // Ensure alice approves pool for both _tokens vm.prank(alice); TestERC20(address(tokens[0])).approve(address(testPool), type(uint256).max); vm.prank(alice); @@ -252,22 +252,22 @@ contract GasTest is Test { } } - /// @notice Gas measurement: perform 10 swaps back-and-forth between first two tokens in the 2-token pool. + /// @notice Gas measurement: perform 10 swaps back-and-forth between first two _tokens in the 2-token pool. function testSwapGasPair() public { _performSwapGasTest(pool2); } - /// @notice Gas measurement: perform 10 swaps back-and-forth between first two tokens in the 10-token pool. + /// @notice Gas measurement: perform 10 swaps back-and-forth between first two _tokens in the 10-token pool. function testSwapGasTen() public { _performSwapGasTest(pool10); } - /// @notice Gas measurement: perform 10 swaps back-and-forth between first two tokens in the 20-token pool. + /// @notice Gas measurement: perform 10 swaps back-and-forth between first two _tokens in the 20-token pool. function testSwapGasTwenty() public { _performSwapGasTest(pool20); } - /// @notice Gas measurement: perform 10 swaps back-and-forth between first two tokens in the 100-token pool. + /// @notice Gas measurement: perform 10 swaps back-and-forth between first two _tokens in the 100-token pool. function testSwapGasFifty() public { _performSwapGasTest(pool50); } @@ -307,7 +307,7 @@ contract GasTest is Test { uint256 minted = testPool.swapMint(alice, alice, 0, input, 0); // If nothing minted (numerical edge), skip burn step if (minted == 0) continue; - // Immediately burn the minted LP back to tokens, targeting the same token index + // Immediately burn the minted LP back to _tokens, targeting the same token index testPool.burnSwap(alice, alice, minted, 0, 0, false); } @@ -343,7 +343,7 @@ contract GasTest is Test { vm.startPrank(alice); - // Mint additional tokens to alice and approve pool to transfer tokens for proportional mint + // Mint additional _tokens to alice and approve pool to transfer _tokens for proportional mint for (uint256 i = 0; i < poolTokens.length; i++) { TestERC20(address(poolTokens[i])).mint(alice, iterations * input * 2); TestERC20(address(poolTokens[i])).approve(address(testPool), type(uint256).max); diff --git a/test/NativeTest.t.sol b/test/NativeTest.t.sol index 973bb60..36a1345 100644 --- a/test/NativeTest.t.sol +++ b/test/NativeTest.t.sol @@ -61,7 +61,7 @@ contract NativeTest is Test { vm.deal(alice, 100 ether); vm.deal(bob, 100 ether); - // Deploy two regular ERC20 tokens + // Deploy two regular ERC20 _tokens token0 = new TestERC20Native("T0", "T0", 0); token1 = new TestERC20Native("T1", "T1", 0); @@ -72,7 +72,7 @@ contract NativeTest is Test { token0.mint(address(this), INIT_BAL); token1.mint(address(this), INIT_BAL); - // For WETH, we deposit native currency to get wrapped tokens + // For WETH, we deposit native currency to get wrapped _tokens weth.deposit{value: INIT_BAL}(); // Configure LMSR parameters @@ -104,7 +104,7 @@ contract NativeTest is Test { // Perform initial mint pool.initialMint(address(this), 0); - // Mint tokens to alice and bob for testing + // Mint _tokens to alice and bob for testing token0.mint(alice, INIT_BAL); token1.mint(alice, INIT_BAL); @@ -407,7 +407,7 @@ contract NativeTest is Test { true // unwrap ); - // Bob should receive tokens and native currency + // Bob should receive _tokens and native currency assertEq(token0.balanceOf(bob), bobToken0Before + withdraws[0], "Bob token0"); assertEq(token1.balanceOf(bob), bobToken1Before + withdraws[1], "Bob token1"); assertEq(bob.balance, bobEthBefore + withdraws[2], "Bob should receive ETH"); @@ -441,7 +441,7 @@ contract NativeTest is Test { assertTrue(alice.balance <= aliceEthBefore, "Alice ETH should decrease"); assertTrue(aliceEthBefore - alice.balance <= maxIn, "Alice spent at most maxIn"); - // Alice should receive LP tokens + // Alice should receive LP _tokens assertTrue(pool.balanceOf(alice) >= aliceLpBefore + lpMinted, "Alice should receive LP"); vm.stopPrank(); @@ -567,7 +567,7 @@ contract NativeTest is Test { vm.stopPrank(); } - /// @notice Test that unwrap=false with WETH actually transfers WETH tokens (not native) + /// @notice Test that unwrap=false with WETH actually transfers WETH _tokens (not native) function testSwapWithWethNoUnwrap() public { uint256 maxIn = 10_000; diff --git a/test/PartyPlanner.t.sol b/test/PartyPlanner.t.sol index 6a0e85a..66bbfea 100644 --- a/test/PartyPlanner.t.sol +++ b/test/PartyPlanner.t.sol @@ -49,17 +49,17 @@ contract PartyPlannerTest is Test { // Deploy PartyPlanner planner = Deploy.newPartyPlanner(); - // Deploy mock tokens + // Deploy mock _tokens tokenA = new MockERC20("Token A", "TKNA", 18); tokenB = new MockERC20("Token B", "TKNB", 18); tokenC = new MockERC20("Token C", "TKNC", 6); - // Mint tokens to payer + // Mint _tokens to payer tokenA.mint(payer, INITIAL_MINT_AMOUNT); tokenB.mint(payer, INITIAL_MINT_AMOUNT); tokenC.mint(payer, INITIAL_MINT_AMOUNT); - // Approve tokens for PartyPlanner + // Approve _tokens for PartyPlanner vm.startPrank(payer); tokenA.approve(address(planner), type(uint256).max); tokenB.approve(address(planner), type(uint256).max); @@ -156,7 +156,7 @@ contract PartyPlannerTest is Test { } assertTrue(poolInTokenB, "Pool should be indexed under tokenB"); - // Verify LP tokens were minted to receiver + // Verify LP _tokens were minted to receiver assertEq(pool.balanceOf(receiver), lpAmount, "Receiver should have LP tokens"); } diff --git a/test/PartyPool.t.sol b/test/PartyPool.t.sol index 03e5e6c..f19ddab 100644 --- a/test/PartyPool.t.sol +++ b/test/PartyPool.t.sol @@ -130,7 +130,7 @@ contract PartyPoolTest is Test { alice = address(0xA11ce); bob = address(0xB0b); - // Deploy three ERC20 test tokens and mint initial supplies to this test contract for initial deposit + // Deploy three ERC20 test _tokens and mint initial supplies to this test contract for initial deposit token0 = new TestERC20("T0", "T0", 0); token1 = new TestERC20("T1", "T1", 0); token2 = new TestERC20("T2", "T2", 0); @@ -175,7 +175,7 @@ contract PartyPoolTest is Test { int128 kappa3 = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage); 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) + // Transfer initial deposit amounts into pool before initial mint (pool expects _tokens already in contract) // We deposit equal amounts INIT_BAL for each token token0.transfer(address(pool), INIT_BAL); token1.transfer(address(pool), INIT_BAL); @@ -184,7 +184,7 @@ contract PartyPoolTest is Test { // Perform initial mint (initial deposit); receiver is this contract pool.initialMint(address(this), 0); - // Set up pool10 with 10 tokens + // Set up pool10 with 10 _tokens IERC20[] memory tokens10 = new IERC20[](10); tokens10[0] = IERC20(address(token0)); tokens10[1] = IERC20(address(token1)); @@ -205,7 +205,7 @@ contract PartyPoolTest is Test { int128 kappa10 = LMSRStabilized.computeKappaFromSlippage(tokens10.length, tradeFrac, targetSlippage); pool10 = Deploy.newPartyPool("LP10", "LP10", tokens10, bases10, kappa10, feePpm, feePpm, false); - // Mint additional tokens for pool10 initial deposit + // Mint additional _tokens for pool10 initial deposit token0.mint(address(this), INIT_BAL); token1.mint(address(this), INIT_BAL); token2.mint(address(this), INIT_BAL); @@ -232,7 +232,7 @@ contract PartyPoolTest is Test { // Perform initial mint for pool10 pool10.initialMint(address(this), 0); - // For later tests we will mint tokens to alice/bob as needed + // For later tests we will mint _tokens to alice/bob as needed token0.mint(alice, INIT_BAL); token1.mint(alice, INIT_BAL); token2.mint(alice, INIT_BAL); @@ -258,7 +258,7 @@ contract PartyPoolTest is Test { viewer = Deploy.newViewer(); } - /// @notice Basic sanity: initial mint should have produced LP tokens for this contract and the pool holds tokens. + /// @notice Basic sanity: initial mint should have produced LP _tokens for this contract and the pool holds _tokens. function testInitialMintAndLP() public view { uint256 totalLp = pool.totalSupply(); assertTrue(totalLp > 0, "Initial LP supply should be > 0"); @@ -274,7 +274,7 @@ contract PartyPoolTest is Test { function testProportionalMintZeroLpReverts() public { // Attempt to request a tiny LP amount (1) and expect revert because calculated actualLpToMint will be zero - // Approve pool to transfer tokens on alice's behalf + // Approve pool to transfer _tokens on alice's behalf vm.startPrank(alice); token0.approve(address(pool), type(uint256).max); token1.approve(address(pool), type(uint256).max); @@ -290,7 +290,7 @@ contract PartyPoolTest is Test { /// does not undercharge (no value extraction). This test verifies the request succeeds /// and that computed deposits are at least the proportional floor (ceil >= floor). function testProportionalMintOneWeiSucceedsAndProtectsPool() public { - // Request a tiny LP amount (1 wei). Approve pool to transfer tokens on alice's behalf. + // Request a tiny LP amount (1 wei). Approve pool to transfer _tokens on alice's behalf. vm.startPrank(alice); token0.approve(address(pool), type(uint256).max); token1.approve(address(pool), type(uint256).max); @@ -406,14 +406,14 @@ contract PartyPoolTest is Test { assertTrue(withdrawAmounts[i] <= poolBal, "withdraw amount cannot exceed pool balance"); } - // Burn by sending LP tokens from this contract (which holds initial LP from setUp) + // Burn by sending LP _tokens from this contract (which holds initial LP from setUp) // Call burn(payer=this, receiver=bob, lpAmount=totalLp) pool.burn(address(this), bob, totalLp, 0, false); // After burning entire pool, totalSupply should be zero or very small (we expect zero since we withdrew all) assertEq(pool.totalSupply(), 0); - // Bob should have received the withdrawn tokens + // Bob should have received the withdrawn _tokens for (uint i = 0; i < withdrawAmounts.length; i++) { assertTrue(IERC20(pool.allTokens()[i]).balanceOf(bob) >= withdrawAmounts[i], "Bob should receive withdrawn tokens"); } @@ -424,7 +424,7 @@ contract PartyPoolTest is Test { // Use alice as payer and bob as receiver uint256 maxIn = 10_000; - // Ensure alice has tokens and approves pool + // Ensure alice has _tokens and approves pool vm.prank(alice); token0.approve(address(pool), type(uint256).max); @@ -503,7 +503,7 @@ contract PartyPoolTest is Test { // Compute expected deposit amounts via view uint256[] memory expected = viewer.mintAmounts(pool, req); - // Ensure alice has tokens and approve pool + // Ensure alice has _tokens and approve pool vm.startPrank(alice); token0.approve(address(pool), type(uint256).max); token1.approve(address(pool), type(uint256).max); @@ -548,7 +548,7 @@ contract PartyPoolTest is Test { uint256[] memory expected = viewer.mintAmounts(pool10, req); - // Approve all tokens from alice + // Approve all _tokens from alice vm.startPrank(alice); token0.approve(address(pool10), type(uint256).max); token1.approve(address(pool10), type(uint256).max); @@ -614,7 +614,7 @@ contract PartyPoolTest is Test { uint256 myLp = pool.balanceOf(address(this)); if (myLp < req) { uint256 topUp = req - myLp; - // Have alice supply tokens to mint LP into this contract + // Have alice supply _tokens to mint LP into this contract vm.startPrank(alice); token0.approve(address(pool), type(uint256).max); token1.approve(address(pool), type(uint256).max); @@ -754,7 +754,7 @@ contract PartyPoolTest is Test { // Very large input relative to pool uint256 largeInput = 10_000_000_000; // intentionally large - // Ensure alice has sufficient tokens for this large test input (mint top-up) + // Ensure alice has sufficient _tokens for this large test input (mint top-up) token0.mint(alice, largeInput); vm.startPrank(alice); @@ -818,12 +818,12 @@ contract PartyPoolTest is Test { // Deploy the borrower contract borrower = new FlashBorrower(address(pool)); - // Mint tokens to alice to be used for repayments + // Mint _tokens to alice to be used for repayments token0.mint(alice, INIT_BAL * 2); token1.mint(alice, INIT_BAL * 2); token2.mint(alice, INIT_BAL * 2); - // Alice approves borrower to transfer tokens on their behalf for repayment + // Alice approves borrower to transfer _tokens on their behalf for repayment vm.startPrank(alice); token0.approve(address(borrower), type(uint256).max); token1.approve(address(borrower), type(uint256).max); @@ -998,7 +998,7 @@ contract PartyPoolTest is Test { int128 kappaCustom = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage); PartyPool poolCustom = Deploy.newPartyPool("LP_CUSTOM", "LP_CUSTOM", tokens, bases, kappaCustom, feePpm, feePpm, false); - // Mint additional tokens for both pools + // Mint additional _tokens for both pools token0.mint(address(this), INIT_BAL * 2); token1.mint(address(this), INIT_BAL * 2); token2.mint(address(this), INIT_BAL * 2); @@ -1052,7 +1052,7 @@ contract PartyPoolTest is Test { } /// @notice Test that minting the same proportion in pools with different initial LP amounts - /// returns correctly scaled LP tokens + /// returns correctly scaled LP _tokens function testProportionalMintingScaledByInitialAmount() public { // Create two identical pools with different initial LP amounts IERC20[] memory tokens = new IERC20[](3); @@ -1072,7 +1072,7 @@ contract PartyPoolTest is Test { int128 kappaCustom2 = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage); PartyPool poolCustom = Deploy.newPartyPool("LP_CUSTOM", "LP_CUSTOM", tokens, bases, kappaCustom2, feePpm, feePpm, false); - // Mint additional tokens + // Mint additional _tokens token0.mint(address(this), INIT_BAL * 4); token1.mint(address(this), INIT_BAL * 4); token2.mint(address(this), INIT_BAL * 4); @@ -1108,7 +1108,7 @@ contract PartyPoolTest is Test { vm.startPrank(alice); - // Approve tokens for both pools + // Approve _tokens for both pools token0.approve(address(poolDefault), type(uint256).max); token1.approve(address(poolDefault), type(uint256).max); token2.approve(address(poolDefault), type(uint256).max);