编译器
0.8.10+commit.fc410830
文件 1 的 26:BitMath.sol
pragma solidity 0.8.10;
library BitMath {
function closestBitRight(
uint256 x,
uint8 bit
) internal pure returns (uint256 id) {
unchecked {
uint256 shift = 255 - bit;
x <<= shift;
return (x == 0) ? type(uint256).max : mostSignificantBit(x) - shift;
}
}
function closestBitLeft(
uint256 x,
uint8 bit
) internal pure returns (uint256 id) {
unchecked {
x >>= bit;
return (x == 0) ? type(uint256).max : leastSignificantBit(x) + bit;
}
}
function mostSignificantBit(uint256 x) internal pure returns (uint8 msb) {
assembly {
if gt(x, 0xffffffffffffffffffffffffffffffff) {
x := shr(128, x)
msb := 128
}
if gt(x, 0xffffffffffffffff) {
x := shr(64, x)
msb := add(msb, 64)
}
if gt(x, 0xffffffff) {
x := shr(32, x)
msb := add(msb, 32)
}
if gt(x, 0xffff) {
x := shr(16, x)
msb := add(msb, 16)
}
if gt(x, 0xff) {
x := shr(8, x)
msb := add(msb, 8)
}
if gt(x, 0xf) {
x := shr(4, x)
msb := add(msb, 4)
}
if gt(x, 0x3) {
x := shr(2, x)
msb := add(msb, 2)
}
if gt(x, 0x1) {
msb := add(msb, 1)
}
}
}
function leastSignificantBit(uint256 x) internal pure returns (uint8 lsb) {
assembly {
let sx := shl(128, x)
if iszero(iszero(sx)) {
lsb := 128
x := sx
}
sx := shl(64, x)
if iszero(iszero(sx)) {
x := sx
lsb := add(lsb, 64)
}
sx := shl(32, x)
if iszero(iszero(sx)) {
x := sx
lsb := add(lsb, 32)
}
sx := shl(16, x)
if iszero(iszero(sx)) {
x := sx
lsb := add(lsb, 16)
}
sx := shl(8, x)
if iszero(iszero(sx)) {
x := sx
lsb := add(lsb, 8)
}
sx := shl(4, x)
if iszero(iszero(sx)) {
x := sx
lsb := add(lsb, 4)
}
sx := shl(2, x)
if iszero(iszero(sx)) {
x := sx
lsb := add(lsb, 2)
}
if iszero(iszero(shl(1, x))) {
lsb := add(lsb, 1)
}
lsb := sub(255, lsb)
}
}
}
文件 2 的 26:Constants.sol
pragma solidity 0.8.10;
library Constants {
uint8 internal constant SCALE_OFFSET = 128;
uint256 internal constant SCALE = 1 << SCALE_OFFSET;
uint256 internal constant PRECISION = 1e18;
uint256 internal constant SQUARED_PRECISION = PRECISION * PRECISION;
uint256 internal constant MAX_FEE = 0.1e18;
uint256 internal constant MAX_PROTOCOL_SHARE = 2_500;
uint256 internal constant BASIS_POINT_MAX = 10_000;
bytes32 internal constant CALLBACK_SUCCESS = keccak256("LBPair.onFlashLoan");
}
文件 3 的 26:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 26:ERC20.sol
pragma solidity >=0.8.0;
abstract contract ERC20 {
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
string public name;
string public symbol;
uint8 public immutable decimals;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}
文件 5 的 26:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 6 的 26:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
文件 7 的 26:IJoeFactory.sol
pragma solidity 0.8.10;
interface IJoeFactory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint256);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function migrator() external view returns (address);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function allPairs(uint256) external view returns (address pair);
function allPairsLength() external view returns (uint256);
function createPair(address tokenA, address tokenB) external returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
function setMigrator(address) external;
}
文件 8 的 26:ILBFactory.sol
pragma solidity 0.8.10;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ILBPair} from "./ILBPair.sol";
import {IPendingOwnable} from "./IPendingOwnable.sol";
interface ILBFactory is IPendingOwnable {
error LBFactory__IdenticalAddresses(IERC20 token);
error LBFactory__QuoteAssetNotWhitelisted(IERC20 quoteAsset);
error LBFactory__QuoteAssetAlreadyWhitelisted(IERC20 quoteAsset);
error LBFactory__AddressZero();
error LBFactory__LBPairAlreadyExists(
IERC20 tokenX,
IERC20 tokenY,
uint256 _binStep
);
error LBFactory__LBPairDoesNotExist(
IERC20 tokenX,
IERC20 tokenY,
uint256 binStep
);
error LBFactory__LBPairNotCreated(
IERC20 tokenX,
IERC20 tokenY,
uint256 binStep
);
error LBFactory__FlashLoanFeeAboveMax(uint256 fees, uint256 maxFees);
error LBFactory__BinStepTooLow(uint256 binStep);
error LBFactory__PresetIsLockedForUsers(address user, uint256 binStep);
error LBFactory__LBPairIgnoredIsAlreadyInTheSameState();
error LBFactory__BinStepHasNoPreset(uint256 binStep);
error LBFactory__PresetOpenStateIsAlreadyInTheSameState();
error LBFactory__SameFeeRecipient(address feeRecipient);
error LBFactory__SameFlashLoanFee(uint256 flashLoanFee);
error LBFactory__LBPairSafetyCheckFailed(address LBPairImplementation);
error LBFactory__SameImplementation(address LBPairImplementation);
error LBFactory__ImplementationNotSet();
struct LBPairInformation {
uint16 binStep;
ILBPair LBPair;
bool createdByOwner;
bool ignoredForRouting;
}
event LBPairCreated(
IERC20 indexed tokenX,
IERC20 indexed tokenY,
uint256 indexed binStep,
ILBPair LBPair,
uint256 pid
);
event FeeRecipientSet(address oldRecipient, address newRecipient);
event FlashLoanFeeSet(uint256 oldFlashLoanFee, uint256 newFlashLoanFee);
event LBPairImplementationSet(
address oldLBPairImplementation,
address LBPairImplementation
);
event LBPairIgnoredStateChanged(ILBPair indexed LBPair, bool ignored);
event PresetSet(
uint256 indexed binStep,
uint256 baseFactor,
uint256 filterPeriod,
uint256 decayPeriod,
uint256 reductionFactor,
uint256 variableFeeControl,
uint256 protocolShare,
uint256 maxVolatilityAccumulator
);
event PresetOpenStateChanged(uint256 indexed binStep, bool indexed isOpen);
event PresetRemoved(uint256 indexed binStep);
event QuoteAssetAdded(IERC20 indexed quoteAsset);
event QuoteAssetRemoved(IERC20 indexed quoteAsset);
function getMinBinStep() external pure returns (uint256);
function getFeeRecipient() external view returns (address);
function getMaxFlashLoanFee() external pure returns (uint256);
function getFlashLoanFee() external view returns (uint256);
function getLBPairImplementation() external view returns (address);
function getNumberOfLBPairs() external view returns (uint256);
function getLBPairAtIndex(uint256 id) external returns (ILBPair);
function getNumberOfQuoteAssets() external view returns (uint256);
function getQuoteAssetAtIndex(uint256 index) external view returns (IERC20);
function isQuoteAsset(IERC20 token) external view returns (bool);
function getLBPairInformation(
IERC20 tokenX,
IERC20 tokenY,
uint256 binStep
) external view returns (LBPairInformation memory);
function getPreset(
uint256 binStep
)
external
view
returns (
uint256 baseFactor,
uint256 filterPeriod,
uint256 decayPeriod,
uint256 reductionFactor,
uint256 variableFeeControl,
uint256 protocolShare,
uint256 maxAccumulator,
bool isOpen
);
function getAllBinSteps()
external
view
returns (uint256[] memory presetsBinStep);
function getOpenBinSteps()
external
view
returns (uint256[] memory openBinStep);
function getAllLBPairs(
IERC20 tokenX,
IERC20 tokenY
) external view returns (LBPairInformation[] memory LBPairsBinStep);
function setLBPairImplementation(address lbPairImplementation) external;
function createLBPair(
IERC20 tokenX,
IERC20 tokenY,
uint24 activeId,
uint16 binStep
) external returns (ILBPair pair);
function setLBPairIgnored(
IERC20 tokenX,
IERC20 tokenY,
uint16 binStep,
bool ignored
) external;
function setPreset(
uint16 binStep,
uint16 baseFactor,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint24 variableFeeControl,
uint16 protocolShare,
uint24 maxVolatilityAccumulator,
bool isOpen
) external;
function setPresetOpenState(uint16 binStep, bool isOpen) external;
function removePreset(uint16 binStep) external;
function setFeesParametersOnPair(
IERC20 tokenX,
IERC20 tokenY,
uint16 binStep,
uint16 baseFactor,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint24 variableFeeControl,
uint16 protocolShare,
uint24 maxVolatilityAccumulator
) external;
function setFeeRecipient(address feeRecipient) external;
function setFlashLoanFee(uint256 flashLoanFee) external;
function addQuoteAsset(IERC20 quoteAsset) external;
function removeQuoteAsset(IERC20 quoteAsset) external;
function forceDecay(ILBPair lbPair) external;
}
文件 9 的 26:ILBFlashLoanCallback.sol
pragma solidity 0.8.10;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface ILBFlashLoanCallback {
function LBFlashLoanCallback(
address sender,
IERC20 tokenX,
IERC20 tokenY,
bytes32 amounts,
bytes32 totalFees,
bytes calldata data
) external returns (bytes32);
}
文件 10 的 26:ILBLegacyFactory.sol
pragma solidity 0.8.10;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ILBLegacyPair} from "./ILBLegacyPair.sol";
import {IPendingOwnable} from "./IPendingOwnable.sol";
interface ILBLegacyFactory is IPendingOwnable {
struct LBPairInformation {
uint16 binStep;
ILBLegacyPair LBPair;
bool createdByOwner;
bool ignoredForRouting;
}
event LBPairCreated(
IERC20 indexed tokenX,
IERC20 indexed tokenY,
uint256 indexed binStep,
ILBLegacyPair LBPair,
uint256 pid
);
event FeeRecipientSet(address oldRecipient, address newRecipient);
event FlashLoanFeeSet(uint256 oldFlashLoanFee, uint256 newFlashLoanFee);
event FeeParametersSet(
address indexed sender,
ILBLegacyPair indexed LBPair,
uint256 binStep,
uint256 baseFactor,
uint256 filterPeriod,
uint256 decayPeriod,
uint256 reductionFactor,
uint256 variableFeeControl,
uint256 protocolShare,
uint256 maxVolatilityAccumulator
);
event FactoryLockedStatusUpdated(bool unlocked);
event LBPairImplementationSet(
address oldLBPairImplementation,
address LBPairImplementation
);
event LBPairIgnoredStateChanged(ILBLegacyPair indexed LBPair, bool ignored);
event PresetSet(
uint256 indexed binStep,
uint256 baseFactor,
uint256 filterPeriod,
uint256 decayPeriod,
uint256 reductionFactor,
uint256 variableFeeControl,
uint256 protocolShare,
uint256 maxVolatilityAccumulator,
uint256 sampleLifetime
);
event PresetRemoved(uint256 indexed binStep);
event QuoteAssetAdded(IERC20 indexed quoteAsset);
event QuoteAssetRemoved(IERC20 indexed quoteAsset);
function MAX_FEE() external pure returns (uint256);
function MIN_BIN_STEP() external pure returns (uint256);
function MAX_BIN_STEP() external pure returns (uint256);
function MAX_PROTOCOL_SHARE() external pure returns (uint256);
function LBPairImplementation() external view returns (address);
function getNumberOfQuoteAssets() external view returns (uint256);
function getQuoteAsset(uint256 index) external view returns (IERC20);
function isQuoteAsset(IERC20 token) external view returns (bool);
function feeRecipient() external view returns (address);
function flashLoanFee() external view returns (uint256);
function creationUnlocked() external view returns (bool);
function allLBPairs(uint256 id) external returns (ILBLegacyPair);
function getNumberOfLBPairs() external view returns (uint256);
function getLBPairInformation(
IERC20 tokenX,
IERC20 tokenY,
uint256 binStep
) external view returns (LBPairInformation memory);
function getPreset(
uint16 binStep
)
external
view
returns (
uint256 baseFactor,
uint256 filterPeriod,
uint256 decayPeriod,
uint256 reductionFactor,
uint256 variableFeeControl,
uint256 protocolShare,
uint256 maxAccumulator,
uint256 sampleLifetime
);
function getAllBinSteps()
external
view
returns (uint256[] memory presetsBinStep);
function getAllLBPairs(
IERC20 tokenX,
IERC20 tokenY
) external view returns (LBPairInformation[] memory LBPairsBinStep);
function setLBPairImplementation(address LBPairImplementation) external;
function createLBPair(
IERC20 tokenX,
IERC20 tokenY,
uint24 activeId,
uint16 binStep
) external returns (ILBLegacyPair pair);
function setLBPairIgnored(
IERC20 tokenX,
IERC20 tokenY,
uint256 binStep,
bool ignored
) external;
function setPreset(
uint16 binStep,
uint16 baseFactor,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint24 variableFeeControl,
uint16 protocolShare,
uint24 maxVolatilityAccumulator,
uint16 sampleLifetime
) external;
function removePreset(uint16 binStep) external;
function setFeesParametersOnPair(
IERC20 tokenX,
IERC20 tokenY,
uint16 binStep,
uint16 baseFactor,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint24 variableFeeControl,
uint16 protocolShare,
uint24 maxVolatilityAccumulator
) external;
function setFeeRecipient(address feeRecipient) external;
function setFlashLoanFee(uint256 flashLoanFee) external;
function setFactoryLockedState(bool locked) external;
function addQuoteAsset(IERC20 quoteAsset) external;
function removeQuoteAsset(IERC20 quoteAsset) external;
function forceDecay(ILBLegacyPair LBPair) external;
}
文件 11 的 26:ILBLegacyPair.sol
pragma solidity 0.8.10;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ILBLegacyToken} from "./ILBLegacyToken.sol";
interface ILBLegacyPair is ILBLegacyToken {
struct FeeParameters {
uint16 binStep;
uint16 baseFactor;
uint16 filterPeriod;
uint16 decayPeriod;
uint16 reductionFactor;
uint24 variableFeeControl;
uint16 protocolShare;
uint24 maxVolatilityAccumulated;
uint24 volatilityAccumulated;
uint24 volatilityReference;
uint24 indexRef;
uint40 time;
}
struct FeesDistribution {
uint128 total;
uint128 protocol;
}
struct Bin {
uint112 reserveX;
uint112 reserveY;
uint256 accTokenXPerShare;
uint256 accTokenYPerShare;
}
struct PairInformation {
uint24 activeId;
uint136 reserveX;
uint136 reserveY;
uint16 oracleSampleLifetime;
uint16 oracleSize;
uint16 oracleActiveSize;
uint40 oracleLastTimestamp;
uint16 oracleId;
FeesDistribution feesX;
FeesDistribution feesY;
}
struct Debts {
uint256 debtX;
uint256 debtY;
}
struct Fees {
uint128 tokenX;
uint128 tokenY;
}
struct MintInfo {
uint256 amountXIn;
uint256 amountYIn;
uint256 amountXAddedToPair;
uint256 amountYAddedToPair;
uint256 activeFeeX;
uint256 activeFeeY;
uint256 totalDistributionX;
uint256 totalDistributionY;
uint256 id;
uint256 amountX;
uint256 amountY;
uint256 distributionX;
uint256 distributionY;
}
event Swap(
address indexed sender,
address indexed recipient,
uint256 indexed id,
bool swapForY,
uint256 amountIn,
uint256 amountOut,
uint256 volatilityAccumulated,
uint256 fees
);
event FlashLoan(
address indexed sender,
address indexed receiver,
IERC20 token,
uint256 amount,
uint256 fee
);
event CompositionFee(
address indexed sender,
address indexed recipient,
uint256 indexed id,
uint256 feesX,
uint256 feesY
);
event DepositedToBin(
address indexed sender,
address indexed recipient,
uint256 indexed id,
uint256 amountX,
uint256 amountY
);
event WithdrawnFromBin(
address indexed sender,
address indexed recipient,
uint256 indexed id,
uint256 amountX,
uint256 amountY
);
event FeesCollected(
address indexed sender,
address indexed recipient,
uint256 amountX,
uint256 amountY
);
event ProtocolFeesCollected(
address indexed sender,
address indexed recipient,
uint256 amountX,
uint256 amountY
);
event OracleSizeIncreased(uint256 previousSize, uint256 newSize);
function tokenX() external view returns (IERC20);
function tokenY() external view returns (IERC20);
function factory() external view returns (address);
function getReservesAndId()
external
view
returns (uint256 reserveX, uint256 reserveY, uint256 activeId);
function getGlobalFees()
external
view
returns (
uint128 feesXTotal,
uint128 feesYTotal,
uint128 feesXProtocol,
uint128 feesYProtocol
);
function getOracleParameters()
external
view
returns (
uint256 oracleSampleLifetime,
uint256 oracleSize,
uint256 oracleActiveSize,
uint256 oracleLastTimestamp,
uint256 oracleId,
uint256 min,
uint256 max
);
function getOracleSampleFrom(
uint256 timeDelta
)
external
view
returns (
uint256 cumulativeId,
uint256 cumulativeAccumulator,
uint256 cumulativeBinCrossed
);
function feeParameters() external view returns (FeeParameters memory);
function findFirstNonEmptyBinId(
uint24 id_,
bool sentTokenY
) external view returns (uint24 id);
function getBin(
uint24 id
) external view returns (uint256 reserveX, uint256 reserveY);
function pendingFees(
address account,
uint256[] memory ids
) external view returns (uint256 amountX, uint256 amountY);
function swap(
bool sentTokenY,
address to
) external returns (uint256 amountXOut, uint256 amountYOut);
function flashLoan(
address receiver,
IERC20 token,
uint256 amount,
bytes calldata data
) external;
function mint(
uint256[] calldata ids,
uint256[] calldata distributionX,
uint256[] calldata distributionY,
address to
)
external
returns (
uint256 amountXAddedToPair,
uint256 amountYAddedToPair,
uint256[] memory liquidityMinted
);
function burn(
uint256[] calldata ids,
uint256[] calldata amounts,
address to
) external returns (uint256 amountX, uint256 amountY);
function increaseOracleLength(uint16 newSize) external;
function collectFees(
address account,
uint256[] calldata ids
) external returns (uint256 amountX, uint256 amountY);
function collectProtocolFees()
external
returns (uint128 amountX, uint128 amountY);
function setFeesParameters(bytes32 packedFeeParameters) external;
function forceDecay() external;
function initialize(
IERC20 tokenX,
IERC20 tokenY,
uint24 activeId,
uint16 sampleLifetime,
bytes32 packedFeeParameters
) external;
}
文件 12 的 26:ILBLegacyRouter.sol
pragma solidity 0.8.10;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ILBFactory} from "./ILBFactory.sol";
import {IJoeFactory} from "./IJoeFactory.sol";
import {ILBLegacyPair} from "./ILBLegacyPair.sol";
import {ILBToken} from "./ILBToken.sol";
import {IWNATIVE} from "./IWNATIVE.sol";
interface ILBLegacyRouter {
struct LiquidityParameters {
IERC20 tokenX;
IERC20 tokenY;
uint256 binStep;
uint256 amountX;
uint256 amountY;
uint256 amountXMin;
uint256 amountYMin;
uint256 activeIdDesired;
uint256 idSlippage;
int256[] deltaIds;
uint256[] distributionX;
uint256[] distributionY;
address to;
uint256 deadline;
}
function factory() external view returns (address);
function wavax() external view returns (address);
function oldFactory() external view returns (address);
function getIdFromPrice(
ILBLegacyPair LBPair,
uint256 price
) external view returns (uint24);
function getPriceFromId(
ILBLegacyPair LBPair,
uint24 id
) external view returns (uint256);
function getSwapIn(
ILBLegacyPair lbPair,
uint256 amountOut,
bool swapForY
) external view returns (uint256 amountIn, uint256 feesIn);
function getSwapOut(
ILBLegacyPair lbPair,
uint256 amountIn,
bool swapForY
) external view returns (uint256 amountOut, uint256 feesIn);
function createLBPair(
IERC20 tokenX,
IERC20 tokenY,
uint24 activeId,
uint16 binStep
) external returns (ILBLegacyPair pair);
function addLiquidity(
LiquidityParameters calldata liquidityParameters
)
external
returns (uint256[] memory depositIds, uint256[] memory liquidityMinted);
function addLiquidityAVAX(
LiquidityParameters calldata liquidityParameters
)
external
payable
returns (uint256[] memory depositIds, uint256[] memory liquidityMinted);
function removeLiquidity(
IERC20 tokenX,
IERC20 tokenY,
uint16 binStep,
uint256 amountXMin,
uint256 amountYMin,
uint256[] memory ids,
uint256[] memory amounts,
address to,
uint256 deadline
) external returns (uint256 amountX, uint256 amountY);
function removeLiquidityAVAX(
IERC20 token,
uint16 binStep,
uint256 amountTokenMin,
uint256 amountAVAXMin,
uint256[] memory ids,
uint256[] memory amounts,
address payable to,
uint256 deadline
) external returns (uint256 amountToken, uint256 amountAVAX);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
uint256[] memory pairBinSteps,
IERC20[] memory tokenPath,
address to,
uint256 deadline
) external returns (uint256 amountOut);
function swapExactTokensForAVAX(
uint256 amountIn,
uint256 amountOutMinAVAX,
uint256[] memory pairBinSteps,
IERC20[] memory tokenPath,
address payable to,
uint256 deadline
) external returns (uint256 amountOut);
function swapExactAVAXForTokens(
uint256 amountOutMin,
uint256[] memory pairBinSteps,
IERC20[] memory tokenPath,
address to,
uint256 deadline
) external payable returns (uint256 amountOut);
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
uint256[] memory pairBinSteps,
IERC20[] memory tokenPath,
address to,
uint256 deadline
) external returns (uint256[] memory amountsIn);
function swapTokensForExactAVAX(
uint256 amountOut,
uint256 amountInMax,
uint256[] memory pairBinSteps,
IERC20[] memory tokenPath,
address payable to,
uint256 deadline
) external returns (uint256[] memory amountsIn);
function swapAVAXForExactTokens(
uint256 amountOut,
uint256[] memory pairBinSteps,
IERC20[] memory tokenPath,
address to,
uint256 deadline
) external payable returns (uint256[] memory amountsIn);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
uint256[] memory pairBinSteps,
IERC20[] memory tokenPath,
address to,
uint256 deadline
) external returns (uint256 amountOut);
function swapExactTokensForAVAXSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMinAVAX,
uint256[] memory pairBinSteps,
IERC20[] memory tokenPath,
address payable to,
uint256 deadline
) external returns (uint256 amountOut);
function swapExactAVAXForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
uint256[] memory pairBinSteps,
IERC20[] memory tokenPath,
address to,
uint256 deadline
) external payable returns (uint256 amountOut);
function sweep(IERC20 token, address to, uint256 amount) external;
function sweepLBToken(
ILBToken _lbToken,
address _to,
uint256[] calldata _ids,
uint256[] calldata _amounts
) external;
}
文件 13 的 26:ILBLegacyToken.sol
pragma solidity 0.8.10;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface ILBLegacyToken is IERC165 {
event TransferSingle(
address indexed sender,
address indexed from,
address indexed to,
uint256 id,
uint256 amount
);
event TransferBatch(
address indexed sender,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] amounts
);
event ApprovalForAll(
address indexed account,
address indexed sender,
bool approved
);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function balanceOf(
address account,
uint256 id
) external view returns (uint256);
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory batchBalances);
function totalSupply(uint256 id) external view returns (uint256);
function isApprovedForAll(
address owner,
address spender
) external view returns (bool);
function setApprovalForAll(address sender, bool approved) external;
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata id,
uint256[] calldata amount
) external;
}
文件 14 的 26:ILBPair.sol
pragma solidity 0.8.10;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ILBFactory} from "./ILBFactory.sol";
import {ILBFlashLoanCallback} from "./ILBFlashLoanCallback.sol";
import {ILBToken} from "./ILBToken.sol";
interface ILBPair is ILBToken {
error LBPair__ZeroBorrowAmount();
error LBPair__AddressZero();
error LBPair__AlreadyInitialized();
error LBPair__EmptyMarketConfigs();
error LBPair__FlashLoanCallbackFailed();
error LBPair__FlashLoanInsufficientAmount();
error LBPair__InsufficientAmountIn();
error LBPair__InsufficientAmountOut();
error LBPair__InvalidInput();
error LBPair__InvalidStaticFeeParameters();
error LBPair__OnlyFactory();
error LBPair__OnlyProtocolFeeRecipient();
error LBPair__OutOfLiquidity();
error LBPair__TokenNotSupported();
error LBPair__ZeroAmount(uint24 id);
error LBPair__ZeroAmountsOut(uint24 id);
error LBPair__ZeroShares(uint24 id);
error LBPair__MaxTotalFeeExceeded();
struct MintArrays {
uint256[] ids;
bytes32[] amounts;
uint256[] liquidityMinted;
}
event DepositedToBins(
address indexed sender,
address indexed to,
uint256[] ids,
bytes32[] amounts
);
event WithdrawnFromBins(
address indexed sender,
address indexed to,
uint256[] ids,
bytes32[] amounts
);
event CompositionFees(
address indexed sender,
uint24 id,
bytes32 totalFees,
bytes32 protocolFees
);
event CollectedProtocolFees(
address indexed feeRecipient,
bytes32 protocolFees
);
event Swap(
address indexed sender,
address indexed to,
uint24 id,
bytes32 amountsIn,
bytes32 amountsOut,
uint24 volatilityAccumulator,
bytes32 totalFees,
bytes32 protocolFees
);
event StaticFeeParametersSet(
address indexed sender,
uint16 baseFactor,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint24 variableFeeControl,
uint16 protocolShare,
uint24 maxVolatilityAccumulator
);
event FlashLoan(
address indexed sender,
ILBFlashLoanCallback indexed receiver,
uint24 activeId,
bytes32 amounts,
bytes32 totalFees,
bytes32 protocolFees
);
event OracleLengthIncreased(address indexed sender, uint16 oracleLength);
event ForcedDecay(
address indexed sender,
uint24 idReference,
uint24 volatilityReference
);
function initialize(
uint16 baseFactor,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint24 variableFeeControl,
uint16 protocolShare,
uint24 maxVolatilityAccumulator,
uint24 activeId
) external;
function getFactory() external view returns (ILBFactory factory);
function getTokenX() external view returns (IERC20 tokenX);
function getTokenY() external view returns (IERC20 tokenY);
function getBinStep() external view returns (uint16 binStep);
function getReserves()
external
view
returns (uint128 reserveX, uint128 reserveY);
function getActiveId() external view returns (uint24 activeId);
function getBin(
uint24 id
) external view returns (uint128 binReserveX, uint128 binReserveY);
function getNextNonEmptyBin(
bool swapForY,
uint24 id
) external view returns (uint24 nextId);
function getProtocolFees()
external
view
returns (uint128 protocolFeeX, uint128 protocolFeeY);
function getStaticFeeParameters()
external
view
returns (
uint16 baseFactor,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint24 variableFeeControl,
uint16 protocolShare,
uint24 maxVolatilityAccumulator
);
function getVariableFeeParameters()
external
view
returns (
uint24 volatilityAccumulator,
uint24 volatilityReference,
uint24 idReference,
uint40 timeOfLastUpdate
);
function getOracleParameters()
external
view
returns (
uint8 sampleLifetime,
uint16 size,
uint16 activeSize,
uint40 lastUpdated,
uint40 firstTimestamp
);
function getOracleSampleAt(
uint40 lookupTimestamp
)
external
view
returns (
uint64 cumulativeId,
uint64 cumulativeVolatility,
uint64 cumulativeBinCrossed
);
function getPriceFromId(uint24 id) external view returns (uint256 price);
function getIdFromPrice(uint256 price) external view returns (uint24 id);
function getSwapIn(
uint128 amountOut,
bool swapForY
)
external
view
returns (uint128 amountIn, uint128 amountOutLeft, uint128 fee);
function getSwapOut(
uint128 amountIn,
bool swapForY
)
external
view
returns (uint128 amountInLeft, uint128 amountOut, uint128 fee);
function swap(
bool swapForY,
address to
) external returns (bytes32 amountsOut);
function flashLoan(
ILBFlashLoanCallback receiver,
bytes32 amounts,
bytes calldata data
) external;
function mint(
address to,
bytes32[] calldata liquidityConfigs,
address refundTo
)
external
returns (
bytes32 amountsReceived,
bytes32 amountsLeft,
uint256[] memory liquidityMinted
);
function burn(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amountsToBurn
) external returns (bytes32[] memory amounts);
function collectProtocolFees()
external
returns (bytes32 collectedProtocolFees);
function increaseOracleLength(uint16 newLength) external;
function setStaticFeeParameters(
uint16 baseFactor,
uint16 filterPeriod,
uint16 decayPeriod,
uint16 reductionFactor,
uint24 variableFeeControl,
uint16 protocolShare,
uint24 maxVolatilityAccumulator
) external;
function forceDecay() external;
}
文件 15 的 26:ILBRouter.sol
pragma solidity 0.8.10;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IJoeFactory} from "./IJoeFactory.sol";
import {ILBFactory} from "./ILBFactory.sol";
import {ILBLegacyFactory} from "./ILBLegacyFactory.sol";
import {ILBLegacyRouter} from "./ILBLegacyRouter.sol";
import {ILBPair} from "./ILBPair.sol";
import {ILBToken} from "./ILBToken.sol";
import {IWNATIVE} from "./IWNATIVE.sol";
interface ILBRouter {
error LBRouter__SenderIsNotWNATIVE();
error LBRouter__PairNotCreated(
address tokenX,
address tokenY,
uint256 binStep
);
error LBRouter__WrongAmounts(uint256 amount, uint256 reserve);
error LBRouter__SwapOverflows(uint256 id);
error LBRouter__BrokenSwapSafetyCheck();
error LBRouter__NotFactoryOwner();
error LBRouter__TooMuchTokensIn(uint256 excess);
error LBRouter__BinReserveOverflows(uint256 id);
error LBRouter__IdOverflows(int256 id);
error LBRouter__LengthsMismatch();
error LBRouter__WrongTokenOrder();
error LBRouter__IdSlippageCaught(
uint256 activeIdDesired,
uint256 idSlippage,
uint256 activeId
);
error LBRouter__AmountSlippageCaught(
uint256 amountXMin,
uint256 amountX,
uint256 amountYMin,
uint256 amountY
);
error LBRouter__IdDesiredOverflows(uint256 idDesired, uint256 idSlippage);
error LBRouter__FailedToSendNATIVE(address recipient, uint256 amount);
error LBRouter__DeadlineExceeded(
uint256 deadline,
uint256 currentTimestamp
);
error LBRouter__AmountSlippageBPTooBig(uint256 amountSlippage);
error LBRouter__InsufficientAmountOut(
uint256 amountOutMin,
uint256 amountOut
);
error LBRouter__MaxAmountInExceeded(uint256 amountInMax, uint256 amountIn);
error LBRouter__InvalidTokenPath(address wrongToken);
error LBRouter__InvalidVersion(uint256 version);
error LBRouter__WrongNativeLiquidityParameters(
address tokenX,
address tokenY,
uint256 amountX,
uint256 amountY,
uint256 msgValue
);
enum Version {
V1,
V2,
V2_1
}
struct LiquidityParameters {
IERC20 tokenX;
IERC20 tokenY;
uint256 binStep;
uint256 amountX;
uint256 amountY;
uint256 amountXMin;
uint256 amountYMin;
uint256 activeIdDesired;
uint256 idSlippage;
int256[] deltaIds;
uint256[] distributionX;
uint256[] distributionY;
address to;
address refundTo;
uint256 deadline;
}
struct Path {
uint256[] pairBinSteps;
Version[] versions;
IERC20[] tokenPath;
}
function getFactory() external view returns (ILBFactory);
function getLegacyFactory() external view returns (ILBLegacyFactory);
function getV1Factory() external view returns (IJoeFactory);
function getLegacyRouter() external view returns (ILBLegacyRouter);
function getWNATIVE() external view returns (IWNATIVE);
function getIdFromPrice(
ILBPair LBPair,
uint256 price
) external view returns (uint24);
function getPriceFromId(
ILBPair LBPair,
uint24 id
) external view returns (uint256);
function getSwapIn(
ILBPair LBPair,
uint128 amountOut,
bool swapForY
)
external
view
returns (uint128 amountIn, uint128 amountOutLeft, uint128 fee);
function getSwapOut(
ILBPair LBPair,
uint128 amountIn,
bool swapForY
)
external
view
returns (uint128 amountInLeft, uint128 amountOut, uint128 fee);
function createLBPair(
IERC20 tokenX,
IERC20 tokenY,
uint24 activeId,
uint16 binStep
) external returns (ILBPair pair);
function addLiquidity(
LiquidityParameters calldata liquidityParameters
)
external
returns (
uint256 amountXAdded,
uint256 amountYAdded,
uint256 amountXLeft,
uint256 amountYLeft,
uint256[] memory depositIds,
uint256[] memory liquidityMinted
);
function addLiquidityNATIVE(
LiquidityParameters calldata liquidityParameters
)
external
payable
returns (
uint256 amountXAdded,
uint256 amountYAdded,
uint256 amountXLeft,
uint256 amountYLeft,
uint256[] memory depositIds,
uint256[] memory liquidityMinted
);
function removeLiquidity(
IERC20 tokenX,
IERC20 tokenY,
uint16 binStep,
uint256 amountXMin,
uint256 amountYMin,
uint256[] memory ids,
uint256[] memory amounts,
address to,
uint256 deadline
) external returns (uint256 amountX, uint256 amountY);
function removeLiquidityNATIVE(
IERC20 token,
uint16 binStep,
uint256 amountTokenMin,
uint256 amountNATIVEMin,
uint256[] memory ids,
uint256[] memory amounts,
address payable to,
uint256 deadline
) external returns (uint256 amountToken, uint256 amountNATIVE);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
Path memory path,
address to,
uint256 deadline
) external returns (uint256 amountOut);
function swapExactTokensForNATIVE(
uint256 amountIn,
uint256 amountOutMinNATIVE,
Path memory path,
address payable to,
uint256 deadline
) external returns (uint256 amountOut);
function swapExactNATIVEForTokens(
uint256 amountOutMin,
Path memory path,
address to,
uint256 deadline
) external payable returns (uint256 amountOut);
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
Path memory path,
address to,
uint256 deadline
) external returns (uint256[] memory amountsIn);
function swapTokensForExactNATIVE(
uint256 amountOut,
uint256 amountInMax,
Path memory path,
address payable to,
uint256 deadline
) external returns (uint256[] memory amountsIn);
function swapNATIVEForExactTokens(
uint256 amountOut,
Path memory path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amountsIn);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
Path memory path,
address to,
uint256 deadline
) external returns (uint256 amountOut);
function swapExactTokensForNATIVESupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMinNATIVE,
Path memory path,
address payable to,
uint256 deadline
) external returns (uint256 amountOut);
function swapExactNATIVEForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
Path memory path,
address to,
uint256 deadline
) external payable returns (uint256 amountOut);
function sweep(IERC20 token, address to, uint256 amount) external;
function sweepLBToken(
ILBToken _lbToken,
address _to,
uint256[] calldata _ids,
uint256[] calldata _amounts
) external;
}
文件 16 的 26:ILBToken.sol
pragma solidity 0.8.10;
interface ILBToken {
error LBToken__AddressThisOrZero();
error LBToken__InvalidLength();
error LBToken__SelfApproval(address owner);
error LBToken__SpenderNotApproved(address from, address spender);
error LBToken__TransferExceedsBalance(address from, uint256 id, uint256 amount);
error LBToken__BurnExceedsBalance(address from, uint256 id, uint256 amount);
event TransferBatch(
address indexed sender, address indexed from, address indexed to, uint256[] ids, uint256[] amounts
);
event ApprovalForAll(address indexed account, address indexed sender, bool approved);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function totalSupply(uint256 id) external view returns (uint256);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
function isApprovedForAll(address owner, address spender) external view returns (bool);
function approveForAll(address spender, bool approved) external;
function batchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts) external;
}
文件 17 的 26:IPendingOwnable.sol
pragma solidity 0.8.10;
interface IPendingOwnable {
error PendingOwnable__AddressZero();
error PendingOwnable__NoPendingOwner();
error PendingOwnable__NotOwner();
error PendingOwnable__NotPendingOwner();
error PendingOwnable__PendingOwnerAlreadySet();
event PendingOwnerSet(address indexed pendingOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function owner() external view returns (address);
function pendingOwner() external view returns (address);
function setPendingOwner(address pendingOwner) external;
function revokePendingOwner() external;
function becomeOwner() external;
function renounceOwnership() external;
}
文件 18 的 26:IWNATIVE.sol
pragma solidity 0.8.10;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IWNATIVE is IERC20 {
function deposit() external payable;
function withdraw(uint256) external;
}
文件 19 的 26:Lotus.sol
pragma solidity ^0.8.10;
import {SafeTransferLib} from "solmate/src/utils/SafeTransferLib.sol";
import {ERC20} from "solmate/src/tokens/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/ILBPair.sol";
import "./interfaces/ILBRouter.sol";
import "./interfaces/ILBToken.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./libraries/Constants.sol";
import {PriceHelper} from "./libraries/PriceHelper.sol";
contract Lotus is ERC20, Ownable {
using SafeTransferLib for address payable;
using SafeMath for uint256;
using PriceHelper for uint256;
address MUSE_DAO = 0xd7f52f7ff142b94B8deFc7Da8d34a7C65407533a;
ILBRouter public joeRouter;
ILBPair public pair;
address public vault;
address public immutable NATIVE;
bool public rebalancesEnabled;
bool public feesEnabled;
bool isRebalancing;
uint16 public binStep;
uint24 public startBin;
uint256 public lastRecordedActiveBin;
uint24 public maxBin;
uint256 public xPerBin;
uint24 public floorLiquidityBin;
uint24 public tightLiqBin;
uint256 public burnFee = 80;
uint256 public stakeFee = 20;
uint24 public seedLiquidityTimes;
uint256 public maxSupply;
constructor(
ILBRouter joeRouter_,
address native_,
uint256 maxSupply_,
uint256 _xPerBin
) ERC20("White Lotus", "LOTUS", 18) {
joeRouter = joeRouter_;
NATIVE = native_;
maxSupply = maxSupply_ * 1 ether;
rebalancesEnabled = true;
feesEnabled = true;
xPerBin = _xPerBin * 1 ether;
}
modifier rebalanceAllowed() {
if (binStep == 0 || floorLiquidityBin == getActiveBinId())
revert("At floor");
if (getActiveBinId() - lastRecordedActiveBin > 5 && rebalancesEnabled) {
_;
} else {
revert("Out of range");
}
}
function initialize(
address pair_,
int256[] memory deltaIds,
uint256[] memory distributionX,
uint256[] memory distributionY,
address _vault
) external payable onlyOwner {
require(seedLiquidityTimes < 4, "initialized");
if (seedLiquidityTimes == 0) {
vault = _vault;
pair = ILBPair(pair_);
binStep = pair.getBinStep();
startBin = getActiveBinId();
lastRecordedActiveBin = getActiveBinId() + 1;
approvals();
maxBin = getActiveBinId() + 300;
}
_mint(address(this), maxSupply / 3);
isRebalancing = true;
addLiquidity(deltaIds, distributionX, distributionY, getActiveBinId());
isRebalancing = false;
seedLiquidityTimes = seedLiquidityTimes + 1;
}
function rebalanceLiquidity() external rebalanceAllowed {
isRebalancing = true;
removeLiquidity();
uint256 totalEthInContract = IERC20(NATIVE).balanceOf(address(this));
uint256 totalLotusInPool = (maxBin - (getActiveBinId() + 1)) * xPerBin;
uint256 totalCirculatingSupply = totalSupply -
(totalLotusInPool +
balanceOf[0x000000000000000000000000000000000000dEaD]);
uint256 newFloorPrice = getAverageTokenPrice(
totalEthInContract,
totalCirculatingSupply
);
uint24 expectedFloorBin = joeRouter.getIdFromPrice(
pair,
newFloorPrice.convertDecimalPriceTo128x128()
);
floorLiquidityBin = expectedFloorBin > getActiveBinId()
? getActiveBinId() - 1
: expectedFloorBin;
int256 deltaForMainLiq = -(int24(getActiveBinId()) -
int(int24(floorLiquidityBin)));
tightLiqBin = getActiveBinId() - 1;
int256[] memory deltaIds = new int256[](2);
deltaIds[0] = deltaForMainLiq;
deltaIds[1] = -1;
uint256[] memory distributionX = new uint256[](2);
distributionX[0] = 0;
distributionX[1] = 0;
uint256[] memory distributionY = new uint256[](2);
distributionY[0] = (Constants.PRECISION * 90) / 100;
distributionY[1] = (Constants.PRECISION * 10) / 100;
addLiquidity(deltaIds, distributionX, distributionY, getActiveBinId());
isRebalancing = false;
}
function rebalanceMax() external {
require(
getActiveBinId() > maxBin && rebalancesEnabled,
"Not there yet"
);
isRebalancing = true;
uint256[] memory amounts = new uint256[](1);
uint256[] memory ids = new uint256[](1);
ids[0] = floorLiquidityBin;
amounts[0] = pair.balanceOf(address(this), ids[0]);
pair.burn(address(this), address(this), ids, amounts);
uint256 totalEthInContract = IERC20(NATIVE).balanceOf(address(this));
uint256 totalLotusInPool = 0;
uint256 totalCirculatingSupply = totalSupply -
(totalLotusInPool +
balanceOf[0x000000000000000000000000000000000000dEaD]);
uint256 newFloorPrice = getAverageTokenPrice(
totalEthInContract,
totalCirculatingSupply
);
uint24 expectedFloorBin = joeRouter.getIdFromPrice(
pair,
newFloorPrice.convertDecimalPriceTo128x128()
);
require(expectedFloorBin > floorLiquidityBin, "no");
floorLiquidityBin = expectedFloorBin > getActiveBinId()
? getActiveBinId() - 1
: expectedFloorBin;
int256 deltaForMainLiq = -(int24(getActiveBinId()) -
int(int24(floorLiquidityBin)));
int256[] memory deltaIds = new int256[](1);
deltaIds[0] = deltaForMainLiq;
uint256[] memory distributionX = new uint256[](1);
distributionX[0] = 0;
uint256[] memory distributionY = new uint256[](1);
distributionY[0] = Constants.PRECISION;
addLiquidity(deltaIds, distributionX, distributionY, getActiveBinId());
isRebalancing = false;
require(IERC20(NATIVE).balanceOf(address(this)) < 1 ether, "failed");
}
function removeLiquidity() internal {
bool isInsideRange = false;
uint256 numberOfBinsToWithdraw = (getActiveBinId() -
lastRecordedActiveBin);
numberOfBinsToWithdraw = floorLiquidityBin == 0
? numberOfBinsToWithdraw
: numberOfBinsToWithdraw + 1;
if (
tightLiqBin >= lastRecordedActiveBin &&
tightLiqBin <= lastRecordedActiveBin + numberOfBinsToWithdraw
) {
isInsideRange = true;
} else {
if (floorLiquidityBin > 0) {
isInsideRange = false;
numberOfBinsToWithdraw++;
}
}
uint256[] memory amounts = new uint256[](numberOfBinsToWithdraw);
uint256[] memory ids = new uint256[](numberOfBinsToWithdraw);
for (uint256 i; i < numberOfBinsToWithdraw; i++) {
ids[i] = lastRecordedActiveBin + i;
}
if (floorLiquidityBin != 0) {
ids[ids.length - 1] = floorLiquidityBin;
if (!isInsideRange) ids[numberOfBinsToWithdraw - 2] = tightLiqBin;
}
lastRecordedActiveBin = getActiveBinId();
for (uint256 i; i < numberOfBinsToWithdraw; i++) {
uint256 LBTokenAmount = pair.balanceOf(address(this), ids[i]);
amounts[i] = LBTokenAmount;
}
pair.burn(address(this), address(this), ids, amounts);
}
function addLiquidity(
int256[] memory deltaIds,
uint256[] memory distributionX,
uint256[] memory distributionY,
uint24 activeIdDesired
) internal {
uint256 amountX = balanceOf[address(this)];
uint256 amountY = IERC20(NATIVE).balanceOf(address(this));
uint256 amountXmin = (amountX * 99) / 100;
uint256 amountYmin = (amountY * 99) / 100;
uint256 idSlippage = 0;
ILBRouter.LiquidityParameters memory liquidityParameters = ILBRouter
.LiquidityParameters(
IERC20(address(this)),
IERC20(NATIVE),
binStep,
amountX,
amountY,
amountXmin,
amountYmin,
activeIdDesired,
idSlippage,
deltaIds,
distributionX,
distributionY,
address(this),
address(this),
block.timestamp
);
joeRouter.addLiquidity(liquidityParameters);
}
function chargeTax(
address from,
address to,
uint256 amount
) internal returns (uint256 _amount) {
_amount = amount;
if (feesEnabled && !isRebalancing) {
if (from == address(pair) && to != (address(this))) {
uint256 devFee = calculateFee(_amount, 22);
uint256 daoFee = calculateFee(_amount, 3);
balanceOf[owner()] += devFee;
emit Transfer(from, owner(), devFee);
balanceOf[MUSE_DAO] += daoFee;
emit Transfer(from, MUSE_DAO, daoFee);
_amount -= devFee;
_amount -= daoFee;
}
if (from == address(joeRouter) && to == address(pair)) {
uint256 sendToVault;
if (getActiveBinId() == floorLiquidityBin) {
sendToVault = calculateFee(_amount, (stakeFee + burnFee));
balanceOf[vault] += sendToVault;
emit Transfer(from, vault, sendToVault);
_amount -= sendToVault;
} else {
uint256 burn = calculateFee(_amount, burnFee);
sendToVault = calculateFee(_amount, stakeFee);
balanceOf[vault] += sendToVault;
emit Transfer(from, vault, sendToVault);
unchecked {
totalSupply -= burn;
}
emit Transfer(from, address(0), burn);
_amount -= (sendToVault + burn);
}
}
}
}
function transfer(
address to,
uint256 amount
) public virtual override returns (bool) {
balanceOf[msg.sender] -= amount;
uint256 _amount = chargeTax(msg.sender, to, amount);
unchecked {
balanceOf[to] += _amount;
}
emit Transfer(msg.sender, to, _amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max)
allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
uint256 _amount = chargeTax(msg.sender, to, amount);
unchecked {
balanceOf[to] += _amount;
}
emit Transfer(from, to, _amount);
return true;
}
function calculateFee(
uint256 amount,
uint256 pct
) public pure returns (uint256) {
uint256 feePercentage = Constants.PRECISION.mul(pct).div(1000);
return amount.mul(feePercentage).div(Constants.PRECISION);
}
function getAverageTokenPrice(
uint256 totalETH,
uint256 totalTokens
) public pure returns (uint256) {
require(totalETH < totalTokens, "ETH must be less than total tokens");
return (totalETH * Constants.PRECISION) / (totalTokens);
}
function getFloorPrice() public view returns (uint256) {
return joeRouter.getPriceFromId(pair, floorLiquidityBin);
}
function getActiveBinId() public view returns (uint24) {
return pair.getActiveId();
}
function feeReceiver() public view returns (address) {
return owner();
}
function approvals() public onlyOwner {
allowance[address(this)][address(joeRouter)] = 2 ** 256 - 1;
IERC20(NATIVE).approve(address(joeRouter), 2 ** 256 - 1);
ILBToken(address(pair)).approveForAll(address(joeRouter), true);
ILBToken(address(pair)).approveForAll(address(pair), true);
}
function disableRebalances(bool rebalances, bool fees) external onlyOwner {
rebalancesEnabled = rebalances;
feesEnabled = fees;
}
function setNewVault(address newVault) external onlyOwner {
vault = newVault;
}
receive() external payable {}
}
文件 20 的 26:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 21 的 26:PriceHelper.sol
pragma solidity 0.8.10;
import {Uint128x128Math} from "./math/Uint128x128Math.sol";
import {Uint256x256Math} from "./math/Uint256x256Math.sol";
import {SafeCast} from "./math/SafeCast.sol";
import {Constants} from "./Constants.sol";
library PriceHelper {
using Uint128x128Math for uint256;
using Uint256x256Math for uint256;
using SafeCast for uint256;
int256 private constant REAL_ID_SHIFT = 1 << 23;
function getPriceFromId(uint24 id, uint16 binStep) internal pure returns (uint256 price) {
uint256 base = getBase(binStep);
int256 exponent = getExponent(id);
price = base.pow(exponent);
}
function getIdFromPrice(uint256 price, uint16 binStep) internal pure returns (uint24 id) {
uint256 base = getBase(binStep);
int256 realId = price.log2() / base.log2();
unchecked {
id = uint256(REAL_ID_SHIFT + realId).safe24();
}
}
function getBase(uint16 binStep) internal pure returns (uint256) {
unchecked {
return Constants.SCALE + (uint256(binStep) << Constants.SCALE_OFFSET) / Constants.BASIS_POINT_MAX;
}
}
function getExponent(uint24 id) internal pure returns (int256) {
unchecked {
return int256(uint256(id)) - REAL_ID_SHIFT;
}
}
function convertDecimalPriceTo128x128(uint256 price) internal pure returns (uint256) {
return price.shiftDivRoundDown(Constants.SCALE_OFFSET, Constants.PRECISION);
}
function convert128x128PriceToDecimal(uint256 price128x128) internal pure returns (uint256) {
return price128x128.mulShiftRoundDown(Constants.PRECISION, Constants.SCALE_OFFSET);
}
}
文件 22 的 26:SafeCast.sol
pragma solidity 0.8.10;
library SafeCast {
error SafeCast__Exceeds248Bits();
error SafeCast__Exceeds240Bits();
error SafeCast__Exceeds232Bits();
error SafeCast__Exceeds224Bits();
error SafeCast__Exceeds216Bits();
error SafeCast__Exceeds208Bits();
error SafeCast__Exceeds200Bits();
error SafeCast__Exceeds192Bits();
error SafeCast__Exceeds184Bits();
error SafeCast__Exceeds176Bits();
error SafeCast__Exceeds168Bits();
error SafeCast__Exceeds160Bits();
error SafeCast__Exceeds152Bits();
error SafeCast__Exceeds144Bits();
error SafeCast__Exceeds136Bits();
error SafeCast__Exceeds128Bits();
error SafeCast__Exceeds120Bits();
error SafeCast__Exceeds112Bits();
error SafeCast__Exceeds104Bits();
error SafeCast__Exceeds96Bits();
error SafeCast__Exceeds88Bits();
error SafeCast__Exceeds80Bits();
error SafeCast__Exceeds72Bits();
error SafeCast__Exceeds64Bits();
error SafeCast__Exceeds56Bits();
error SafeCast__Exceeds48Bits();
error SafeCast__Exceeds40Bits();
error SafeCast__Exceeds32Bits();
error SafeCast__Exceeds24Bits();
error SafeCast__Exceeds16Bits();
error SafeCast__Exceeds8Bits();
function safe248(uint256 x) internal pure returns (uint248 y) {
if ((y = uint248(x)) != x) revert SafeCast__Exceeds248Bits();
}
function safe240(uint256 x) internal pure returns (uint240 y) {
if ((y = uint240(x)) != x) revert SafeCast__Exceeds240Bits();
}
function safe232(uint256 x) internal pure returns (uint232 y) {
if ((y = uint232(x)) != x) revert SafeCast__Exceeds232Bits();
}
function safe224(uint256 x) internal pure returns (uint224 y) {
if ((y = uint224(x)) != x) revert SafeCast__Exceeds224Bits();
}
function safe216(uint256 x) internal pure returns (uint216 y) {
if ((y = uint216(x)) != x) revert SafeCast__Exceeds216Bits();
}
function safe208(uint256 x) internal pure returns (uint208 y) {
if ((y = uint208(x)) != x) revert SafeCast__Exceeds208Bits();
}
function safe200(uint256 x) internal pure returns (uint200 y) {
if ((y = uint200(x)) != x) revert SafeCast__Exceeds200Bits();
}
function safe192(uint256 x) internal pure returns (uint192 y) {
if ((y = uint192(x)) != x) revert SafeCast__Exceeds192Bits();
}
function safe184(uint256 x) internal pure returns (uint184 y) {
if ((y = uint184(x)) != x) revert SafeCast__Exceeds184Bits();
}
function safe176(uint256 x) internal pure returns (uint176 y) {
if ((y = uint176(x)) != x) revert SafeCast__Exceeds176Bits();
}
function safe168(uint256 x) internal pure returns (uint168 y) {
if ((y = uint168(x)) != x) revert SafeCast__Exceeds168Bits();
}
function safe160(uint256 x) internal pure returns (uint160 y) {
if ((y = uint160(x)) != x) revert SafeCast__Exceeds160Bits();
}
function safe152(uint256 x) internal pure returns (uint152 y) {
if ((y = uint152(x)) != x) revert SafeCast__Exceeds152Bits();
}
function safe144(uint256 x) internal pure returns (uint144 y) {
if ((y = uint144(x)) != x) revert SafeCast__Exceeds144Bits();
}
function safe136(uint256 x) internal pure returns (uint136 y) {
if ((y = uint136(x)) != x) revert SafeCast__Exceeds136Bits();
}
function safe128(uint256 x) internal pure returns (uint128 y) {
if ((y = uint128(x)) != x) revert SafeCast__Exceeds128Bits();
}
function safe120(uint256 x) internal pure returns (uint120 y) {
if ((y = uint120(x)) != x) revert SafeCast__Exceeds120Bits();
}
function safe112(uint256 x) internal pure returns (uint112 y) {
if ((y = uint112(x)) != x) revert SafeCast__Exceeds112Bits();
}
function safe104(uint256 x) internal pure returns (uint104 y) {
if ((y = uint104(x)) != x) revert SafeCast__Exceeds104Bits();
}
function safe96(uint256 x) internal pure returns (uint96 y) {
if ((y = uint96(x)) != x) revert SafeCast__Exceeds96Bits();
}
function safe88(uint256 x) internal pure returns (uint88 y) {
if ((y = uint88(x)) != x) revert SafeCast__Exceeds88Bits();
}
function safe80(uint256 x) internal pure returns (uint80 y) {
if ((y = uint80(x)) != x) revert SafeCast__Exceeds80Bits();
}
function safe72(uint256 x) internal pure returns (uint72 y) {
if ((y = uint72(x)) != x) revert SafeCast__Exceeds72Bits();
}
function safe64(uint256 x) internal pure returns (uint64 y) {
if ((y = uint64(x)) != x) revert SafeCast__Exceeds64Bits();
}
function safe56(uint256 x) internal pure returns (uint56 y) {
if ((y = uint56(x)) != x) revert SafeCast__Exceeds56Bits();
}
function safe48(uint256 x) internal pure returns (uint48 y) {
if ((y = uint48(x)) != x) revert SafeCast__Exceeds48Bits();
}
function safe40(uint256 x) internal pure returns (uint40 y) {
if ((y = uint40(x)) != x) revert SafeCast__Exceeds40Bits();
}
function safe32(uint256 x) internal pure returns (uint32 y) {
if ((y = uint32(x)) != x) revert SafeCast__Exceeds32Bits();
}
function safe24(uint256 x) internal pure returns (uint24 y) {
if ((y = uint24(x)) != x) revert SafeCast__Exceeds24Bits();
}
function safe16(uint256 x) internal pure returns (uint16 y) {
if ((y = uint16(x)) != x) revert SafeCast__Exceeds16Bits();
}
function safe8(uint256 x) internal pure returns (uint8 y) {
if ((y = uint8(x)) != x) revert SafeCast__Exceeds8Bits();
}
}
文件 23 的 26:SafeMath.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
文件 24 的 26:SafeTransferLib.sol
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
library SafeTransferLib {
function safeTransferETH(address to, uint256 amount) internal {
bool success;
assembly {
success := call(gas(), to, amount, 0, 0, 0, 0)
}
require(success, "ETH_TRANSFER_FAILED");
}
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool success;
assembly {
let freeMemoryPointer := mload(0x40)
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), from)
mstore(add(freeMemoryPointer, 36), to)
mstore(add(freeMemoryPointer, 68), amount)
success := and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
)
}
require(success, "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
assembly {
let freeMemoryPointer := mload(0x40)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), to)
mstore(add(freeMemoryPointer, 36), amount)
success := and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
assembly {
let freeMemoryPointer := mload(0x40)
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), to)
mstore(add(freeMemoryPointer, 36), amount)
success := and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "APPROVE_FAILED");
}
}
文件 25 的 26:Uint128x128Math.sol
pragma solidity 0.8.10;
import {Constants} from "../Constants.sol";
import {BitMath} from "./BitMath.sol";
library Uint128x128Math {
using BitMath for uint256;
error Uint128x128Math__LogUnderflow();
error Uint128x128Math__PowUnderflow(uint256 x, int256 y);
uint256 constant LOG_SCALE_OFFSET = 127;
uint256 constant LOG_SCALE = 1 << LOG_SCALE_OFFSET;
uint256 constant LOG_SCALE_SQUARED = LOG_SCALE * LOG_SCALE;
function log2(uint256 x) internal pure returns (int256 result) {
if (x == 1) return -128;
if (x == 0) revert Uint128x128Math__LogUnderflow();
x >>= 1;
unchecked {
int256 sign;
if (x >= LOG_SCALE) {
sign = 1;
} else {
sign = -1;
x = LOG_SCALE_SQUARED / x;
}
uint256 n = (x >> LOG_SCALE_OFFSET).mostSignificantBit();
result = int256(n) << LOG_SCALE_OFFSET;
uint256 y = x >> n;
if (y != LOG_SCALE) {
for (int256 delta = int256(1 << (LOG_SCALE_OFFSET - 1)); delta > 0; delta >>= 1) {
y = (y * y) >> LOG_SCALE_OFFSET;
if (y >= 1 << (LOG_SCALE_OFFSET + 1)) {
result += delta;
y >>= 1;
}
}
}
result = (result * sign) << 1;
}
}
function pow(uint256 x, int256 y) internal pure returns (uint256 result) {
bool invert;
uint256 absY;
if (y == 0) return Constants.SCALE;
assembly {
absY := y
if slt(absY, 0) {
absY := sub(0, absY)
invert := iszero(invert)
}
}
if (absY < 0x100000) {
result = Constants.SCALE;
assembly {
let squared := x
if gt(x, 0xffffffffffffffffffffffffffffffff) {
squared := div(not(0), squared)
invert := iszero(invert)
}
if and(absY, 0x1) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x2) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x4) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x8) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x10) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x20) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x40) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x80) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x100) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x200) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x400) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x800) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x1000) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x2000) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x4000) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x8000) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x10000) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x20000) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x40000) { result := shr(128, mul(result, squared)) }
squared := shr(128, mul(squared, squared))
if and(absY, 0x80000) { result := shr(128, mul(result, squared)) }
}
}
if (result == 0) revert Uint128x128Math__PowUnderflow(x, y);
return invert ? type(uint256).max / result : result;
}
}
文件 26 的 26:Uint256x256Math.sol
pragma solidity 0.8.10;
library Uint256x256Math {
error Uint256x256Math__MulShiftOverflow();
error Uint256x256Math__MulDivOverflow();
function mulDivRoundDown(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
(uint256 prod0, uint256 prod1) = _getMulProds(x, y);
return _getEndOfDivRoundDown(x, y, denominator, prod0, prod1);
}
function mulDivRoundUp(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
result = mulDivRoundDown(x, y, denominator);
if (mulmod(x, y, denominator) != 0) result += 1;
}
function mulShiftRoundDown(
uint256 x,
uint256 y,
uint8 offset
) internal pure returns (uint256 result) {
(uint256 prod0, uint256 prod1) = _getMulProds(x, y);
if (prod0 != 0) result = prod0 >> offset;
if (prod1 != 0) {
if (prod1 >= 1 << offset)
revert Uint256x256Math__MulShiftOverflow();
unchecked {
result += prod1 << (256 - offset);
}
}
}
function mulShiftRoundUp(
uint256 x,
uint256 y,
uint8 offset
) internal pure returns (uint256 result) {
result = mulShiftRoundDown(x, y, offset);
if (mulmod(x, y, 1 << offset) != 0) result += 1;
}
function shiftDivRoundDown(
uint256 x,
uint8 offset,
uint256 denominator
) internal pure returns (uint256 result) {
uint256 prod0;
uint256 prod1;
prod0 = x << offset;
unchecked {
prod1 = x >> (256 - offset);
}
return _getEndOfDivRoundDown(x, 1 << offset, denominator, prod0, prod1);
}
function shiftDivRoundUp(
uint256 x,
uint8 offset,
uint256 denominator
) internal pure returns (uint256 result) {
result = shiftDivRoundDown(x, offset, denominator);
if (mulmod(x, 1 << offset, denominator) != 0) result += 1;
}
function _getMulProds(
uint256 x,
uint256 y
) private pure returns (uint256 prod0, uint256 prod1) {
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
}
function _getEndOfDivRoundDown(
uint256 x,
uint256 y,
uint256 denominator,
uint256 prod0,
uint256 prod1
) private pure returns (uint256 result) {
if (prod1 == 0) {
unchecked {
result = prod0 / denominator;
}
} else {
if (prod1 >= denominator) revert Uint256x256Math__MulDivOverflow();
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
unchecked {
uint256 lpotdod = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, lpotdod)
prod0 := div(prod0, lpotdod)
lpotdod := add(div(sub(0, lpotdod), lpotdod), 1)
}
prod0 |= prod1 * lpotdod;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
}
}
}
}
{
"compilationTarget": {
"contracts/Lotus.sol": "Lotus"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract ILBRouter","name":"joeRouter_","type":"address"},{"internalType":"address","name":"native_","type":"address"},{"internalType":"uint256","name":"maxSupply_","type":"uint256"},{"internalType":"uint256","name":"_xPerBin","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Uint256x256Math__MulDivOverflow","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NATIVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"binStep","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"pct","type":"uint256"}],"name":"calculateFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"rebalances","type":"bool"},{"internalType":"bool","name":"fees","type":"bool"}],"name":"disableRebalances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feesEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"floorLiquidityBin","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getActiveBinId","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"totalETH","type":"uint256"},{"internalType":"uint256","name":"totalTokens","type":"uint256"}],"name":"getAverageTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getFloorPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair_","type":"address"},{"internalType":"int256[]","name":"deltaIds","type":"int256[]"},{"internalType":"uint256[]","name":"distributionX","type":"uint256[]"},{"internalType":"uint256[]","name":"distributionY","type":"uint256[]"},{"internalType":"address","name":"_vault","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"joeRouter","outputs":[{"internalType":"contract ILBRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRecordedActiveBin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBin","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"contract ILBPair","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebalanceLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebalanceMax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebalancesEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"seedLiquidityTimes","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newVault","type":"address"}],"name":"setNewVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startBin","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tightLiqBin","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"xPerBin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]