more gas optimization; protocol fee enabled by default in tests
This commit is contained in:
@@ -24,8 +24,8 @@ Naturally multi-asset, Liquidity Party altcoin pools provide direct, one-hop swa
|
||||
|
||||
| Assets | Pairs | Swap Gas | Mint Gas |
|
||||
|-------:|------:|---------:|----------:|
|
||||
| 2 | 1 | 132,000 | 143,000 |
|
||||
| 2* | 1 | 119,000 | 143,000 |
|
||||
| 2 | 1 | 131,000 | 143,000 |
|
||||
| 2* | 1 | 118,000 | 143,000 |
|
||||
| 10 | 45 | 142,000 | 412,000 |
|
||||
| 20 | 190 | 157,000 | 749,000 |
|
||||
| 50 | 1225 | 199,000 | 1,760,000 |
|
||||
|
||||
@@ -11,6 +11,8 @@ import {PartyPoolSwapImpl} from "./PartyPoolSwapImpl.sol";
|
||||
import {PartyPoolViewer} from "./PartyPoolViewer.sol";
|
||||
|
||||
library Deploy {
|
||||
address internal constant PROTOCOL_FEE_RECEIVER = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8; // dev account #1
|
||||
uint256 internal constant PROTOCOL_FEE_PPM = 100_000; // 10%
|
||||
|
||||
function newPartyPlanner() internal returns (PartyPlanner) {
|
||||
return new PartyPlanner(
|
||||
@@ -18,8 +20,8 @@ library Deploy {
|
||||
new PartyPoolMintImpl(),
|
||||
new PartyPoolDeployer(),
|
||||
new PartyPoolBalancedPairDeployer(),
|
||||
0, // protocolFeePpm = 0 for deploy helper
|
||||
address(0) // protocolFeeAddress = address(0) for deploy helper
|
||||
PROTOCOL_FEE_PPM,
|
||||
PROTOCOL_FEE_RECEIVER
|
||||
);
|
||||
}
|
||||
|
||||
@@ -33,10 +35,6 @@ library Deploy {
|
||||
uint256 _flashFeePpm,
|
||||
bool _stable
|
||||
) internal returns (PartyPool) {
|
||||
// default protocol fee/off parameters (per your instruction) - set to 0 / address(0)
|
||||
uint256 protocolFeePpm = 0;
|
||||
address protocolAddr = address(0);
|
||||
|
||||
return _stable && tokens_.length == 2 ?
|
||||
new PartyPoolBalancedPair(
|
||||
name_,
|
||||
@@ -46,8 +44,8 @@ library Deploy {
|
||||
_kappa,
|
||||
_swapFeePpm,
|
||||
_flashFeePpm,
|
||||
protocolFeePpm,
|
||||
protocolAddr,
|
||||
PROTOCOL_FEE_PPM,
|
||||
PROTOCOL_FEE_RECEIVER,
|
||||
new PartyPoolSwapImpl(),
|
||||
new PartyPoolMintImpl()
|
||||
) :
|
||||
@@ -59,8 +57,8 @@ library Deploy {
|
||||
_kappa,
|
||||
_swapFeePpm,
|
||||
_flashFeePpm,
|
||||
protocolFeePpm,
|
||||
protocolAddr,
|
||||
PROTOCOL_FEE_PPM,
|
||||
PROTOCOL_FEE_RECEIVER,
|
||||
new PartyPoolSwapImpl(),
|
||||
new PartyPoolMintImpl()
|
||||
);
|
||||
|
||||
@@ -146,8 +146,8 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
/// @inheritdoc IPartyPool
|
||||
function initialMint(address receiver, uint256 lpTokens) external
|
||||
returns (uint256 lpMinted) {
|
||||
bytes memory data = abi.encodeWithSignature(
|
||||
"initialMint(address,uint256,int128)",
|
||||
bytes memory data = abi.encodeWithSelector(
|
||||
PartyPoolMintImpl.initialMint.selector,
|
||||
receiver,
|
||||
lpTokens,
|
||||
KAPPA
|
||||
@@ -164,8 +164,8 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
/// @param deadline timestamp after which the transaction will revert. Pass 0 to ignore.
|
||||
function mint(address payer, address receiver, uint256 lpTokenAmount, uint256 deadline) external
|
||||
returns (uint256 lpMinted) {
|
||||
bytes memory data = abi.encodeWithSignature(
|
||||
"mint(address,address,uint256,uint256)",
|
||||
bytes memory data = abi.encodeWithSelector(
|
||||
PartyPoolMintImpl.mint.selector,
|
||||
payer,
|
||||
receiver,
|
||||
lpTokenAmount,
|
||||
@@ -183,8 +183,8 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
/// @param deadline timestamp after which the transaction will revert. Pass 0 to ignore.
|
||||
function burn(address payer, address receiver, uint256 lpAmount, uint256 deadline) external
|
||||
returns (uint256[] memory withdrawAmounts) {
|
||||
bytes memory data = abi.encodeWithSignature(
|
||||
"burn(address,address,uint256,uint256)",
|
||||
bytes memory data = abi.encodeWithSelector(
|
||||
PartyPoolMintImpl.burn.selector,
|
||||
payer,
|
||||
receiver,
|
||||
lpAmount,
|
||||
@@ -226,11 +226,19 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
(uint256 totalTransferAmount, uint256 amountOutUint, int128 amountInInternalUsed, int128 amountOutInternal, , uint256 feeUint) =
|
||||
_quoteSwapExactIn(inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice);
|
||||
|
||||
// Transfer tokens
|
||||
tokens[inputTokenIndex].safeTransferFrom(payer, address(this), totalTransferAmount);
|
||||
uint256 balIAfter = IERC20(tokens[inputTokenIndex]).balanceOf(address(this));
|
||||
tokens[outputTokenIndex].safeTransfer(receiver, amountOutUint);
|
||||
uint256 balJAfter = IERC20(tokens[outputTokenIndex]).balanceOf(address(this));
|
||||
// Cache token references for fewer SLOADs
|
||||
IERC20 tokenIn = tokens[inputTokenIndex];
|
||||
IERC20 tokenOut = tokens[outputTokenIndex];
|
||||
|
||||
// Transfer tokens in
|
||||
tokenIn.safeTransferFrom(payer, address(this), 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
|
||||
tokenOut.safeTransfer(receiver, amountOutUint);
|
||||
|
||||
// Accrue protocol share (floor) from the fee on input token
|
||||
if (PROTOCOL_FEE_PPM > 0 && feeUint > 0) {
|
||||
@@ -240,14 +248,17 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
}
|
||||
}
|
||||
|
||||
// Update cached uint balances for i and j using effective balances (onchain - owed)
|
||||
_recordCachedBalance(inputTokenIndex, balIAfter);
|
||||
_recordCachedBalance(outputTokenIndex, balJAfter);
|
||||
// Inline _recordCachedBalance: ensure onchain >= owed then set cached = onchain - owed
|
||||
require(balIAfter >= protocolFeesOwed[inputTokenIndex], "balance < protocol owed");
|
||||
cachedUintBalances[inputTokenIndex] = balIAfter - protocolFeesOwed[inputTokenIndex];
|
||||
|
||||
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);
|
||||
|
||||
emit Swap(payer, receiver, tokens[inputTokenIndex], tokens[outputTokenIndex], totalTransferAmount, amountOutUint);
|
||||
emit Swap(payer, receiver, tokenIn, tokenOut, totalTransferAmount, amountOutUint);
|
||||
|
||||
return (totalTransferAmount, amountOutUint, feeUint);
|
||||
}
|
||||
@@ -275,8 +286,6 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
)
|
||||
{
|
||||
uint256 n = tokens.length;
|
||||
require(inputTokenIndex < n && outputTokenIndex < n, "swap: idx");
|
||||
require(maxAmountIn > 0, "swap: input zero");
|
||||
|
||||
// Estimate max net input (fee on gross rounded up, then subtract)
|
||||
(, uint256 netUintForSwap) = _computeFee(maxAmountIn, SWAP_FEE_PPM);
|
||||
@@ -316,8 +325,8 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
int128 limitPrice,
|
||||
uint256 deadline
|
||||
) external returns (uint256 amountInUsed, uint256 amountOut, uint256 fee) {
|
||||
bytes memory data = abi.encodeWithSignature(
|
||||
'swapToLimit(address,address,uint256,uint256,int128,uint256,uint256,uint256)',
|
||||
bytes memory data = abi.encodeWithSelector(
|
||||
PartyPoolSwapImpl.swapToLimit.selector,
|
||||
payer,
|
||||
receiver,
|
||||
inputTokenIndex,
|
||||
@@ -347,8 +356,8 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
uint256 maxAmountIn,
|
||||
uint256 deadline
|
||||
) external returns (uint256 lpMinted) {
|
||||
bytes memory data = abi.encodeWithSignature(
|
||||
"swapMint(address,address,uint256,uint256,uint256,uint256,uint256)",
|
||||
bytes memory data = abi.encodeWithSelector(
|
||||
PartyPoolMintImpl.swapMint.selector,
|
||||
payer,
|
||||
receiver,
|
||||
inputTokenIndex,
|
||||
@@ -377,8 +386,8 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
uint256 inputTokenIndex,
|
||||
uint256 deadline
|
||||
) external returns (uint256 amountOutUint) {
|
||||
bytes memory data = abi.encodeWithSignature(
|
||||
"burnSwap(address,address,uint256,uint256,uint256,uint256,uint256)",
|
||||
bytes memory data = abi.encodeWithSelector(
|
||||
PartyPoolMintImpl.burnSwap.selector,
|
||||
payer,
|
||||
receiver,
|
||||
lpAmount,
|
||||
@@ -422,13 +431,15 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
||||
}
|
||||
}
|
||||
|
||||
require(token.transfer(address(receiver), amount));
|
||||
token.safeTransfer(address(receiver), amount);
|
||||
require(receiver.onFlashLoan(msg.sender, address(token), amount, fee, data) == FLASH_CALLBACK_SUCCESS);
|
||||
require(token.transferFrom(address(receiver), address(this), amount + fee));
|
||||
token.safeTransferFrom(address(receiver), address(this), amount + fee);
|
||||
|
||||
// Update cached balance for the borrowed token
|
||||
uint256 balAfter = token.balanceOf(address(this));
|
||||
_recordCachedBalance(tokenIndex, balAfter);
|
||||
// Inline _recordCachedBalance logic
|
||||
require(balAfter >= protocolFeesOwed[tokenIndex], "balance < protocol owed");
|
||||
cachedUintBalances[tokenIndex] = balAfter - protocolFeesOwed[tokenIndex];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,11 +78,4 @@ abstract contract PartyPoolBase is ERC20Internal, ReentrancyGuard, PartyPoolHelp
|
||||
return floorValue;
|
||||
}
|
||||
|
||||
/// @dev Helper to record cached balances as effectiveBalance = onchain - owed. Reverts if owed > onchain.
|
||||
function _recordCachedBalance(uint256 idx, uint256 onchainBal) internal {
|
||||
uint256 owed = protocolFeesOwed[idx];
|
||||
require(onchainBal >= owed, "balance < protocol owed");
|
||||
cachedUintBalances[idx] = onchainBal - owed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -87,9 +87,12 @@ contract PartyPoolSwapImpl is PartyPoolBase {
|
||||
}
|
||||
}
|
||||
|
||||
// Update caches to effective balances
|
||||
_recordCachedBalance(inputTokenIndex, balIAfter);
|
||||
_recordCachedBalance(outputTokenIndex, balJAfter);
|
||||
// Update caches to effective balances (inline _recordCachedBalance)
|
||||
require(balIAfter >= protocolFeesOwed[inputTokenIndex], "balance < protocol owed");
|
||||
cachedUintBalances[inputTokenIndex] = balIAfter - protocolFeesOwed[inputTokenIndex];
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user