event changes: SwapMint/BurnSwap replace rather than augment the regular Mint/Burn events; All swapping events have lpFee and protocolFee

This commit is contained in:
tim
2025-10-21 14:42:40 -04:00
parent 11ae6f2a4b
commit 538f778f51
4 changed files with 54 additions and 31 deletions

View File

@@ -38,29 +38,45 @@ interface IPartyPool is IERC20Metadata, IOwnable {
IERC20 indexed tokenIn,
IERC20 indexed tokenOut,
uint256 amountIn,
uint256 amountOut
uint256 amountOut,
uint256 lpFee,
uint256 protocolFee
);
/// @notice Emitted when a single-token swapMint is executed.
/// Records payer/receiver, input token index, gross transfer (net+fee), net input and fee taken.
/// @notice Emitted instead of Swap when a single-token swapMint is executed.
event SwapMint(
address indexed payer,
address indexed receiver,
uint256 indexed inputTokenIndex,
uint256 grossTransfer, // total _tokens transferred (net + fee)
uint256 netInput, // net input credited to swaps (after fee)
uint256 feeTaken // fee taken (ceil)
IERC20 indexed tokenIn,
uint256 amountIn,
uint256 amountOut,
uint256 lpFee, // taken from the input token
uint256 protocolFee // taken from the input token
);
/// @notice Emitted when a burnSwap is executed.
/// Records payer/receiver, target token index and the uint payout sent to the receiver.
/// @notice Emitted instead of Burn when a burnSwap is executed.
event BurnSwap(
address indexed payer,
address indexed receiver,
uint256 indexed targetTokenIndex,
uint256 payoutUint
IERC20 indexed tokenOut,
uint256 amountIn,
uint256 amountOut,
uint256 lpFee,
uint256 protocolFee
);
event Flash(
address indexed initiator,
IERC3156FlashBorrower indexed receiver,
IERC20 indexed token,
uint256 amount,
uint256 lpFee,
uint256 protocolFee
);
/// @notice Emitted when protocol fees are collected from this pool.
/// @dev After collection, the protocolFee accounting array will be zeroed out.
event ProtocolFeesCollected();
function LMSR() external view returns (LMSRStabilized.State memory);

View File

@@ -19,6 +19,7 @@ import {SafeERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/uti
import {IERC3156FlashLender} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol";
import {NativeWrapper} from "./NativeWrapper.sol";
import {OwnableExternal} from "./OwnableExternal.sol";
import {IPartyPoolViewer} from "./IPartyPoolViewer.sol";
/// @title PartyPool - LMSR-backed multi-asset pool with LP ERC20 token
/// @notice A multi-asset liquidity pool backed by the LMSRStabilized pricing model.
@@ -259,8 +260,9 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
uint256 balJAfter = _cachedUintBalances[outputTokenIndex] + _protocolFeesOwed[outputTokenIndex] - amountOutUint;
// Accrue protocol share (floor) from the fee on input token
uint256 protoShare = 0;
if (PROTOCOL_FEE_PPM > 0 && feeUint > 0) {
uint256 protoShare = (feeUint * PROTOCOL_FEE_PPM) / 1_000_000; // floor
protoShare = (feeUint * PROTOCOL_FEE_PPM) / 1_000_000; // floor
if (protoShare > 0) {
_protocolFeesOwed[inputTokenIndex] += protoShare;
}
@@ -279,7 +281,8 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
// Transfer output to receiver near the end
_sendTokenTo(tokenOut, receiver, amountOutUint, unwrap);
emit Swap(payer, receiver, tokenIn, tokenOut, totalTransferAmount, amountOutUint);
emit Swap(payer, receiver, tokenIn, tokenOut, totalTransferAmount,
amountOutUint, feeUint - protoShare, protoShare);
return (totalTransferAmount, amountOutUint, feeUint);
}
@@ -450,8 +453,9 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
(uint256 fee, ) = _computeFee(amount, FLASH_FEE_PPM);
// Compute protocol share of flash fee
uint256 protoShare = 0;
if (PROTOCOL_FEE_PPM > 0 && fee > 0) {
uint256 protoShare = (fee * PROTOCOL_FEE_PPM) / 1_000_000; // floor
protoShare = (fee * PROTOCOL_FEE_PPM) / 1_000_000; // floor
if (protoShare > 0) {
_protocolFeesOwed[tokenIndex] += protoShare;
}
@@ -467,6 +471,8 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
require(balAfter >= _protocolFeesOwed[tokenIndex], "balance < protocol owed");
_cachedUintBalances[tokenIndex] = balAfter - _protocolFeesOwed[tokenIndex];
emit Flash(msg.sender, receiver, token, amount, fee-protoShare, protoShare);
return true;
}

View File

@@ -424,12 +424,8 @@ contract PartyPoolMintImpl is PartyPoolBase {
// Use natural ERC20 function since base contract inherits from ERC20
_mint(receiver, actualLpToMint);
// Emit SwapMint event with gross transfer, net input and fee (planned exact-in)
emit IPartyPool.SwapMint(payer, receiver, inputTokenIndex, totalTransfer, amountInUint, feeUintActual);
// Emit standard Mint event which records deposit amounts and LP minted
emit IPartyPool.Mint(payer, receiver, new uint256[](n), actualLpToMint);
// Note: depositAmounts array omitted (empty) since swapMint uses single-token input
emit IPartyPool.SwapMint(payer, receiver, _tokens[inputTokenIndex],
totalTransfer, actualLpToMint, feeUintActual-protoShare, protoShare);
return actualLpToMint;
}
@@ -524,7 +520,8 @@ contract PartyPoolMintImpl is PartyPoolBase {
}
// Transfer the payout to receiver via centralized helper
_sendTokenTo(_tokens[inputTokenIndex], receiver, amountOutUint, unwrap);
IERC20 inputToken = _tokens[inputTokenIndex];
_sendTokenTo(inputToken, receiver, amountOutUint, unwrap);
// Burn LP _tokens from payer (authorization via allowance)
if (msg.sender != payer) {
@@ -545,9 +542,6 @@ contract PartyPoolMintImpl is PartyPoolBase {
newQInternal[idx] = _uintToInternalFloor(newBal, _bases[idx]);
}
// Emit BurnSwap with public-facing info only (do not expose ΔS or LP burned)
emit IPartyPool.BurnSwap(payer, receiver, inputTokenIndex, amountOutUint);
// If entire pool drained, deinit; else update proportionally
bool allZero = true;
for (uint256 idx = 0; idx < n; idx++) {
@@ -559,7 +553,9 @@ contract PartyPoolMintImpl is PartyPoolBase {
_lmsr.updateForProportionalChange(newQInternal);
}
emit IPartyPool.Burn(payer, receiver, new uint256[](n), lpAmount);
emit IPartyPool.BurnSwap(payer, receiver, inputToken, lpAmount, amountOutUint,
feeTokenUint-protoShare, protoShare);
return amountOutUint;
}

View File

@@ -74,18 +74,21 @@ contract PartyPoolSwapImpl is PartyPoolBase {
_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));
IERC20 tokenIn = _tokens[inputTokenIndex];
_receiveTokenFrom(payer, tokenIn, totalTransferAmount);
uint256 balIAfter = tokenIn.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));
IERC20 tokenOut = _tokens[outputTokenIndex];
_sendTokenTo(tokenOut, receiver, amountOutUint, unwrap);
uint256 balJAfter = IERC20(tokenOut).balanceOf(address(this));
require(balJAfter == prevBalJ - amountOutUint, "swapToLimit: non-standard tokenOut");
// Accrue protocol share (floor) from the fee on input token
uint256 protoShare = 0;
if (protocolFeePpm > 0 && feeUint > 0 ) {
uint256 protoShare = (feeUint * protocolFeePpm) / 1_000_000; // floor
protoShare = (feeUint * protocolFeePpm) / 1_000_000; // floor
if (protoShare > 0) {
_protocolFeesOwed[inputTokenIndex] += protoShare;
}
@@ -102,7 +105,8 @@ contract PartyPoolSwapImpl is PartyPoolBase {
_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, tokenIn, tokenOut,
amountInUsedUint, amountOutUint, feeUint-protoShare, protoShare);
return (amountInUsedUint, amountOutUint, feeUint);
}
@@ -164,6 +168,7 @@ contract PartyPoolSwapImpl is PartyPoolBase {
// transfer owed _tokens to protocol destination via centralized helper
_sendTokenTo(_tokens[i], dest, owed, false);
}
emit IPartyPool.ProtocolFeesCollected();
}
}