cached pair fees
This commit is contained in:
@@ -58,7 +58,7 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
|
||||
function fees() external view returns (uint256[] memory) { return _fees; }
|
||||
|
||||
/// @notice Effective combined fee in ppm for (i as input, j as output)
|
||||
function fee(uint256 i, uint256 j) external view returns (uint256) { return _pairFeePpm(i,j); }
|
||||
function fee(uint256 i, uint256 j) external view returns (uint256) { return _pairFeePpmView(i,j); }
|
||||
|
||||
/// @notice Flash-loan fee in parts-per-million (ppm) applied to flash borrow amounts.
|
||||
uint256 private immutable FLASH_FEE_PPM;
|
||||
@@ -240,7 +240,7 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
|
||||
uint256 maxAmountIn,
|
||||
int128 limitPrice
|
||||
) external view returns (uint256 amountIn, uint256 amountOut, uint256 inFee) {
|
||||
(uint256 grossIn, uint256 outUint,,,, uint256 feeUint) = _quoteSwapExactIn(inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice);
|
||||
(uint256 grossIn, uint256 outUint,,,, uint256 feeUint) = _quoteSwapExactIn(inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, _pairFeePpmView(inputTokenIndex, outputTokenIndex));
|
||||
return (grossIn, outUint, feeUint);
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
|
||||
|
||||
// Compute amounts using the same path as views
|
||||
(uint256 totalTransferAmount, uint256 amountOutUint, int128 amountInInternalUsed, int128 amountOutInternal, , uint256 feeUint) =
|
||||
_quoteSwapExactIn(inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice);
|
||||
_quoteSwapExactIn(inputTokenIndex, outputTokenIndex, maxAmountIn, limitPrice, _pairFeePpm(inputTokenIndex, outputTokenIndex));
|
||||
|
||||
// Cache token references for fewer SLOADs
|
||||
IERC20 tokenIn = _tokens[inputTokenIndex];
|
||||
@@ -309,7 +309,8 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
|
||||
uint256 inputTokenIndex,
|
||||
uint256 outputTokenIndex,
|
||||
uint256 maxAmountIn,
|
||||
int128 limitPrice
|
||||
int128 limitPrice,
|
||||
uint256 feePpm
|
||||
) internal view
|
||||
returns (
|
||||
uint256 grossIn,
|
||||
@@ -321,8 +322,7 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
|
||||
)
|
||||
{
|
||||
// Estimate max net input (fee on gross rounded up, then subtract)
|
||||
uint256 pairFeePpm = _pairFeePpm(inputTokenIndex, outputTokenIndex);
|
||||
(, uint256 netUintForSwap) = _computeFee(maxAmountIn, pairFeePpm);
|
||||
(, uint256 netUintForSwap) = _computeFee(maxAmountIn, feePpm);
|
||||
|
||||
// Convert to internal (floor)
|
||||
int128 deltaInternalI = _uintToInternalFloor(netUintForSwap, _bases[inputTokenIndex]);
|
||||
@@ -338,8 +338,8 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool
|
||||
// Compute gross transfer including fee on the used input (ceil)
|
||||
feeUint = 0;
|
||||
grossIn = amountInUintNoFee;
|
||||
if (pairFeePpm > 0) {
|
||||
feeUint = _ceilFee(amountInUintNoFee, pairFeePpm);
|
||||
if (feePpm > 0) {
|
||||
feeUint = _ceilFee(amountInUintNoFee, feePpm);
|
||||
grossIn += feeUint;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
import "./NativeWrapper.sol";
|
||||
import {ABDKMath64x64} from "../lib/abdk-libraries-solidity/ABDKMath64x64.sol";
|
||||
import {ERC20Internal} from "./ERC20Internal.sol";
|
||||
import {IERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
|
||||
import {LMSRStabilized} from "./LMSRStabilized.sol";
|
||||
import {PartyPoolHelpers} from "./PartyPoolHelpers.sol";
|
||||
import {ReentrancyGuard} from "../lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol";
|
||||
import {SafeERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import {ReentrancyGuard} from "../lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol";
|
||||
import {ERC20Internal} from "./ERC20Internal.sol";
|
||||
import {LMSRStabilized} from "./LMSRStabilized.sol";
|
||||
import {NativeWrapper} from "./NativeWrapper.sol";
|
||||
import {OwnableInternal} from "./OwnableInternal.sol";
|
||||
import {PartyPoolHelpers} from "./PartyPoolHelpers.sol";
|
||||
|
||||
/// @notice Abstract base contract that contains storage and internal helpers only.
|
||||
/// No external/public functions here.
|
||||
@@ -26,6 +26,7 @@ abstract contract PartyPoolBase is OwnableInternal, ERC20Internal, ReentrancyGua
|
||||
|
||||
/// @notice Per-asset swap fees in ppm. Fees are applied on input for swaps; see helpers for composition rules.
|
||||
uint256[] internal _fees;
|
||||
mapping( uint256 => uint256 ) internal _pairFees;
|
||||
|
||||
//
|
||||
// Internal state
|
||||
@@ -92,12 +93,22 @@ abstract contract PartyPoolBase is OwnableInternal, ERC20Internal, ReentrancyGua
|
||||
// We implement this as: ceil( fi + fj - (fi*fj)/1e6 ) for the real-valued expression.
|
||||
// For integer arithmetic with fi,fj in ppm this is equal to: fi + fj - floor( (fi*fj)/1e6 ).
|
||||
// So we compute prod = fi * fj, prodDiv = prod / 1e6 (floor), and return fi + fj - prodDiv.
|
||||
function _pairFeePpm(uint256 i, uint256 j) internal view returns (uint256) {
|
||||
function _pairFeePpmView(uint256 i, uint256 j) internal view returns (uint256) {
|
||||
uint256 fi = _fees[i];
|
||||
uint256 fj = _fees[j];
|
||||
return fi + fj - fi * fj / 1_000_000;
|
||||
}
|
||||
|
||||
function _pairFeePpm(uint256 i, uint256 j) internal returns (uint256 fee) {
|
||||
uint256 key = 1000 * i + j;
|
||||
fee = _pairFees[key];
|
||||
if (fee == 0) {
|
||||
// store fee in cache
|
||||
fee = _pairFeePpmView(i,j);
|
||||
_pairFees[key] = fee;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert uint token amount -> internal 64.64 (floor). Uses ABDKMath64x64.divu which truncates.
|
||||
function _uintToInternalFloor(uint256 amount, uint256 base) internal pure returns (int128) {
|
||||
// internal = amount / base (as Q64.64)
|
||||
|
||||
Reference in New Issue
Block a user