-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactor import statements and add new gas test Refactored import statements in ProtocolFeeLibrary.t.sol and added a new test in PoolManager.t.sol to check the gas usage when setting the protocol fee. The changes in import statements are done to follow the file path consistency and the new gas test will help in stress testing to evaluate the gas cost for a particular operation. * Optimize `ProtocolFeeLibrary.validate` Refactored and optimized the `validate` function in the `ProtocolFeeLibrary.sol` file. The logic for validating the fee has been simplified and compressed using assembly language. This results in a reduction in bytecode sizes in several snapshots including.poolManager, initialize, and set protocol fee. * Add gas test for `calculateSwapFee` This commit introduces a gas test for the `calculateSwapFee` function inside the `ProtocolFeeLibraryTest` contract. With the addition of `GasSnapshot` import, it now tracks the gas consumption of this specific function, helping us to optimize efficiency and performance. * Refactor `calculateSwapFee` function to use assembly The `calculateSwapFee` function in the `ProtocolFeeLibrary.sol` file has been rewritten to use assembly for performance optimization. This improves efficiency by reducing gas usage, reflected in the bytecode size reduction, which is captured by the snapshot changes. Operating at a lower level with assembly allows us to manage resources more directly. * Change visibility of protocol fee thresholds * Optimize `isValidProtocolFee` further * Apply review comments
- Loading branch information
Showing
8 changed files
with
41 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
33 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
61902 | ||
61862 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
21934 | ||
21878 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
32415 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
180456 | ||
180453 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,43 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity ^0.8.20; | ||
|
||
import "./UnsafeMath.sol"; | ||
|
||
library ProtocolFeeLibrary { | ||
// Max protocol fee is 0.1% (1000 pips) | ||
uint16 public constant MAX_PROTOCOL_FEE = 1000; | ||
|
||
// Thresholds used for optimized bounds checks on protocol fees | ||
uint24 internal constant FEE_0_THRESHOLD = 1001; | ||
uint24 internal constant FEE_1_THRESHOLD = 1001 << 12; | ||
|
||
// the protocol fee is represented in hundredths of a bip | ||
uint256 internal constant PIPS_DENOMINATOR = 1_000_000; | ||
|
||
function getZeroForOneFee(uint24 self) internal pure returns (uint16) { | ||
return uint16(self & (4096 - 1)); | ||
return uint16(self & 0xfff); | ||
} | ||
|
||
function getOneForZeroFee(uint24 self) internal pure returns (uint16) { | ||
return uint16(self >> 12); | ||
} | ||
|
||
function isValidProtocolFee(uint24 self) internal pure returns (bool) { | ||
if (self != 0) { | ||
uint16 fee0 = getZeroForOneFee(self); | ||
uint16 fee1 = getOneForZeroFee(self); | ||
// The fee is represented in pips and it cannot be greater than the MAX_PROTOCOL_FEE. | ||
if ((fee0 > MAX_PROTOCOL_FEE) || (fee1 > MAX_PROTOCOL_FEE)) { | ||
return false; | ||
} | ||
function isValidProtocolFee(uint24 self) internal pure returns (bool valid) { | ||
// Equivalent to: getZeroForOneFee(self) <= MAX_PROTOCOL_FEE && getOneForZeroFee(self) <= MAX_PROTOCOL_FEE | ||
assembly { | ||
let isZeroForOneFeeOk := lt(and(self, 0xfff), FEE_0_THRESHOLD) | ||
let isOneForZeroFeeOk := lt(self, FEE_1_THRESHOLD) | ||
valid := and(isZeroForOneFeeOk, isOneForZeroFeeOk) | ||
} | ||
return true; | ||
} | ||
|
||
// The protocol fee is taken from the input amount first and then the LP fee is taken from the remaining | ||
// The swap fee is capped at 100% | ||
// Equivalent to protocolFee + lpFee(1_000_000 - protocolFee) / 1_000_000 | ||
function calculateSwapFee(uint24 self, uint24 lpFee) internal pure returns (uint24) { | ||
unchecked { | ||
uint256 numerator = uint256(self) * uint256(lpFee); | ||
return uint24(uint256(self) + lpFee - UnsafeMath.divRoundingUp(numerator, PIPS_DENOMINATOR)); | ||
function calculateSwapFee(uint24 self, uint24 lpFee) internal pure returns (uint24 swapFee) { | ||
// protocolFee + lpFee - (protocolFee * lpFee / 1_000_000). Div rounds up to favor LPs over the protocol. | ||
assembly { | ||
let numerator := mul(self, lpFee) | ||
let divRoundingUp := add(div(numerator, PIPS_DENOMINATOR), gt(mod(numerator, PIPS_DENOMINATOR), 0)) | ||
swapFee := sub(add(self, lpFee), divRoundingUp) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters