Untitled diff
18 removals
Words removed | 23 |
Total words | 1069 |
Words removed (%) | 2.15 |
562 lines
96 additions
Words added | 190 |
Total words | 1236 |
Words added (%) | 15.37 |
640 lines
pragma solidity 0.8.10;
pragma solidity ^0.8.20;
import {EnumerableSet} from "openzeppelin/utils/structs/EnumerableSet.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {EnumerableMap} from "openzeppelin/utils/structs/EnumerableMap.sol";
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {IERC20} from "openzeppelin/token/ERC20/IERC20.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable2Step, Ownable} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {PairParameterHelper} from "./libraries/PairParameterHelper.sol";
import {PairParameterHelper} from "./libraries/PairParameterHelper.sol";
import {Encoded} from "./libraries/math/Encoded.sol";
import {Encoded} from "./libraries/math/Encoded.sol";
import {ImmutableClone} from "./libraries/ImmutableClone.sol";
import {ImmutableClone} from "./libraries/ImmutableClone.sol";
import {PendingOwnable} from "./libraries/PendingOwnable.sol";
import {PriceHelper} from "./libraries/PriceHelper.sol";
import {PriceHelper} from "./libraries/PriceHelper.sol";
import {SafeCast} from "./libraries/math/SafeCast.sol";
import {SafeCast} from "./libraries/math/SafeCast.sol";
import {Hooks} from "./libraries/Hooks.sol";
import {ILBFactory} from "./interfaces/ILBFactory.sol";
import {ILBFactory} from "./interfaces/ILBFactory.sol";
import {ILBPair} from "./interfaces/ILBPair.sol";
import {ILBPair} from "./interfaces/ILBPair.sol";
import {ILBHooks} from "./interfaces/ILBHooks.sol";
contract LBFactory is PendingOwnable, ILBFactory {
contract LBFactory is Ownable2Step, AccessControl, ILBFactory {
using SafeCast for uint256;
using SafeCast for uint256;
using Encoded for bytes32;
using Encoded for bytes32;
using PairParameterHelper for bytes32;
using PairParameterHelper for bytes32;
using EnumerableSet for EnumerableSet.AddressSet;
using EnumerableSet for EnumerableSet.AddressSet;
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableMap for EnumerableMap.UintToUintMap;
using EnumerableMap for EnumerableMap.UintToUintMap;
bytes32 public constant LB_HOOKS_MANAGER_ROLE =
keccak256("LB_HOOKS_MANAGER_ROLE");
uint256 private constant _OFFSET_IS_PRESET_OPEN = 255;
uint256 private constant _OFFSET_IS_PRESET_OPEN = 255;
uint256 private constant _MIN_BIN_STEP = 1;
uint256 private constant _MIN_BIN_STEP = 1;
uint256 private constant _MAX_FLASHLOAN_FEE = 0.1e18;
uint256 private constant _MAX_FLASHLOAN_FEE = 0.1e18;
address private _feeRecipient;
address private _feeRecipient;
uint256 private _flashLoanFee;
uint256 private _flashLoanFee;
address private _lbPairImplementation;
address private _lbPairImplementation;
ILBPair[] private _allLBPairs;
ILBPair[] private _allLBPairs;
mapping(IERC20 => mapping(IERC20 => mapping(uint256 => LBPairInformation)))
mapping(IERC20 => mapping(IERC20 => mapping(uint256 => LBPairInformation)))
private _lbPairsInfo;
private _lbPairsInfo;
EnumerableMap.UintToUintMap private _presets;
EnumerableMap.UintToUintMap private _presets;
EnumerableSet.AddressSet private _quoteAssetWhitelist;
EnumerableSet.AddressSet private _quoteAssetWhitelist;
mapping(IERC20 => mapping(IERC20 => EnumerableSet.UintSet))
mapping(IERC20 => mapping(IERC20 => EnumerableSet.UintSet))
private _availableLBPairBinSteps;
private _availableLBPairBinSteps;
constructor(address feeRecipient, uint256 flashLoanFee) {
constructor(
address feeRecipient,
address initialOwner,
uint256 flashLoanFee
) Ownable(initialOwner) {
if (flashLoanFee > _MAX_FLASHLOAN_FEE)
if (flashLoanFee > _MAX_FLASHLOAN_FEE)
revert LBFactory__FlashLoanFeeAboveMax(
revert LBFactory__FlashLoanFeeAboveMax(
flashLoanFee,
flashLoanFee,
_MAX_FLASHLOAN_FEE
_MAX_FLASHLOAN_FEE
);
);
_setFeeRecipient(feeRecipient);
_setFeeRecipient(feeRecipient);
_flashLoanFee = flashLoanFee;
_flashLoanFee = flashLoanFee;
emit FlashLoanFeeSet(0, flashLoanFee);
emit FlashLoanFeeSet(0, flashLoanFee);
}
}
function getMinBinStep()
function getMinBinStep()
external
external
pure
pure
override
override
returns (uint256 minBinStep)
returns (uint256 minBinStep)
{
{
return _MIN_BIN_STEP;
return _MIN_BIN_STEP;
}
}
function getFeeRecipient()
function getFeeRecipient()
external
external
view
view
override
override
returns (address feeRecipient)
returns (address feeRecipient)
{
{
return _feeRecipient;
return _feeRecipient;
}
}
function getMaxFlashLoanFee()
function getMaxFlashLoanFee()
external
external
pure
pure
override
override
returns (uint256 maxFee)
returns (uint256 maxFee)
{
{
return _MAX_FLASHLOAN_FEE;
return _MAX_FLASHLOAN_FEE;
}
}
function getFlashLoanFee()
function getFlashLoanFee()
external
external
view
view
override
override
returns (uint256 flashLoanFee)
returns (uint256 flashLoanFee)
{
{
return _flashLoanFee;
return _flashLoanFee;
}
}
function getLBPairImplementation()
function getLBPairImplementation()
external
external
view
view
override
override
returns (address lbPairImplementation)
returns (address lbPairImplementation)
{
{
return _lbPairImplementation;
return _lbPairImplementation;
}
}
function getNumberOfLBPairs()
function getNumberOfLBPairs()
external
external
view
view
override
override
returns (uint256 lbPairNumber)
returns (uint256 lbPairNumber)
{
{
return _allLBPairs.length;
return _allLBPairs.length;
}
}
function getLBPairAtIndex(uint256 index)
function getLBPairAtIndex(uint256 index)
external
external
view
view
override
override
returns (ILBPair lbPair)
returns (ILBPair lbPair)
{
{
return _allLBPairs[index];
return _allLBPairs[index];
}
}
function getNumberOfQuoteAssets()
function getNumberOfQuoteAssets()
external
external
view
view
override
override
returns (uint256 numberOfQuoteAssets)
returns (uint256 numberOfQuoteAssets)
{
{
return _quoteAssetWhitelist.length();
return _quoteAssetWhitelist.length();
}
}
function getQuoteAssetAtIndex(uint256 index)
function getQuoteAssetAtIndex(uint256 index)
external
external
view
view
override
override
returns (IERC20 asset)
returns (IERC20 asset)
{
{
return IERC20(_quoteAssetWhitelist.at(index));
return IERC20(_quoteAssetWhitelist.at(index));
}
}
function isQuoteAsset(IERC20 token)
function isQuoteAsset(IERC20 token)
external
external
view
view
override
override
returns (bool isQuote)
returns (bool isQuote)
{
{
return _quoteAssetWhitelist.contains(address(token));
return _quoteAssetWhitelist.contains(address(token));
}
}
function getLBPairInformation(
function getLBPairInformation(
IERC20 tokenA,
IERC20 tokenA,
IERC20 tokenB,
IERC20 tokenB,
uint256 binStep
uint256 binStep
)
)
external
external
view
view
override
override
returns (LBPairInformation memory lbPairInformation)
returns (LBPairInformation memory lbPairInformation)
{
{
return _getLBPairInformation(tokenA, tokenB, binStep);
return _getLBPairInformation(tokenA, tokenB, binStep);
}
}
function getPreset(uint256 binStep)
function getPreset(uint256 binStep)
external
external
view
view
override
override
returns (
returns (
uint256 baseFactor,
uint256 baseFactor,
uint256 filterPeriod,
uint256 filterPeriod,
uint256 decayPeriod,
uint256 decayPeriod,
uint256 reductionFactor,
uint256 reductionFactor,
uint256 variableFeeControl,
uint256 variableFeeControl,
uint256 protocolShare,
uint256 protocolShare,
uint256 maxVolatilityAccumulator,
uint256 maxVolatilityAccumulator,
bool isOpen
bool isOpen
)
)
{
{
if (!_presets.contains(binStep))
if (!_presets.contains(binStep))
revert LBFactory__BinStepHasNoPreset(binStep);
revert LBFactory__BinStepHasNoPreset(binStep);
bytes32 preset = bytes32(_presets.get(binStep));
bytes32 preset = bytes32(_presets.get(binStep));
baseFactor = preset.getBaseFactor();
baseFactor = preset.getBaseFactor();
filterPeriod = preset.getFilterPeriod();
filterPeriod = preset.getFilterPeriod();
decayPeriod = preset.getDecayPeriod();
decayPeriod = preset.getDecayPeriod();
reductionFactor = preset.getReductionFactor();
reductionFactor = preset.getReductionFactor();
variableFeeControl = preset.getVariableFeeControl();
variableFeeControl = preset.getVariableFeeControl();
protocolShare = preset.getProtocolShare();
protocolShare = preset.getProtocolShare();
maxVolatilityAccumulator = preset.getMaxVolatilityAccumulator();
maxVolatilityAccumulator = preset.getMaxVolatilityAccumulator();
isOpen = preset.decodeBool(_OFFSET_IS_PRESET_OPEN);
isOpen = preset.decodeBool(_OFFSET_IS_PRESET_OPEN);
}
}
function getAllBinSteps()
function getAllBinSteps()
external
external
view
view
override
override
returns (uint256[] memory binStepWithPreset)
returns (uint256[] memory binStepWithPreset)
{
{
return _presets.keys();
return _presets.keys();
}
}
function getOpenBinSteps()
function getOpenBinSteps()
external
external
view
view
override
override
returns (uint256[] memory openBinStep)
returns (uint256[] memory openBinStep)
{
{
uint256 length = _presets.length();
uint256 length = _presets.length();
if (length > 0) {
if (length > 0) {
openBinStep = new uint256[](length);
openBinStep = new uint256[](length);
uint256 index;
uint256 index;
for (uint256 i; i < length; ++i) {
for (uint256 i; i < length; ++i) {
(uint256 binStep, uint256 preset) = _presets.at(i);
(uint256 binStep, uint256 preset) = _presets.at(i);
if (_isPresetOpen(bytes32(preset))) {
if (_isPresetOpen(bytes32(preset))) {
openBinStep[index] = binStep;
openBinStep[index] = binStep;
index++;
index++;
}
}
}
}
if (index < length) {
if (index < length) {
assembly {
assembly {
mstore(openBinStep, index)
mstore(openBinStep, index)
}
}
}
}
}
}
}
}
function getAllLBPairs(IERC20 tokenX, IERC20 tokenY)
function getAllLBPairs(IERC20 tokenX, IERC20 tokenY)
external
external
view
view
override
override
returns (LBPairInformation[] memory lbPairsAvailable)
returns (LBPairInformation[] memory lbPairsAvailable)
{
{
unchecked {
unchecked {
(IERC20 tokenA, IERC20 tokenB) = _sortTokens(tokenX, tokenY);
(IERC20 tokenA, IERC20 tokenB) = _sortTokens(tokenX, tokenY);
EnumerableSet.UintSet storage addressSet = _availableLBPairBinSteps[
EnumerableSet.UintSet storage addressSet = _availableLBPairBinSteps[
tokenA
tokenA
][tokenB];
][tokenB];
uint256 length = addressSet.length();
uint256 length = addressSet.length();
if (length > 0) {
if (length > 0) {
lbPairsAvailable = new LBPairInformation[](length);
lbPairsAvailable = new LBPairInformation[](length);
mapping(uint256 => LBPairInformation)
mapping(uint256 => LBPairInformation)
storage lbPairsInfo = _lbPairsInfo[tokenA][tokenB];
storage lbPairsInfo = _lbPairsInfo[tokenA][tokenB];
for (uint256 i = 0; i < length; ++i) {
for (uint256 i = 0; i < length; ++i) {
uint16 binStep = addressSet.at(i).safe16();
uint16 binStep = addressSet.at(i).safe16();
lbPairsAvailable[i] = LBPairInformation({
lbPairsAvailable[i] = LBPairInformation({
binStep: binStep,
binStep: binStep,
LBPair: lbPairsInfo[binStep].LBPair,
LBPair: lbPairsInfo[binStep].LBPair,
createdByOwner: lbPairsInfo[binStep].createdByOwner,
createdByOwner: lbPairsInfo[binStep].createdByOwner,
ignoredForRouting: lbPairsInfo[binStep]
ignoredForRouting: lbPairsInfo[binStep]
.ignoredForRouting
.ignoredForRouting
});
});
}
}
}
}
}
}
}
}
function setLBPairImplementation(address newLBPairImplementation)
function setLBPairImplementation(address newLBPairImplementation)
external
external
override
override
onlyOwner
onlyOwner
{
{
if (ILBPair(newLBPairImplementation).getFactory() != this) {
if (ILBPair(newLBPairImplementation).getFactory() != this) {
revert LBFactory__LBPairSafetyCheckFailed(newLBPairImplementation);
revert LBFactory__LBPairSafetyCheckFailed(newLBPairImplementation);
}
}
address oldLBPairImplementation = _lbPairImplementation;
address oldLBPairImplementation = _lbPairImplementation;
if (oldLBPairImplementation == newLBPairImplementation) {
if (oldLBPairImplementation == newLBPairImplementation) {
revert LBFactory__SameImplementation(newLBPairImplementation);
revert LBFactory__SameImplementation(newLBPairImplementation);
}
}
_lbPairImplementation = newLBPairImplementation;
_lbPairImplementation = newLBPairImplementation;
emit LBPairImplementationSet(
emit LBPairImplementationSet(
oldLBPairImplementation,
oldLBPairImplementation,
newLBPairImplementation
newLBPairImplementation
);
);
}
}
function createLBPair(
function createLBPair(
IERC20 tokenX,
IERC20 tokenX,
IERC20 tokenY,
IERC20 tokenY,
uint24 activeId,
uint24 activeId,
uint16 binStep
uint16 binStep
) external override returns (ILBPair pair) {
) external override returns (ILBPair pair) {
if (!_presets.contains(binStep))
if (!_presets.contains(binStep))
revert LBFactory__BinStepHasNoPreset(binStep);
revert LBFactory__BinStepHasNoPreset(binStep);
bytes32 preset = bytes32(_presets.get(binStep));
bytes32 preset = bytes32(_presets.get(binStep));
bool isOwner = msg.sender == owner();
bool isOwner = msg.sender == owner();
if (!_isPresetOpen(preset) && !isOwner) {
if (!_isPresetOpen(preset) && !isOwner) {
revert LBFactory__PresetIsLockedForUsers(msg.sender, binStep);
revert LBFactory__PresetIsLockedForUsers(msg.sender, binStep);
}
}
if (!_quoteAssetWhitelist.contains(address(tokenY)))
if (!_quoteAssetWhitelist.contains(address(tokenY)))
revert LBFactory__QuoteAssetNotWhitelisted(tokenY);
revert LBFactory__QuoteAssetNotWhitelisted(tokenY);
if (tokenX == tokenY) revert LBFactory__IdenticalAddresses(tokenX);
if (tokenX == tokenY) revert LBFactory__IdenticalAddresses(tokenX);
PriceHelper.getPriceFromId(activeId, binStep);
PriceHelper.getPriceFromId(activeId, binStep);
(IERC20 tokenA, IERC20 tokenB) = _sortTokens(tokenX, tokenY);
(IERC20 tokenA, IERC20 tokenB) = _sortTokens(tokenX, tokenY);
if (address(tokenA) == address(0)) revert LBFactory__AddressZero();
if (address(tokenA) == address(0)) revert LBFactory__AddressZero();
if (
if (
address(_lbPairsInfo[tokenA][tokenB][binStep].LBPair) != address(0)
address(_lbPairsInfo[tokenA][tokenB][binStep].LBPair) != address(0)
) {
) {
revert LBFactory__LBPairAlreadyExists(tokenX, tokenY, binStep);
revert LBFactory__LBPairAlreadyExists(tokenX, tokenY, binStep);
}
}
{
{
address implementation = _lbPairImplementation;
address implementation = _lbPairImplementation;
if (implementation == address(0))
if (implementation == address(0))
revert LBFactory__ImplementationNotSet();
revert LBFactory__ImplementationNotSet();
pair = ILBPair(
pair = ILBPair(
ImmutableClone.cloneDeterministic(
ImmutableClone.cloneDeterministic(
implementation,
implementation,
abi.encodePacked(tokenX, tokenY, binStep),
abi.encodePacked(tokenX, tokenY, binStep),
keccak256(abi.encode(tokenA, tokenB, binStep))
keccak256(abi.encode(tokenA, tokenB, binStep))
)
)
);
);
}
}
Text moved to lines 365-375
pair.initialize(
preset.getBaseFactor(),
preset.getFilterPeriod(),
preset.getDecayPeriod(),
preset.getReductionFactor(),
preset.getVariableFeeControl(),
preset.getProtocolShare(),
preset.getMaxVolatilityAccumulator(),
activeId
);
_lbPairsInfo[tokenA][tokenB][binStep] = LBPairInformation({
_lbPairsInfo[tokenA][tokenB][binStep] = LBPairInformation({
binStep: binStep,
binStep: binStep,
LBPair: pair,
LBPair: pair,
createdByOwner: isOwner,
createdByOwner: isOwner,
ignoredForRouting: false
ignoredForRouting: false
});
});
_allLBPairs.push(pair);
_allLBPairs.push(pair);
_availableLBPairBinSteps[tokenA][tokenB].add(binStep);
_availableLBPairBinSteps[tokenA][tokenB].add(binStep);
emit LBPairCreated(
emit LBPairCreated(
tokenX,
tokenX,
tokenY,
tokenY,
binStep,
binStep,
pair,
pair,
_allLBPairs.length - 1
_allLBPairs.length - 1
);
);
Text moved from lines 338-348
pair.initialize(
preset.getBaseFactor(),
preset.getFilterPeriod(),
preset.getDecayPeriod(),
preset.getReductionFactor(),
preset.getVariableFeeControl(),
preset.getProtocolShare(),
preset.getMaxVolatilityAccumulator(),
activeId
);
}
}
function setLBPairIgnored(
function setLBPairIgnored(
IERC20 tokenX,
IERC20 tokenX,
IERC20 tokenY,
IERC20 tokenY,
uint16 binStep,
uint16 binStep,
bool ignored
bool ignored
) external override onlyOwner {
) external override onlyOwner {
(IERC20 tokenA, IERC20 tokenB) = _sortTokens(tokenX, tokenY);
(IERC20 tokenA, IERC20 tokenB) = _sortTokens(tokenX, tokenY);
LBPairInformation memory pairInformation = _lbPairsInfo[tokenA][tokenB][
LBPairInformation memory pairInformation = _lbPairsInfo[tokenA][tokenB][
binStep
binStep
];
];
if (address(pairInformation.LBPair) == address(0)) {
if (address(pairInformation.LBPair) == address(0)) {
revert LBFactory__LBPairDoesNotExist(tokenX, tokenY, binStep);
revert LBFactory__LBPairDoesNotExist(tokenX, tokenY, binStep);
}
}
if (pairInformation.ignoredForRouting == ignored)
if (pairInformation.ignoredForRouting == ignored)
revert LBFactory__LBPairIgnoredIsAlreadyInTheSameState();
revert LBFactory__LBPairIgnoredIsAlreadyInTheSameState();
_lbPairsInfo[tokenA][tokenB][binStep].ignoredForRouting = ignored;
_lbPairsInfo[tokenA][tokenB][binStep].ignoredForRouting = ignored;
emit LBPairIgnoredStateChanged(pairInformation.LBPair, ignored);
emit LBPairIgnoredStateChanged(pairInformation.LBPair, ignored);
}
}
function setPreset(
function setPreset(
uint16 binStep,
uint16 binStep,
uint16 baseFactor,
uint16 baseFactor,
uint16 filterPeriod,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint16 reductionFactor,
uint24 variableFeeControl,
uint24 variableFeeControl,
uint16 protocolShare,
uint16 protocolShare,
uint24 maxVolatilityAccumulator,
uint24 maxVolatilityAccumulator,
bool isOpen
bool isOpen
) external override onlyOwner {
) external override onlyOwner {
if (binStep < _MIN_BIN_STEP) revert LBFactory__BinStepTooLow(binStep);
if (binStep < _MIN_BIN_STEP) revert LBFactory__BinStepTooLow(binStep);
bytes32 preset = bytes32(0).setStaticFeeParameters(
bytes32 preset = bytes32(0).setStaticFeeParameters(
baseFactor,
baseFactor,
filterPeriod,
filterPeriod,
decayPeriod,
decayPeriod,
reductionFactor,
reductionFactor,
variableFeeControl,
variableFeeControl,
protocolShare,
protocolShare,
maxVolatilityAccumulator
maxVolatilityAccumulator
);
);
if (isOpen) {
if (isOpen) {
preset = preset.setBool(true, _OFFSET_IS_PRESET_OPEN);
preset = preset.setBool(true, _OFFSET_IS_PRESET_OPEN);
}
}
_presets.set(binStep, uint256(preset));
_presets.set(binStep, uint256(preset));
emit PresetSet(
emit PresetSet(
binStep,
binStep,
baseFactor,
baseFactor,
filterPeriod,
filterPeriod,
decayPeriod,
decayPeriod,
reductionFactor,
reductionFactor,
variableFeeControl,
variableFeeControl,
protocolShare,
protocolShare,
maxVolatilityAccumulator
maxVolatilityAccumulator
);
);
emit PresetOpenStateChanged(binStep, isOpen);
emit PresetOpenStateChanged(binStep, isOpen);
}
}
function setPresetOpenState(uint16 binStep, bool isOpen)
function setPresetOpenState(uint16 binStep, bool isOpen)
external
external
override
override
onlyOwner
onlyOwner
{
{
if (!_presets.contains(binStep))
if (!_presets.contains(binStep))
revert LBFactory__BinStepHasNoPreset(binStep);
revert LBFactory__BinStepHasNoPreset(binStep);
bytes32 preset = bytes32(_presets.get(binStep));
bytes32 preset = bytes32(_presets.get(binStep));
if (preset.decodeBool(_OFFSET_IS_PRESET_OPEN) == isOpen) {
if (preset.decodeBool(_OFFSET_IS_PRESET_OPEN) == isOpen) {
revert LBFactory__PresetOpenStateIsAlreadyInTheSameState();
revert LBFactory__PresetOpenStateIsAlreadyInTheSameState();
}
}
_presets.set(
_presets.set(
binStep,
binStep,
uint256(preset.setBool(isOpen, _OFFSET_IS_PRESET_OPEN))
uint256(preset.setBool(isOpen, _OFFSET_IS_PRESET_OPEN))
);
);
emit PresetOpenStateChanged(binStep, isOpen);
emit PresetOpenStateChanged(binStep, isOpen);
}
}
function removePreset(uint16 binStep) external override onlyOwner {
function removePreset(uint16 binStep) external override onlyOwner {
if (!_presets.remove(binStep))
if (!_presets.remove(binStep))
revert LBFactory__BinStepHasNoPreset(binStep);
revert LBFactory__BinStepHasNoPreset(binStep);
emit PresetRemoved(binStep);
emit PresetRemoved(binStep);
}
}
function setFeesParametersOnPair(
function setFeesParametersOnPair(
IERC20 tokenX,
IERC20 tokenX,
IERC20 tokenY,
IERC20 tokenY,
uint16 binStep,
uint16 binStep,
uint16 baseFactor,
uint16 baseFactor,
uint16 filterPeriod,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint16 reductionFactor,
uint24 variableFeeControl,
uint24 variableFeeControl,
uint16 protocolShare,
uint16 protocolShare,
uint24 maxVolatilityAccumulator
uint24 maxVolatilityAccumulator
) external override onlyOwner {
) external override onlyOwner {
ILBPair lbPair = _getLBPairInformation(tokenX, tokenY, binStep).LBPair;
ILBPair lbPair = _getLBPairInformation(tokenX, tokenY, binStep).LBPair;
if (address(lbPair) == address(0))
if (address(lbPair) == address(0))
revert LBFactory__LBPairNotCreated(tokenX, tokenY, binStep);
revert LBFactory__LBPairNotCreated(tokenX, tokenY, binStep);
lbPair.setStaticFeeParameters(
lbPair.setStaticFeeParameters(
baseFactor,
baseFactor,
filterPeriod,
filterPeriod,
decayPeriod,
decayPeriod,
reductionFactor,
reductionFactor,
variableFeeControl,
variableFeeControl,
protocolShare,
protocolShare,
maxVolatilityAccumulator
maxVolatilityAccumulator
);
);
}
}
function setLBHooksParametersOnPair(
IERC20 tokenX,
IERC20 tokenY,
uint16 binStep,
bytes32 hooksParameters,
bytes calldata onHooksSetData
) external override onlyRole(LB_HOOKS_MANAGER_ROLE) {
if (
Hooks.getHooks(hooksParameters) == address(0) ||
Hooks.getFlags(hooksParameters) == 0
) {
revert LBFactory__InvalidHooksParameters();
}
_setLBHooksParametersOnPair(
tokenX,
tokenY,
binStep,
hooksParameters,
onHooksSetData
);
}
function removeLBHooksOnPair(
IERC20 tokenX,
IERC20 tokenY,
uint16 binStep
) external override onlyRole(LB_HOOKS_MANAGER_ROLE) {
_setLBHooksParametersOnPair(tokenX, tokenY, binStep, 0, new bytes(0));
}
function setFeeRecipient(address feeRecipient) external override onlyOwner {
function setFeeRecipient(address feeRecipient) external override onlyOwner {
_setFeeRecipient(feeRecipient);
_setFeeRecipient(feeRecipient);
}
}
function setFlashLoanFee(uint256 flashLoanFee) external override onlyOwner {
function setFlashLoanFee(uint256 flashLoanFee) external override onlyOwner {
uint256 oldFlashLoanFee = _flashLoanFee;
uint256 oldFlashLoanFee = _flashLoanFee;
if (oldFlashLoanFee == flashLoanFee)
if (oldFlashLoanFee == flashLoanFee)
revert LBFactory__SameFlashLoanFee(flashLoanFee);
revert LBFactory__SameFlashLoanFee(flashLoanFee);
if (flashLoanFee > _MAX_FLASHLOAN_FEE)
if (flashLoanFee > _MAX_FLASHLOAN_FEE)
revert LBFactory__FlashLoanFeeAboveMax(
revert LBFactory__FlashLoanFeeAboveMax(
flashLoanFee,
flashLoanFee,
_MAX_FLASHLOAN_FEE
_MAX_FLASHLOAN_FEE
);
);
_flashLoanFee = flashLoanFee;
_flashLoanFee = flashLoanFee;
emit FlashLoanFeeSet(oldFlashLoanFee, flashLoanFee);
emit FlashLoanFeeSet(oldFlashLoanFee, flashLoanFee);
}
}
function addQuoteAsset(IERC20 quoteAsset) external override onlyOwner {
function addQuoteAsset(IERC20 quoteAsset) external override onlyOwner {
if (!_quoteAssetWhitelist.add(address(quoteAsset))) {
if (!_quoteAssetWhitelist.add(address(quoteAsset))) {
revert LBFactory__QuoteAssetAlreadyWhitelisted(quoteAsset);
revert LBFactory__QuoteAssetAlreadyWhitelisted(quoteAsset);
}
}
emit QuoteAssetAdded(quoteAsset);
emit QuoteAssetAdded(quoteAsset);
}
}
function removeQuoteAsset(IERC20 quoteAsset) external override onlyOwner {
function removeQuoteAsset(IERC20 quoteAsset) external override onlyOwner {
if (!_quoteAssetWhitelist.remove(address(quoteAsset)))
if (!_quoteAssetWhitelist.remove(address(quoteAsset)))
revert LBFactory__QuoteAssetNotWhitelisted(quoteAsset);
revert LBFactory__QuoteAssetNotWhitelisted(quoteAsset);
emit QuoteAssetRemoved(quoteAsset);
emit QuoteAssetRemoved(quoteAsset);
}
}
function _isPresetOpen(bytes32 preset) internal pure returns (bool) {
function _isPresetOpen(bytes32 preset) internal pure returns (bool) {
return preset.decodeBool(_OFFSET_IS_PRESET_OPEN);
return preset.decodeBool(_OFFSET_IS_PRESET_OPEN);
}
}
function _setFeeRecipient(address feeRecipient) internal {
function _setFeeRecipient(address feeRecipient) internal {
if (feeRecipient == address(0)) revert LBFactory__AddressZero();
if (feeRecipient == address(0)) revert LBFactory__AddressZero();
address oldFeeRecipient = _feeRecipient;
address oldFeeRecipient = _feeRecipient;
if (oldFeeRecipient == feeRecipient)
if (oldFeeRecipient == feeRecipient)
revert LBFactory__SameFeeRecipient(_feeRecipient);
revert LBFactory__SameFeeRecipient(_feeRecipient);
_feeRecipient = feeRecipient;
_feeRecipient = feeRecipient;
emit FeeRecipientSet(oldFeeRecipient, feeRecipient);
emit FeeRecipientSet(oldFeeRecipient, feeRecipient);
}
}
function forceDecay(ILBPair pair) external override onlyOwner {
function forceDecay(ILBPair pair) external override onlyOwner {
pair.forceDecay();
pair.forceDecay();
}
}
function _getLBPairInformation(
function _getLBPairInformation(
IERC20 tokenA,
IERC20 tokenA,
IERC20 tokenB,
IERC20 tokenB,
uint256 binStep
uint256 binStep
) private view returns (LBPairInformation memory) {
) private view returns (LBPairInformation memory) {
(tokenA, tokenB) = _sortTokens(tokenA, tokenB);
(tokenA, tokenB) = _sortTokens(tokenA, tokenB);
return _lbPairsInfo[tokenA][tokenB][binStep];
return _lbPairsInfo[tokenA][tokenB][binStep];
}
}
function _sortTokens(IERC20 tokenA, IERC20 tokenB)
function _sortTokens(IERC20 tokenA, IERC20 tokenB)
private
private
pure
pure
returns (IERC20, IERC20)
returns (IERC20, IERC20)
{
{
if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
return (tokenA, tokenB);
return (tokenA, tokenB);
}
}
function _setLBHooksParametersOnPair(
IERC20 tokenX,
IERC20 tokenY,
uint16 binStep,
bytes32 hooksParameters,
bytes memory onHooksSetData
) internal {
ILBPair lbPair = _getLBPairInformation(tokenX, tokenY, binStep).LBPair;
if (address(lbPair) == address(0))
revert LBFactory__LBPairNotCreated(tokenX, tokenY, binStep);
if (lbPair.getLBHooksParameters() == hooksParameters)
revert LBFactory__SameHooksParameters(hooksParameters);
lbPair.setHooksParameters(hooksParameters, onHooksSetData);
}
function hasRole(bytes32 role, address account)
public
view
override
returns (bool)
{
if (role == DEFAULT_ADMIN_ROLE) return account == owner();
return super.hasRole(role, account);
}
function _grantRole(bytes32 role, address account)
internal
override
returns (bool)
{
if (role == DEFAULT_ADMIN_ROLE)
revert LBFactory__CannotGrantDefaultAdminRole();
return super._grantRole(role, account);
}
}
}