forked from Uniswap/v4-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProtocolFeeLibrary.sol
43 lines (36 loc) · 1.82 KB
/
ProtocolFeeLibrary.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.20;
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 & 0xfff);
}
function getOneForZeroFee(uint24 self) internal pure returns (uint16) {
return uint16(self >> 12);
}
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)
}
}
// 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 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)
}
}
}