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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user