文件 1 的 96:Address.sol
pragma solidity ^0.7.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 96:BitMath.sol
pragma solidity >=0.5.0;
library BitMath {
function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
require(x > 0);
if (x >= 0x100000000000000000000000000000000) {
x >>= 128;
r += 128;
}
if (x >= 0x10000000000000000) {
x >>= 64;
r += 64;
}
if (x >= 0x100000000) {
x >>= 32;
r += 32;
}
if (x >= 0x10000) {
x >>= 16;
r += 16;
}
if (x >= 0x100) {
x >>= 8;
r += 8;
}
if (x >= 0x10) {
x >>= 4;
r += 4;
}
if (x >= 0x4) {
x >>= 2;
r += 2;
}
if (x >= 0x2) r += 1;
}
function leastSignificantBit(uint256 x) internal pure returns (uint8 r) {
require(x > 0);
r = 255;
if (x & type(uint128).max > 0) {
r -= 128;
} else {
x >>= 128;
}
if (x & type(uint64).max > 0) {
r -= 64;
} else {
x >>= 64;
}
if (x & type(uint32).max > 0) {
r -= 32;
} else {
x >>= 32;
}
if (x & type(uint16).max > 0) {
r -= 16;
} else {
x >>= 16;
}
if (x & type(uint8).max > 0) {
r -= 8;
} else {
x >>= 8;
}
if (x & 0xf > 0) {
r -= 4;
} else {
x >>= 4;
}
if (x & 0x3 > 0) {
r -= 2;
} else {
x >>= 2;
}
if (x & 0x1 > 0) r -= 1;
}
}
文件 3 的 96:BlockTimestamp.sol
pragma solidity =0.7.6;
abstract contract BlockTimestamp {
function _blockTimestamp() internal view virtual returns (uint256) {
return block.timestamp;
}
}
文件 4 的 96:BubblyFactory.sol
pragma solidity =0.7.6;
import './interfaces/IBubblyFactory.sol';
import './BubblyPoolDeployer.sol';
import './NoDelegateCall.sol';
import './BubblyPool.sol';
contract BubblyFactory is IBubblyFactory, BubblyPoolDeployer, NoDelegateCall {
address public override owner;
mapping(uint24 => int24) public override feeAmountTickSpacing;
mapping(address => mapping(address => mapping(uint24 => address))) public override getPool;
address public CPM;
address public NPM;
constructor() {
owner = msg.sender;
emit OwnerChanged(address(0), msg.sender);
feeAmountTickSpacing[500] = 10;
emit FeeAmountEnabled(500, 10);
feeAmountTickSpacing[3000*5] = 60;
emit FeeAmountEnabled(3000*5, 60);
feeAmountTickSpacing[10000] = 200;
emit FeeAmountEnabled(10000, 200);
}
function createPool(
address tokenA,
address tokenB,
uint24 fee
) external override noDelegateCall returns (address pool) {
require(msg.sender == owner);
require(NPM != address(0),'NPM0');
require(CPM != address(0),'CPM0');
require(tokenA != tokenB);
(address token0, address token1) = (tokenA, tokenB) ;
require(token0 != address(0));
int24 tickSpacing = feeAmountTickSpacing[fee];
require(tickSpacing != 0);
require(getPool[token0][token1][fee] == address(0));
pool = deploy(CPM, NPM, address(this), token0, token1, fee, tickSpacing);
getPool[token0][token1][fee] = pool;
getPool[token1][token0][fee] = pool;
emit PoolCreated(token0, token1, fee, tickSpacing, pool);
}
function setOwner(address _owner) external override {
require(msg.sender == owner);
emit OwnerChanged(owner, _owner);
owner = _owner;
}
function setCPM(address _CPM) external {
require(msg.sender == owner);
emit CPMSet(_CPM);
CPM = _CPM;
}
function setNPM(address _NPM) external {
require(msg.sender == owner);
emit NPMSet(_NPM);
NPM = _NPM;
}
function enableFeeAmount(uint24 fee, int24 tickSpacing) public override {
require(msg.sender == owner);
require(fee < 1000000);
require(tickSpacing > 0 && tickSpacing < 16384);
require(feeAmountTickSpacing[fee] == 0);
feeAmountTickSpacing[fee] = tickSpacing;
emit FeeAmountEnabled(fee, tickSpacing);
}
}
文件 5 的 96:BubblyPool.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import './interfaces/IBubblyPool.sol';
import './NoDelegateCall.sol';
import './libraries/LowGasSafeMath.sol';
import './libraries/SafeCast.sol';
import './libraries/Tick.sol';
import './libraries/TickBitmap.sol';
import './libraries/Position.sol';
import './libraries/Oracle.sol';
import './libraries/FullMath.sol';
import './libraries/FixedPoint128.sol';
import './libraries/FixedPoint96.sol';
import './libraries/TransferHelper.sol';
import './libraries/TickMath.sol';
import './libraries/LiquidityMath.sol';
import './libraries/SqrtPriceMath.sol';
import './libraries/SwapMath.sol';
import './libraries/LiquidityAmounts.sol';
import './interfaces/IBubblyPoolDeployer.sol';
import './interfaces/IBubblyFactory.sol';
import './interfaces/IERC20Minimal.sol';
import './interfaces/callback/IBubblyMintCallback.sol';
import './interfaces/callback/IBubblySwapCallback.sol';
import 'hardhat/console.sol';
contract BubblyPool is IBubblyPool, NoDelegateCall {
using LowGasSafeMath for uint256;
using LowGasSafeMath for int256;
using SafeCast for uint256;
using SafeCast for int256;
using Tick for mapping(int24 => Tick.Info);
using TickBitmap for mapping(int16 => uint256);
using Position for mapping(bytes32 => Position.Info);
using Position for Position.Info;
using Oracle for Oracle.Observation[65535];
address public immutable override factory;
address public immutable override token0;
address public immutable override token1;
uint24 public immutable override fee;
int24 public immutable override tickSpacing;
uint128 public immutable override maxLiquidityPerTick;
struct Slot0 {
uint160 sqrtPriceX96;
int24 tick;
uint16 observationIndex;
uint16 observationCardinality;
uint16 observationCardinalityNext;
uint8 feeProtocol;
bool unlocked;
}
Slot0 public override slot0;
uint256 public override feeGrowthGlobalX128;
struct ProtocolFees {
uint128 token0;
uint128 token1;
}
ProtocolFees public override protocolFees;
uint128 public override liquidity;
mapping(int24 => Tick.Info) public override ticks;
mapping(int16 => uint256) public override tickBitmap;
mapping(bytes32 => Position.Info) public override positions;
Oracle.Observation[65535] public override observations;
bool public override deliveryflag ;
address public CPM;
address public NPM;
address public Delivery;
modifier lock() {
require(slot0.unlocked, 'LOK');
slot0.unlocked = false;
_;
slot0.unlocked = true;
}
modifier onlyFactoryOwner() {
require(msg.sender == IBubblyFactory(factory).owner());
_;
}
modifier onlyNPM() {
require(msg.sender == NPM);
_;
}
constructor() {
int24 _tickSpacing;
(CPM ,NPM ,factory, token0, token1, fee, _tickSpacing) = IBubblyPoolDeployer(msg.sender).parameters();
tickSpacing = _tickSpacing;
maxLiquidityPerTick = Tick.tickSpacingToMaxLiquidityPerTick(_tickSpacing);
}
function setDeliveryFlag(bool flag) onlyFactoryOwner external {
require(Delivery != address(0));
deliveryflag = flag;
TransferHelper.safeApprove(token1, Delivery, balance1());
}
function setDelivery(address _Delivery) onlyFactoryOwner external {
emit DeliverySet(_Delivery);
Delivery = _Delivery;
}
function checkTicks(int24 tickLower, int24 tickUpper) private pure {
require(tickLower < tickUpper, 'TLU');
require(tickLower >= TickMath.MIN_TICK, 'TLM');
require(tickUpper <= TickMath.MAX_TICK, 'TUM');
}
function _blockTimestamp() internal view virtual returns (uint32) {
return uint32(block.timestamp);
}
function balance1() private view returns (uint256) {
(bool success, bytes memory data) =
token1.staticcall(abi.encodeWithSelector(IERC20Minimal.balanceOf.selector, address(this)));
require(success && data.length >= 32);
return abi.decode(data, (uint256));
}
function initialize(uint160 sqrtPriceX96) external override onlyFactoryOwner{
require(slot0.sqrtPriceX96 == 0, 'AI');
int24 tick = TickMath.getTickAtSqrtRatio(sqrtPriceX96);
(uint16 cardinality, uint16 cardinalityNext) = observations.initialize(_blockTimestamp());
slot0 = Slot0({
sqrtPriceX96: sqrtPriceX96,
tick: tick,
observationIndex: 0,
observationCardinality: cardinality,
observationCardinalityNext: cardinalityNext,
feeProtocol: 0,
unlocked: true
});
emit Initialize(sqrtPriceX96, tick);
}
struct ModifyPositionParams {
address owner;
int24 tickLower;
int24 tickUpper;
int128 liquidityDelta;
}
function _modifyPosition(ModifyPositionParams memory params)
private
noDelegateCall
returns (
Position.Info storage position,
int256 amount0,
int256 amount1
)
{
checkTicks(params.tickLower, params.tickUpper);
Slot0 memory _slot0 = slot0;
position = _updatePosition(
params.owner,
params.tickLower,
params.tickUpper,
params.liquidityDelta,
_slot0.tick
);
if (params.liquidityDelta != 0) {
if (_slot0.tick < params.tickLower) {
amount0 = SqrtPriceMath.getAmount0Delta(
TickMath.getSqrtRatioAtTick(params.tickLower),
TickMath.getSqrtRatioAtTick(params.tickUpper),
params.liquidityDelta
);
} else if (_slot0.tick < params.tickUpper) {
uint128 liquidityBefore = liquidity;
(slot0.observationIndex, slot0.observationCardinality) = observations.write(
_slot0.observationIndex,
_blockTimestamp(),
_slot0.tick,
liquidityBefore,
_slot0.observationCardinality,
_slot0.observationCardinalityNext
);
amount0 = SqrtPriceMath.getAmount0Delta(
_slot0.sqrtPriceX96,
TickMath.getSqrtRatioAtTick(params.tickUpper),
params.liquidityDelta
);
amount1 = SqrtPriceMath.getAmount1Delta(
TickMath.getSqrtRatioAtTick(params.tickLower),
_slot0.sqrtPriceX96,
params.liquidityDelta
);
liquidity = LiquidityMath.addDelta(liquidityBefore, params.liquidityDelta);
} else {
amount1 = SqrtPriceMath.getAmount1Delta(
TickMath.getSqrtRatioAtTick(params.tickLower),
TickMath.getSqrtRatioAtTick(params.tickUpper),
params.liquidityDelta
);
}
}
}
function _updatePosition(
address owner,
int24 tickLower,
int24 tickUpper,
int128 liquidityDelta,
int24 tick
) private returns (Position.Info storage position) {
position = positions.get(owner, tickLower, tickUpper);
uint256 _feeGrowthGlobalX128 = feeGrowthGlobalX128;
bool flippedLower;
bool flippedUpper;
if (liquidityDelta != 0) {
uint32 time = _blockTimestamp();
(int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) =
observations.observeSingle(
time,
0,
slot0.tick,
slot0.observationIndex,
liquidity,
slot0.observationCardinality
);
flippedLower = ticks.update(
tickLower,
tick,
liquidityDelta,
_feeGrowthGlobalX128,
secondsPerLiquidityCumulativeX128,
tickCumulative,
time,
false,
maxLiquidityPerTick
);
flippedUpper = ticks.update(
tickUpper,
tick,
liquidityDelta,
_feeGrowthGlobalX128,
secondsPerLiquidityCumulativeX128,
tickCumulative,
time,
true,
maxLiquidityPerTick
);
if (flippedLower) {
tickBitmap.flipTick(tickLower, tickSpacing);
}
if (flippedUpper) {
tickBitmap.flipTick(tickUpper, tickSpacing);
}
}
uint256 feeGrowthInsideX128 =
ticks.getFeeGrowthInside(tickLower, tickUpper, tick, _feeGrowthGlobalX128);
position.update(liquidityDelta, feeGrowthInsideX128);
if (liquidityDelta < 0) {
if (flippedLower) {
ticks.clear(tickLower);
}
if (flippedUpper) {
ticks.clear(tickUpper);
}
}
}
function mint(
address recipient,
int24 tickLower,
int24 tickUpper,
uint128 amount,
bytes calldata data
) external override lock onlyNPM returns (uint256 amount0, uint256 amount1,uint256 collateral) {
require(!deliveryflag);
require(amount > 0);
(, int256 amount0Int, int256 amount1Int) =
_modifyPosition(
ModifyPositionParams({
owner: recipient,
tickLower: tickLower,
tickUpper: tickUpper,
liquidityDelta: int256(amount).toInt128()
})
);
amount0 = uint256(amount0Int);
amount1 = uint256(amount1Int);
uint256 amount0inUSD;
{
uint160 tickUppersqrtPriceX96 = TickMath.getSqrtRatioAtTick(tickUpper);
uint160 tickLowersqrtPriceX96 = TickMath.getSqrtRatioAtTick(tickLower);
if ( slot0.sqrtPriceX96 < tickLowersqrtPriceX96 || slot0.sqrtPriceX96 >= tickUppersqrtPriceX96){
amount0inUSD = SqrtPriceMath.getAmount1Delta(
tickLowersqrtPriceX96,
tickUppersqrtPriceX96,
amount,
true
);
}else {
amount0inUSD = SqrtPriceMath.getAmount1Delta(
slot0.sqrtPriceX96,
tickUppersqrtPriceX96,
amount,
true
);
}
}
uint256 balance1Before;
collateral = amount0inUSD > amount1? amount0inUSD : amount1 ;
if (collateral > 0) balance1Before = balance1();
IBubblyMintCallback(msg.sender).BubblyMintCallback(amount0inUSD, amount1, data);
if (collateral > 0) require(balance1Before.add(collateral) <= balance1(), 'M1');
emit Mint(msg.sender, recipient, tickLower, tickUpper, amount, amount0, amount1,collateral);
}
function collect(
address recipient,
int24 tickLower,
int24 tickUpper,
uint128 amountRequested
) external override lock onlyNPM returns (uint128 amount) {
Position.Info storage position = positions.get(msg.sender, tickLower, tickUpper);
amount = amountRequested > position.tokensOwed ? position.tokensOwed : amountRequested;
if (amount > 0) {
position.tokensOwed -= amount;
TransferHelper.safeTransfer(token1, recipient, amount > balance1() ? balance1() : amount);
}
emit Collect(msg.sender, recipient, tickLower, tickUpper, amount);
}
function burn(
int24 tickLower,
int24 tickUpper,
uint128 amount,
burnParams calldata burnparams
) external override lock onlyNPM returns (uint256 amount0, uint256 amount1,uint256 amount0used, uint256 amount1used,uint256 amountowed) {
(Position.Info storage position, int256 amount0Int, int256 amount1Int) =
_modifyPosition(
ModifyPositionParams({
owner: msg.sender,
tickLower: tickLower,
tickUpper: tickUpper,
liquidityDelta: -int256(amount).toInt128()
})
);
amount0 = uint256(-amount0Int);
amount1 = uint256(-amount1Int);
uint256 amount0inUSD;
if(amount0 > 0){
uint160 tickUpperSqrtPriceX96 = TickMath.getSqrtRatioAtTick(tickUpper);
uint160 tickLowerSqrtPriceX96 = TickMath.getSqrtRatioAtTick(tickLower);
if ( slot0.sqrtPriceX96 < tickLowerSqrtPriceX96 || slot0.sqrtPriceX96 >= tickUpperSqrtPriceX96){
amount0inUSD = SqrtPriceMath.getAmount1Delta(tickLowerSqrtPriceX96, tickUpperSqrtPriceX96, amount, false);
}else{
amount0inUSD = SqrtPriceMath.getAmount1Delta(slot0.sqrtPriceX96, tickUpperSqrtPriceX96, amount, false);
}
}
if(burnparams.liquidity > 0){
amount0used = FullMath.mulDivRoundingUp(uint256(amount), burnparams.lpamount0, uint256(burnparams.liquidity));
amount1used = FullMath.mulDivRoundingUp(uint256(amount), burnparams.lpamount1, uint256(burnparams.liquidity));
uint256 amount1delta = amount1used > amount1 ? (amount1used - amount1) : (amount1 - amount1used);
amountowed = FullMath.mulDiv(burnparams.lpcollateral,uint256(amount), uint256(burnparams.liquidity)) - amount1delta;
if(amountowed > 0){
position.tokensOwed += uint128(amountowed);
}
}
emit Burn(msg.sender, tickLower, tickUpper, amount, amount0, amount1, amountowed);
}
struct SwapCache {
uint8 feeProtocol;
uint128 liquidityStart;
uint32 blockTimestamp;
int56 tickCumulative;
uint160 secondsPerLiquidityCumulativeX128;
bool computedLatestObservation;
}
struct SwapState {
int256 amountSpecifiedRemaining;
int256 amountCalculated;
uint160 sqrtPriceX96;
int24 tick;
uint256 feeGrowthGlobalX128;
uint128 protocolFee;
uint128 liquidity;
}
struct StepComputations {
uint160 sqrtPriceStartX96;
int24 tickNext;
bool initialized;
uint160 sqrtPriceNextX96;
uint256 amountIn;
uint256 amountOut;
uint256 feeAmount;
}
function swap(
SwapParams calldata swapParams,
bytes calldata data
) external override noDelegateCall returns (int256 amount0, int256 amount1, uint256 totalFeeInQuoteToken ) {
require(!deliveryflag);
require(swapParams.amountSpecified != 0, 'AS');
Slot0 memory slot0Start = slot0;
require(slot0Start.unlocked, 'LOK');
require(
swapParams.zeroForOne
? swapParams.sqrtPriceLimitX96 < slot0Start.sqrtPriceX96 && swapParams.sqrtPriceLimitX96 > TickMath.MIN_SQRT_RATIO
: swapParams.sqrtPriceLimitX96 > slot0Start.sqrtPriceX96 && swapParams.sqrtPriceLimitX96 < TickMath.MAX_SQRT_RATIO,
'SPL'
);
slot0.unlocked = false;
SwapCache memory cache =
SwapCache({
liquidityStart: liquidity,
blockTimestamp: _blockTimestamp(),
feeProtocol: swapParams.zeroForOne ? (slot0Start.feeProtocol % 16) : (slot0Start.feeProtocol >> 4),
secondsPerLiquidityCumulativeX128: 0,
tickCumulative: 0,
computedLatestObservation: false
});
bool exactInput = swapParams.amountSpecified > 0;
SwapState memory state =
SwapState({
amountSpecifiedRemaining: swapParams.amountSpecified,
amountCalculated: 0,
sqrtPriceX96: slot0Start.sqrtPriceX96,
tick: slot0Start.tick,
feeGrowthGlobalX128: feeGrowthGlobalX128,
protocolFee: 0,
liquidity: cache.liquidityStart
});
uint256 totalFeeInBaseToken;
while (state.amountSpecifiedRemaining != 0 && state.sqrtPriceX96 != swapParams.sqrtPriceLimitX96) {
StepComputations memory step;
step.sqrtPriceStartX96 = state.sqrtPriceX96;
(step.tickNext, step.initialized) = tickBitmap.nextInitializedTickWithinOneWord(
state.tick,
tickSpacing,
swapParams.zeroForOne
);
if (step.tickNext < TickMath.MIN_TICK) {
step.tickNext = TickMath.MIN_TICK;
} else if (step.tickNext > TickMath.MAX_TICK) {
step.tickNext = TickMath.MAX_TICK;
}
step.sqrtPriceNextX96 = TickMath.getSqrtRatioAtTick(step.tickNext);
(state.sqrtPriceX96, step.amountIn, step.amountOut, step.feeAmount) = SwapMath.computeSwapStep(
state.sqrtPriceX96,
(swapParams.zeroForOne ? step.sqrtPriceNextX96 < swapParams.sqrtPriceLimitX96 : step.sqrtPriceNextX96 > swapParams.sqrtPriceLimitX96)
? swapParams.sqrtPriceLimitX96
: step.sqrtPriceNextX96,
state.liquidity,
state.amountSpecifiedRemaining,
fee
);
if (exactInput) {
state.amountSpecifiedRemaining -= (step.amountIn + step.feeAmount).toInt256();
state.amountCalculated = state.amountCalculated.sub(step.amountOut.toInt256());
} else {
state.amountSpecifiedRemaining += step.amountOut.toInt256();
state.amountCalculated = state.amountCalculated.add((step.amountIn + step.feeAmount).toInt256());
}
if(swapParams.zeroForOne && step.feeAmount > 0){
uint160 sqrtRatioAX96 = step.sqrtPriceStartX96;
uint160 sqrtRatioBX96 = state.sqrtPriceX96;
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
uint128 feeliquidity = LiquidityAmounts.getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, step.feeAmount);
uint256 feeInQuoteToken = SqrtPriceMath.getAmount1Delta(
sqrtRatioAX96,
sqrtRatioBX96,
feeliquidity,
true
);
totalFeeInBaseToken += step.feeAmount;
step.feeAmount = feeInQuoteToken;
totalFeeInQuoteToken += feeInQuoteToken;
}
if(!swapParams.zeroForOne && step.feeAmount > 0) totalFeeInQuoteToken += step.feeAmount;
if (cache.feeProtocol > 0) {
uint256 delta = step.feeAmount / cache.feeProtocol;
step.feeAmount -= delta;
state.protocolFee += uint128(delta);
}
if (state.liquidity > 0)
state.feeGrowthGlobalX128 += FullMath.mulDiv(step.feeAmount, FixedPoint128.Q128, state.liquidity);
if (state.sqrtPriceX96 == step.sqrtPriceNextX96) {
if (step.initialized) {
if (!cache.computedLatestObservation) {
(cache.tickCumulative, cache.secondsPerLiquidityCumulativeX128) = observations.observeSingle(
cache.blockTimestamp,
0,
slot0Start.tick,
slot0Start.observationIndex,
cache.liquidityStart,
slot0Start.observationCardinality
);
cache.computedLatestObservation = true;
}
int128 liquidityNet =
ticks.cross(
step.tickNext,
state.feeGrowthGlobalX128,
cache.secondsPerLiquidityCumulativeX128,
cache.tickCumulative,
cache.blockTimestamp
);
if (swapParams.zeroForOne) liquidityNet = -liquidityNet;
state.liquidity = LiquidityMath.addDelta(state.liquidity, liquidityNet);
}
state.tick = swapParams.zeroForOne ? step.tickNext - 1 : step.tickNext;
} else if (state.sqrtPriceX96 != step.sqrtPriceStartX96) {
state.tick = TickMath.getTickAtSqrtRatio(state.sqrtPriceX96);
}
}
if (state.tick != slot0Start.tick) {
(uint16 observationIndex, uint16 observationCardinality) =
observations.write(
slot0Start.observationIndex,
cache.blockTimestamp,
slot0Start.tick,
cache.liquidityStart,
slot0Start.observationCardinality,
slot0Start.observationCardinalityNext
);
(slot0.sqrtPriceX96, slot0.tick, slot0.observationIndex, slot0.observationCardinality) = (
state.sqrtPriceX96,
state.tick,
observationIndex,
observationCardinality
);
} else {
slot0.sqrtPriceX96 = state.sqrtPriceX96;
}
if (cache.liquidityStart != state.liquidity) liquidity = state.liquidity;
feeGrowthGlobalX128 = state.feeGrowthGlobalX128;
if (state.protocolFee > 0) protocolFees.token1 += state.protocolFee;
(amount0, amount1) = swapParams.zeroForOne == exactInput
? (swapParams.amountSpecified - state.amountSpecifiedRemaining, state.amountCalculated)
: (state.amountCalculated, swapParams.amountSpecified - state.amountSpecifiedRemaining);
if (swapParams.zeroForOne) {
if(!swapParams.isOpen){
if (amount1 < 0) {
amount1 = amount1 + int256(totalFeeInQuoteToken);
require(amount1 < 0);
TransferHelper.safeTransfer(token1, swapParams.recipient, uint256(-amount1));
}
IBubblySwapCallback(msg.sender).BubblySwapCallback(swapParams.isOpen, amount0, amount1, data);
}
else{
uint256 balance1Before = balance1();
amount1 = amount1 - int256(totalFeeInQuoteToken);
amount0 = amount0 - int256(totalFeeInBaseToken);
IBubblySwapCallback(msg.sender).BubblySwapCallback(swapParams.isOpen, amount0, amount1, data);
require(balance1Before.add(uint256(-amount1)) <= balance1(), 'IIA');
}
}
else {
if(!swapParams.isOpen){
uint256 amountToPay = 2 * swapParams.collateralamount > uint256(amount1).sub(totalFeeInQuoteToken) ? (2 * swapParams.collateralamount).sub(uint256(amount1).sub(totalFeeInQuoteToken)):0;
if (amount1 > 0) TransferHelper.safeTransfer(token1, swapParams.recipient, amountToPay - totalFeeInQuoteToken);
IBubblySwapCallback(msg.sender).BubblySwapCallback(swapParams.isOpen, amount0, int256(amountToPay - totalFeeInQuoteToken), data);
}
else{
uint256 balance1Before = balance1();
IBubblySwapCallback(msg.sender).BubblySwapCallback(swapParams.isOpen, amount0, amount1, data);
require(balance1Before.add(uint256(amount1)) <= balance1(), 'IIA');
}
}
require(msg.sender == CPM ,'NCPM');
emit Swap(swapParams.recipient, amount0, amount1, state.sqrtPriceX96, state.liquidity, state.tick,totalFeeInQuoteToken);
slot0.unlocked = true;
}
function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external override lock onlyFactoryOwner {
require(
(feeProtocol0 == 0 || (feeProtocol0 >= 3 && feeProtocol0 <= 10)) &&
(feeProtocol1 == 0 || (feeProtocol1 >= 3 && feeProtocol1 <= 10))
);
uint8 feeProtocolOld = slot0.feeProtocol;
slot0.feeProtocol = feeProtocol0 + (feeProtocol1 << 4);
emit SetFeeProtocol(feeProtocolOld % 16, feeProtocolOld >> 4, feeProtocol0, feeProtocol1);
}
function collectProtocol(
address recipient,
uint128 amountRequested
) external override lock onlyFactoryOwner returns (uint128 amount) {
amount = amountRequested > protocolFees.token1 ? protocolFees.token1 : amountRequested;
if (amount > 0) {
if (amount == protocolFees.token1) amount--;
protocolFees.token1 -= amount;
TransferHelper.safeTransfer(token1, recipient, amount);
}
emit CollectProtocol(msg.sender, recipient, amount);
}
}
文件 6 的 96:BubblyPoolDeployer.sol
pragma solidity =0.7.6;
import './interfaces/IBubblyPoolDeployer.sol';
import './BubblyPool.sol';
contract BubblyPoolDeployer is IBubblyPoolDeployer {
struct Parameters {
address CPM;
address NPM;
address factory;
address token0;
address token1;
uint24 fee;
int24 tickSpacing;
}
Parameters public override parameters;
function deploy(
address CPM,
address NPM,
address factory,
address token0,
address token1,
uint24 fee,
int24 tickSpacing
) internal returns (address pool) {
parameters = Parameters({CPM: CPM, NPM: NPM, factory: factory, token0: token0, token1: token1, fee: fee, tickSpacing: tickSpacing});
pool = address(new BubblyPool{salt: keccak256(abi.encode(token0, token1, fee))}());
delete parameters;
}
}
文件 7 的 96:BytesLib.sol
pragma solidity >=0.5.0 <0.8.0;
library BytesLib {
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
) internal pure returns (bytes memory) {
require(_length + 31 >= _length, 'slice_overflow');
require(_start + _length >= _start, 'slice_overflow');
require(_bytes.length >= _start + _length, 'slice_outOfBounds');
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
tempBytes := mload(0x40)
let lengthmod := and(_length, 31)
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
mstore(0x40, and(add(mc, 31), not(31)))
}
default {
tempBytes := mload(0x40)
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
require(_start + 20 >= _start, 'toAddress_overflow');
require(_bytes.length >= _start + 20, 'toAddress_outOfBounds');
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) {
require(_start + 3 >= _start, 'toUint24_overflow');
require(_bytes.length >= _start + 3, 'toUint24_outOfBounds');
uint24 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x3), _start))
}
return tempUint;
}
}
文件 8 的 96:CallbackValidation.sol
pragma solidity =0.7.6;
import '../interfaces/IBubblyPool.sol';
import './PoolAddress.sol';
library CallbackValidation {
function verifyCallback(
address quoteToken,
address factory,
address tokenA,
address tokenB,
uint24 fee
) internal view returns (IBubblyPool pool) {
return verifyCallback(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee , quoteToken));
}
function verifyCallback(address factory, PoolAddress.PoolKey memory poolKey)
internal
view
returns (IBubblyPool pool)
{
pool = IBubblyPool(PoolAddress.computeAddress(factory, poolKey));
require(msg.sender == address(pool),'valierr');
}
}
文件 9 的 96:ChainId.sol
pragma solidity >=0.7.0;
library ChainId {
function get() internal view returns (uint256 chainId) {
assembly {
chainId := chainid()
}
}
}
文件 10 的 96:CollateralPositionManager.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import './libraries/SafeCast.sol';
import './libraries/TickMath.sol';
import './interfaces/IBubblyPool.sol';
import '@openzeppelin/contracts/math/SafeMath.sol';
import './interfaces/ICollateralPositionManager.sol';
import './interfaces/IBubblyFactory.sol';
import './base/PeripheryImmutableState.sol';
import './base/PeripheryValidation.sol';
import './base/PeripheryPaymentsWithFee.sol';
import './base/Multicall.sol';
import './base/SelfPermit.sol';
import './libraries/Path.sol';
import './libraries/PoolAddress.sol';
import './libraries/CallbackValidation.sol';
import './libraries/FullMath.sol';
import 'hardhat/console.sol';
contract CollateralPositionManager is
ICollateralPositionManager,
PeripheryImmutableState,
PeripheryValidation,
PeripheryPayments,
Multicall,
SelfPermit
{
event updatePosition(address indexed recipient, address indexed pool,uint256 amount0, uint256 amount1, bool long,bool isOpen);
struct CollateralPosition {
uint256 token0amount;
uint256 token1amount;
}
using Path for bytes;
using SafeCast for uint256;
using SafeMath for uint256;
mapping(address => uint80) private _poolIds;
mapping(uint80 => PoolAddress.PoolKey) private _poolIdToPoolKey;
mapping(address => mapping(address => CollateralPosition)) private _longpositions;
mapping(address => mapping(address => CollateralPosition)) private _shortpositions;
uint256 private constant DEFAULT_AMOUNT_IN_CACHED = type(uint256).max;
uint256 private amountInCached = DEFAULT_AMOUNT_IN_CACHED;
address public NPM;
mapping (address => address) public EmergencyAdmin;
mapping (address => bool) public EmergencyPause;
event SetEmergencyAdmin(address indexed pool, address admin);
event SetEmergencyPause(address indexed pool, bool flag);
struct UpdatePositionParams{
bool isOpen;
bool long;
address recipient;
address pool;
uint256 amount0;
uint256 amount1;
}
constructor(address _factory) PeripheryImmutableState(_factory) {
}
modifier onlyFactoryOwnerOrAdmin(address pool) {
require(msg.sender == IBubblyFactory(factory).owner() || msg.sender == EmergencyAdmin[pool] );
_;
}
modifier onlyNPM() {
require(msg.sender == NPM);
_;
}
modifier onlyFactoryOwner() {
require(msg.sender == IBubblyFactory(factory).owner());
_;
}
function setNPM(address npm) external onlyFactoryOwner {
NPM = npm;
}
function getPool(
address quoteToken,
address tokenA,
address tokenB,
uint24 fee
) private view returns (IBubblyPool) {
return IBubblyPool(PoolAddress.computeAddress(factory,PoolAddress.getPoolKey(tokenA, tokenB, fee, quoteToken)));
}
function getLongPosition(
address pool,
address user
) public view override returns (uint256 ,uint256) {
return (_longpositions[pool][user].token0amount, _longpositions[pool][user].token1amount);
}
function getShortPosition(
address pool,
address user
) public view override returns (uint256 ,uint256) {
return (_shortpositions[pool][user].token0amount, _shortpositions[pool][user].token1amount);
}
struct SwapCallbackData {
bytes path;
address payer;
}
function BubblySwapCallback(
bool isOpen,
int256 amount0Delta,
int256 amount1Delta,
bytes calldata _data
) external override {
require(amount1Delta != 0);
SwapCallbackData memory data = abi.decode(_data, (SwapCallbackData));
(address tokenIn, address tokenOut, uint24 fee) = data.path.decodeFirstPool();
address quoteToken = IBubblyPool(msg.sender).token1();
CallbackValidation.verifyCallback(quoteToken, factory, tokenIn, tokenOut, fee);
uint256 amountToPay =
amount1Delta > 0
? uint256(amount1Delta)
: uint256(-amount1Delta);
if (isOpen){
pay(quoteToken, data.payer, msg.sender, amountToPay);
}
}
function exactInputInternal(
internalExactInputSingleParams memory params,
SwapCallbackData memory data
) private returns (uint256 amountOut) {
if (params.recipient == address(0)) params.recipient = tx.origin;
(address tokenIn, address tokenOut, uint24 fee) = data.path.decodeFirstPool();
address pool = address(getPool(params.quoteToken, tokenIn, tokenOut, fee));
require(EmergencyPause[pool] == false);
bool zeroForOne = tokenIn != params.quoteToken;
require(params.isOpen == true,"cp");
require(params.quoteToken == IBubblyPool(pool).token1());
(int256 amount0, int256 amount1 ,uint256 totalFeeInQuoteToken) =
getPool(params.quoteToken, tokenIn, tokenOut, fee).swap(
IBubblyPoolActions.SwapParams({
recipient : params.recipient,
zeroForOne : zeroForOne,
amountSpecified : params.amountIn.toInt256(),
isOpen : params.isOpen,
collateralamount : params.collateralamount,
sqrtPriceLimitX96 : params.sqrtPriceLimitX96 == 0
? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1)
: params.sqrtPriceLimitX96
}),
abi.encode(data)
);
bool long = params.isOpen != zeroForOne;
int256 amount1OnPosition;
if(!params.isOpen && zeroForOne){
amount1OnPosition = amount1 - int256(totalFeeInQuoteToken);
}
else{
amount1OnPosition = amount1 > 0 ? amount1 - int256(totalFeeInQuoteToken) : amount1 + int256(totalFeeInQuoteToken) ;
}
_updateposition(
UpdatePositionParams({
isOpen : params.isOpen,
long : long,
recipient : params.recipient,
pool : pool,
amount0 : uint256((amount0 > 0) ? amount0 : (-amount0)) ,
amount1 : uint256((amount1OnPosition > 0)? amount1OnPosition:(-amount1OnPosition))
})
);
return uint256(-(zeroForOne ? amount1 : amount0));
}
function exactInputSingle(ExactInputSingleParams calldata params)
external
payable
override
checkDeadline(params.deadline)
returns (uint256 amountOut)
{
if(!params.isOpen){
require(params.recipient == msg.sender || params.recipient == tx.origin);
}
uint256 collateralamount = _getcollateral(params.isOpen, params.tokenIn != params.quoteToken, address(getPool(params.quoteToken, params.tokenIn, params.tokenOut, params.fee)), params.recipient, params.amountIn);
amountOut = exactInputInternal(internalExactInputSingleParams({
amountIn : params.amountIn,
recipient : params.recipient,
sqrtPriceLimitX96: params.sqrtPriceLimitX96,
isOpen: params.isOpen,
collateralamount : collateralamount,
quoteToken : params.quoteToken
}),
SwapCallbackData({path: abi.encodePacked(params.tokenIn, params.fee, params.tokenOut), payer: msg.sender})
);
require(amountOut >= params.amountOutMinimum, 'Too little received');
}
function _getcollateral(bool isOpen, bool zeroForOne, address pool, address recipient, uint256 amount) internal view returns (uint256 collateralamount){
if (!isOpen){
CollateralPosition memory position = _checkposition(isOpen != zeroForOne, recipient, pool);
collateralamount = FullMath.mulDiv(amount, position.token1amount, position.token0amount);
}
}
function exactOutputInternal(
internalExactOutputSingleParams memory params,
SwapCallbackData memory data
) private returns (uint256 amountIn) {
(address tokenOut, address tokenIn, uint24 fee) = data.path.decodeFirstPool();
address pool = address(getPool(params.quoteToken, tokenIn, tokenOut, fee));
require(EmergencyPause[pool] == false);
bool zeroForOne = tokenIn != params.quoteToken;
require(params.isOpen == true,"cp");
require(params.quoteToken == IBubblyPool(pool).token1());
(int256 amount0Delta, int256 amount1Delta, uint256 totalFeeInQuoteToken) =
getPool(params.quoteToken, tokenIn, tokenOut, fee).swap(
IBubblyPoolActions.SwapParams({
recipient : params.recipient,
zeroForOne : zeroForOne,
amountSpecified : -params.amountOut.toInt256(),
isOpen : params.isOpen,
collateralamount : params.collateralamount,
sqrtPriceLimitX96: params.sqrtPriceLimitX96 == 0
? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1)
: params.sqrtPriceLimitX96
}),
abi.encode(data)
);
{
uint256 amountOutReceived;
(amountIn, amountOutReceived) = zeroForOne
? (uint256(amount0Delta), uint256(-amount1Delta))
: (uint256(amount1Delta), uint256(-amount0Delta));
if (params.sqrtPriceLimitX96 == 0 && tokenOut == params.quoteToken){
require(amountOutReceived == params.amountOut + totalFeeInQuoteToken);
}
else if (params.sqrtPriceLimitX96 == 0 && tokenOut != params.quoteToken){
require(amountOutReceived == params.amountOut);
}
}
bool long = params.isOpen != zeroForOne;
int256 amount1OnPosition = amount1Delta > 0 ? amount1Delta - int256(totalFeeInQuoteToken) : amount1Delta + int256(totalFeeInQuoteToken) ;
_updateposition(
UpdatePositionParams({
isOpen : params.isOpen,
long : long,
recipient : params.recipient,
pool : pool,
amount0 : uint256((amount0Delta > 0) ? amount0Delta : (-amount0Delta)),
amount1 : uint256((amount1OnPosition > 0) ? amount1OnPosition : (-amount1OnPosition))
})
);
}
function exactOutputSingle(ExactOutputSingleParams calldata params)
external
payable
override
checkDeadline(params.deadline)
returns (uint256 amountIn)
{
uint256 collateralamount = _getcollateral(params.isOpen, params.tokenIn != params.quoteToken, address(getPool(params.quoteToken, params.tokenIn, params.tokenOut, params.fee)), params.recipient, params.amountOut);
amountIn = exactOutputInternal(internalExactOutputSingleParams({
amountOut : params.amountOut,
recipient : params.recipient,
sqrtPriceLimitX96 : params.sqrtPriceLimitX96,
isOpen : params.isOpen,
collateralamount : collateralamount,
quoteToken : params.quoteToken
}),
SwapCallbackData({path: abi.encodePacked(params.tokenOut, params.fee, params.tokenIn), payer: msg.sender})
);
require(amountIn <= params.amountInMaximum, 'Too much requested');
}
function _checkposition(bool long, address recipient ,address pool ) internal view returns (CollateralPosition memory oldposition){
if (long){
oldposition = _longpositions[pool][recipient];
}
else{
oldposition = _shortpositions[pool][recipient];
}
}
function _updateposition(UpdatePositionParams memory params) internal{
CollateralPosition memory oldposition = _checkposition(params.long, params.recipient, params.pool);
CollateralPosition memory newposition;
if(params.isOpen){
newposition = CollateralPosition({
token0amount:oldposition.token0amount.add(params.amount0) ,
token1amount:oldposition.token1amount.add(params.amount1)
});
}else{
require(oldposition.token0amount >= params.amount0,'pne');
uint256 token1left = FullMath.mulDiv(oldposition.token1amount, (oldposition.token0amount - params.amount0), oldposition.token0amount);
newposition = CollateralPosition({
token0amount:oldposition.token0amount.sub(params.amount0) ,
token1amount:(oldposition.token0amount == params.amount0) ? 0 : token1left
});
}
if (params.long) {
_longpositions[params.pool][params.recipient] = newposition;
}
else{
_shortpositions[params.pool][params.recipient] = newposition;
}
emit updatePosition(params.recipient, params.pool, newposition.token0amount, newposition.token1amount, params.long, params.isOpen);
}
function mintWithoutSwap(MintWithoutSwapParams calldata params) onlyNPM override external
{
require(EmergencyPause[params.pool] == false);
bool long = params.amount1 < params.amount1used;
uint256 amount1delta = params.amount1 > params.amount1used? (params.amount1-params.amount1used): (params.amount1used-params.amount1);
uint256 amount0delta = params.amount0 > params.amount0used? (params.amount0-params.amount0used): (params.amount0used-params.amount0);
_updateposition(
UpdatePositionParams({
isOpen : true,
long : long,
recipient : params.recipient,
pool : params.pool,
amount0 : amount0delta,
amount1 : amount1delta
})
);
}
function setEmergencyAdmin (address _pool ,address _admin) external onlyFactoryOwnerOrAdmin(_pool) {
EmergencyAdmin[_pool] = _admin;
emit SetEmergencyAdmin(_pool, _admin);
}
function setEmergencyPause (address _pool ,bool _flag ) external onlyFactoryOwnerOrAdmin(_pool) {
EmergencyPause[_pool] = _flag;
emit SetEmergencyPause(_pool, _flag);
}
}
文件 11 的 96:Context.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
}
文件 12 的 96:ERC165.sol
pragma solidity ^0.7.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
mapping(bytes4 => bool) private _supportedInterfaces;
constructor () {
_registerInterface(_INTERFACE_ID_ERC165);
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return _supportedInterfaces[interfaceId];
}
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
文件 13 的 96:ERC721.sol
pragma solidity ^0.7.0;
import "../../utils/Context.sol";
import "./IERC721.sol";
import "./IERC721Metadata.sol";
import "./IERC721Enumerable.sol";
import "./IERC721Receiver.sol";
import "../../introspection/ERC165.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
import "../../utils/EnumerableSet.sol";
import "../../utils/EnumerableMap.sol";
import "../../utils/Strings.sol";
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
using SafeMath for uint256;
using Address for address;
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableMap for EnumerableMap.UintToAddressMap;
using Strings for uint256;
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
mapping (address => EnumerableSet.UintSet) private _holderTokens;
EnumerableMap.UintToAddressMap private _tokenOwners;
mapping (uint256 => address) private _tokenApprovals;
mapping (address => mapping (address => bool)) private _operatorApprovals;
string private _name;
string private _symbol;
mapping (uint256 => string) private _tokenURIs;
string private _baseURI;
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
constructor (string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_registerInterface(_INTERFACE_ID_ERC721);
_registerInterface(_INTERFACE_ID_ERC721_METADATA);
_registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _holderTokens[owner].length();
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = baseURI();
if (bytes(base).length == 0) {
return _tokenURI;
}
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
return string(abi.encodePacked(base, tokenId.toString()));
}
function baseURI() public view virtual returns (string memory) {
return _baseURI;
}
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
return _holderTokens[owner].at(index);
}
function totalSupply() public view virtual override returns (uint256) {
return _tokenOwners.length();
}
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
(uint256 tokenId, ) = _tokenOwners.at(index);
return tokenId;
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(address from, address to, uint256 tokenId) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _tokenOwners.contains(tokenId);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));
}
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
_mint(to, tokenId);
require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
_approve(address(0), tokenId);
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
_holderTokens[owner].remove(tokenId);
_tokenOwners.remove(tokenId);
emit Transfer(owner, address(0), tokenId);
}
function _transfer(address from, address to, uint256 tokenId) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
_approve(address(0), tokenId);
_holderTokens[from].remove(tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(from, to, tokenId);
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
function _setBaseURI(string memory baseURI_) internal virtual {
_baseURI = baseURI_;
}
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
private returns (bool)
{
if (!to.isContract()) {
return true;
}
bytes memory returndata = to.functionCall(abi.encodeWithSelector(
IERC721Receiver(to).onERC721Received.selector,
_msgSender(),
from,
tokenId,
_data
), "ERC721: transfer to non ERC721Receiver implementer");
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _ERC721_RECEIVED);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
}
文件 14 的 96:ERC721Permit.sol
pragma solidity =0.7.6;
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/utils/Address.sol';
import '../libraries/ChainId.sol';
import '../interfaces/external/IERC1271.sol';
import '../interfaces/IERC721Permit.sol';
import './BlockTimestamp.sol';
abstract contract ERC721Permit is BlockTimestamp, ERC721, IERC721Permit {
function _getAndIncrementNonce(uint256 tokenId) internal virtual returns (uint256);
bytes32 private immutable nameHash;
bytes32 private immutable versionHash;
constructor(
string memory name_,
string memory symbol_,
string memory version_
) ERC721(name_, symbol_) {
nameHash = keccak256(bytes(name_));
versionHash = keccak256(bytes(version_));
}
function DOMAIN_SEPARATOR() public view override returns (bytes32) {
return
keccak256(
abi.encode(
0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,
nameHash,
versionHash,
ChainId.get(),
address(this)
)
);
}
bytes32 public constant override PERMIT_TYPEHASH =
0x49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad;
function permit(
address spender,
uint256 tokenId,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external payable override {
require(_blockTimestamp() <= deadline, 'Permit expired');
bytes32 digest =
keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, spender, tokenId, _getAndIncrementNonce(tokenId), deadline))
)
);
address owner = ownerOf(tokenId);
require(spender != owner, 'ERC721Permit: approval to current owner');
if (Address.isContract(owner)) {
require(IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) == 0x1626ba7e, 'Unauthorized');
} else {
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0), 'Invalid signature');
require(recoveredAddress == owner, 'Unauthorized');
}
_approve(spender, tokenId);
}
}
文件 15 的 96:EmergencySave.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import './interfaces/IDelivery.sol';
import './interfaces/ICollateralPositionManager.sol';
import './interfaces/IBubblyPool.sol';
import './interfaces/IBubblyFactory.sol';
import './libraries/LowGasSafeMath.sol';
import './libraries/TransferHelper.sol';
import './libraries/FullMath.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import './interfaces/IERC20Minimal.sol';
import './base/Multicall.sol';
import 'hardhat/console.sol';
contract EmergencySave is Multicall{
constructor(){
}
struct PreactionParams{
address token;
address from;
address to;
uint256 amount;
address cpm;
address npm;
uint256 amounttoadd;
}
modifier onlyFactoryOwner() {
require(msg.sender == 0x10A14AFBBEd292B3c2F0493dc984A85662e36a7e);
_;
}
function emergencyTokenTransfer(address token, address from ,address to, uint256 amount) external onlyFactoryOwner {
amount = IERC20(token).balanceOf(from);
TransferHelper.safeTransferFrom(token, from, to, amount);
}
function approveToContract(address token, address spender, uint256 amount) external onlyFactoryOwner {
IERC20(token).approve(spender, amount);
}
function emergencyTokenTransferAndreplay(PreactionParams calldata preactionparams,address[] calldata contractAddr, bytes[] calldata calldataArray) external onlyFactoryOwner {
uint256 amount = IERC20(preactionparams.token).balanceOf(preactionparams.from);
TransferHelper.safeTransferFrom(preactionparams.token, preactionparams.from, preactionparams.to, amount);
TransferHelper.safeTransferFrom(preactionparams.token, msg.sender, preactionparams.to, preactionparams.amounttoadd);
IERC20(preactionparams.token).approve(preactionparams.npm, type(uint256).max);
IERC20(preactionparams.token).approve(preactionparams.cpm, type(uint256).max);
console.log("begin to replay");
uint256 length = contractAddr.length;
for(uint256 i = 0; i < length; i++){
console.log("come into tx:" ,i);
(bool success, ) = address(contractAddr[i]).call(calldataArray[i]);
if (!success) {
assembly {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
TransferHelper.safeTransfer(preactionparams.token, msg.sender, IERC20(preactionparams.token).balanceOf(address(this)));
}
}
文件 16 的 96:EnumerableMap.sol
pragma solidity ^0.7.0;
library EnumerableMap {
struct MapEntry {
bytes32 _key;
bytes32 _value;
}
struct Map {
MapEntry[] _entries;
mapping (bytes32 => uint256) _indexes;
}
function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
uint256 keyIndex = map._indexes[key];
if (keyIndex == 0) {
map._entries.push(MapEntry({ _key: key, _value: value }));
map._indexes[key] = map._entries.length;
return true;
} else {
map._entries[keyIndex - 1]._value = value;
return false;
}
}
function _remove(Map storage map, bytes32 key) private returns (bool) {
uint256 keyIndex = map._indexes[key];
if (keyIndex != 0) {
uint256 toDeleteIndex = keyIndex - 1;
uint256 lastIndex = map._entries.length - 1;
MapEntry storage lastEntry = map._entries[lastIndex];
map._entries[toDeleteIndex] = lastEntry;
map._indexes[lastEntry._key] = toDeleteIndex + 1;
map._entries.pop();
delete map._indexes[key];
return true;
} else {
return false;
}
}
function _contains(Map storage map, bytes32 key) private view returns (bool) {
return map._indexes[key] != 0;
}
function _length(Map storage map) private view returns (uint256) {
return map._entries.length;
}
function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
require(map._entries.length > index, "EnumerableMap: index out of bounds");
MapEntry storage entry = map._entries[index];
return (entry._key, entry._value);
}
function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
uint256 keyIndex = map._indexes[key];
if (keyIndex == 0) return (false, 0);
return (true, map._entries[keyIndex - 1]._value);
}
function _get(Map storage map, bytes32 key) private view returns (bytes32) {
uint256 keyIndex = map._indexes[key];
require(keyIndex != 0, "EnumerableMap: nonexistent key");
return map._entries[keyIndex - 1]._value;
}
function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
uint256 keyIndex = map._indexes[key];
require(keyIndex != 0, errorMessage);
return map._entries[keyIndex - 1]._value;
}
struct UintToAddressMap {
Map _inner;
}
function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
}
function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
return _remove(map._inner, bytes32(key));
}
function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
return _contains(map._inner, bytes32(key));
}
function length(UintToAddressMap storage map) internal view returns (uint256) {
return _length(map._inner);
}
function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
(bytes32 key, bytes32 value) = _at(map._inner, index);
return (uint256(key), address(uint160(uint256(value))));
}
function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
(bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
return (success, address(uint160(uint256(value))));
}
function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key)))));
}
function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
}
}
文件 17 的 96:EnumerableSet.sol
pragma solidity ^0.7.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping (bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
bytes32 lastvalue = set._values[lastIndex];
set._values[toDeleteIndex] = lastvalue;
set._indexes[lastvalue] = toDeleteIndex + 1;
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}
文件 18 的 96:FixedPoint128.sol
pragma solidity >=0.4.0;
library FixedPoint128 {
uint256 internal constant Q128 = 0x100000000000000000000000000000000;
}
文件 19 的 96:FixedPoint96.sol
pragma solidity >=0.4.0;
library FixedPoint96 {
uint8 internal constant RESOLUTION = 96;
uint256 internal constant Q96 = 0x1000000000000000000000000;
}
文件 20 的 96:FullMath.sol
pragma solidity >=0.4.0 <0.8.0;
library FullMath {
function mulDiv(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(a, b, not(0))
prod0 := mul(a, b)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
require(denominator > 0);
assembly {
result := div(prod0, denominator)
}
return result;
}
require(denominator > prod1);
uint256 remainder;
assembly {
remainder := mulmod(a, b, denominator)
}
assembly {
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = -denominator & denominator;
assembly {
denominator := div(denominator, twos)
}
assembly {
prod0 := div(prod0, twos)
}
assembly {
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inv = (3 * denominator) ^ 2;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
inv *= 2 - denominator * inv;
result = prod0 * inv;
return result;
}
function mulDivRoundingUp(
uint256 a,
uint256 b,
uint256 denominator
) internal pure returns (uint256 result) {
result = mulDiv(a, b, denominator);
if (mulmod(a, b, denominator) > 0) {
require(result < type(uint256).max);
result++;
}
}
}
文件 21 的 96:HexStrings.sol
pragma solidity =0.7.6;
library HexStrings {
bytes16 internal constant ALPHABET = '0123456789abcdef';
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = '0';
buffer[1] = 'x';
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = ALPHABET[value & 0xf];
value >>= 4;
}
require(value == 0, 'Strings: hex length insufficient');
return string(buffer);
}
function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length);
for (uint256 i = buffer.length; i > 0; i--) {
buffer[i - 1] = ALPHABET[value & 0xf];
value >>= 4;
}
return string(buffer);
}
}
文件 22 的 96:IBubblyFactory.sol
pragma solidity >=0.5.0;
interface IBubblyFactory {
event OwnerChanged(address indexed oldOwner, address indexed newOwner);
event PoolCreated(
address indexed token0,
address indexed token1,
uint24 indexed fee,
int24 tickSpacing,
address pool
);
event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing);
event CPMSet(address indexed CPMaddress);
event NPMSet(address indexed NPMaddress);
function owner() external view returns (address);
function feeAmountTickSpacing(uint24 fee) external view returns (int24);
function getPool(
address tokenA,
address tokenB,
uint24 fee
) external view returns (address pool);
function createPool(
address tokenA,
address tokenB,
uint24 fee
) external returns (address pool);
function setOwner(address _owner) external;
function enableFeeAmount(uint24 fee, int24 tickSpacing) external;
}
文件 23 的 96:IBubblyMintCallback.sol
pragma solidity >=0.5.0;
interface IBubblyMintCallback {
function BubblyMintCallback(
uint256 amount0Owed,
uint256 amount1Owed,
bytes calldata data
) external;
}
文件 24 的 96:IBubblyPool.sol
pragma solidity >=0.5.0;
pragma abicoder v2;
import './pool/IBubblyPoolImmutables.sol';
import './pool/IBubblyPoolState.sol';
import './pool/IBubblyPoolDerivedState.sol';
import './pool/IBubblyPoolActions.sol';
import './pool/IBubblyPoolOwnerActions.sol';
import './pool/IBubblyPoolEvents.sol';
interface IBubblyPool is
IBubblyPoolImmutables,
IBubblyPoolState,
IBubblyPoolActions,
IBubblyPoolOwnerActions,
IBubblyPoolEvents
{
}
文件 25 的 96:IBubblyPoolActions.sol
pragma solidity >=0.5.0;
pragma abicoder v2;
interface IBubblyPoolActions {
function initialize(uint160 sqrtPriceX96) external;
struct SwapParams{
address recipient;
bool zeroForOne;
int256 amountSpecified;
bool isOpen;
uint256 collateralamount;
uint160 sqrtPriceLimitX96;
}
struct burnParams{
uint128 liquidity;
uint256 lpamount0;
uint256 lpamount1;
uint256 lpcollateral;
}
function mint(
address recipient,
int24 tickLower,
int24 tickUpper,
uint128 amount,
bytes calldata data
) external returns (uint256 amount0, uint256 amount1,uint256 collateral);
function collect(
address recipient,
int24 tickLower,
int24 tickUpper,
uint128 amountRequested
) external returns (uint128 amount);
function burn(
int24 tickLower,
int24 tickUpper,
uint128 amount,
burnParams calldata burnparams
) external returns (uint256 amount0, uint256 amount1,uint256 amount0used, uint256 amount1used, uint256 amountowed);
function swap(
SwapParams calldata swapParams,
bytes calldata data
) external returns (int256 amount0, int256 amount1, uint256 totalFeeInQuoteToken);
}
文件 26 的 96:IBubblyPoolDeployer.sol
pragma solidity >=0.5.0;
interface IBubblyPoolDeployer {
function parameters()
external
view
returns (
address CPM,
address NPM,
address factory,
address token0,
address token1,
uint24 fee,
int24 tickSpacing
);
}
文件 27 的 96:IBubblyPoolDerivedState.sol
pragma solidity >=0.5.0;
interface IBubblyPoolDerivedState {
}
文件 28 的 96:IBubblyPoolEvents.sol
pragma solidity >=0.5.0;
interface IBubblyPoolEvents {
event Initialize(uint160 sqrtPriceX96, int24 tick);
event Mint(
address sender,
address indexed owner,
int24 indexed tickLower,
int24 indexed tickUpper,
uint128 amount,
uint256 amount0,
uint256 amount1,
uint256 collateral
);
event Collect(
address indexed owner,
address recipient,
int24 indexed tickLower,
int24 indexed tickUpper,
uint128 amount
);
event Burn(
address indexed owner,
int24 indexed tickLower,
int24 indexed tickUpper,
uint128 amount,
uint256 amount0,
uint256 amount1,
uint256 collateral
);
event Swap(
address indexed recipient,
int256 amount0,
int256 amount1,
uint160 sqrtPriceX96,
uint128 liquidity,
int24 tick,
uint256 totalFeeInQuoteToken
);
event Flash(
address indexed sender,
address indexed recipient,
uint256 amount0,
uint256 amount1,
uint256 paid0,
uint256 paid1
);
event IncreaseObservationCardinalityNext(
uint16 observationCardinalityNextOld,
uint16 observationCardinalityNextNew
);
event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New);
event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount);
event DeliverySet (address indexed Delivery);
}
文件 29 的 96:IBubblyPoolImmutables.sol
pragma solidity >=0.5.0;
interface IBubblyPoolImmutables {
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function fee() external view returns (uint24);
function tickSpacing() external view returns (int24);
function maxLiquidityPerTick() external view returns (uint128);
function deliveryflag() external view returns (bool);
}
文件 30 的 96:IBubblyPoolOwnerActions.sol
pragma solidity >=0.5.0;
interface IBubblyPoolOwnerActions {
function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external;
function collectProtocol(
address recipient,
uint128 amountRequested
) external returns (uint128 amount);
}
文件 31 的 96:IBubblyPoolState.sol
pragma solidity >=0.5.0;
interface IBubblyPoolState {
function slot0()
external
view
returns (
uint160 sqrtPriceX96,
int24 tick,
uint16 observationIndex,
uint16 observationCardinality,
uint16 observationCardinalityNext,
uint8 feeProtocol,
bool unlocked
);
function feeGrowthGlobalX128() external view returns (uint256);
function protocolFees() external view returns (uint128 token0, uint128 token1);
function liquidity() external view returns (uint128);
function ticks(int24 tick)
external
view
returns (
uint128 liquidityGross,
int128 liquidityNet,
uint256 feeGrowthOutsideX128,
int56 tickCumulativeOutside,
uint160 secondsPerLiquidityOutsideX128,
uint32 secondsOutside,
bool initialized
);
function tickBitmap(int16 wordPosition) external view returns (uint256);
function positions(bytes32 key)
external
view
returns (
uint128 _liquidity,
uint256 feeGrowthInsideLastX128,
uint128 tokensOwed
);
function observations(uint256 index)
external
view
returns (
uint32 blockTimestamp,
int56 tickCumulative,
uint160 secondsPerLiquidityCumulativeX128,
bool initialized
);
}
文件 32 的 96:IBubblySwapCallback.sol
pragma solidity >=0.5.0;
interface IBubblySwapCallback {
function BubblySwapCallback(
bool isOpen,
int256 amount0Delta,
int256 amount1Delta,
bytes calldata data
) external;
}
文件 33 的 96:ICollateralPositionManager.sol
pragma solidity >=0.7.5;
pragma abicoder v2;
import '../interfaces/callback/IBubblySwapCallback.sol';
interface ICollateralPositionManager is IBubblySwapCallback {
struct ExactInputSingleParams {
address quoteToken;
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
bool isOpen;
}
struct internalExactInputSingleParams {
uint256 amountIn;
address recipient;
uint160 sqrtPriceLimitX96;
bool isOpen;
uint256 collateralamount;
address quoteToken;
}
struct internalExactOutputSingleParams {
uint256 amountOut;
address recipient;
uint160 sqrtPriceLimitX96;
bool isOpen;
uint256 collateralamount;
address quoteToken;
}
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
struct ExactInputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
}
struct ExactOutputSingleParams {
address quoteToken;
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
uint160 sqrtPriceLimitX96;
bool isOpen;
}
function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
struct ExactOutputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
}
function mintWithoutSwap(MintWithoutSwapParams calldata params) external ;
struct MintWithoutSwapParams {
address pool;
uint256 amount0;
uint256 amount1;
uint256 amount0used;
uint256 amount1used;
address recipient;
}
function getLongPosition(
address pool,
address user
) external view returns (uint256 ,uint256);
function getShortPosition(
address pool,
address user
) external view returns (uint256 ,uint256);
}
文件 34 的 96:IDelivery.sol
pragma solidity >=0.7.5;
pragma abicoder v2;
interface IDelivery {
function Deliver(address pool, uint256 amount, bool forY) external returns (uint256 amountIn);
function setToken(
address token,
address vtoken
) external ;
}
文件 35 的 96:IERC1271.sol
pragma solidity >=0.5.0;
interface IERC1271 {
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
文件 36 的 96:IERC165.sol
pragma solidity ^0.7.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 37 的 96:IERC20.sol
pragma solidity ^0.7.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, 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 sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 38 的 96:IERC20Metadata.sol
pragma solidity ^0.7.0;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 39 的 96:IERC20Minimal.sol
pragma solidity >=0.5.0;
interface IERC20Minimal {
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, 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 sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 40 的 96:IERC20Permit.sol
pragma solidity >=0.6.0 <0.8.0;
interface IERC20Permit {
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 41 的 96:IERC20PermitAllowed.sol
pragma solidity >=0.5.0;
interface IERC20PermitAllowed {
function permit(
address holder,
address spender,
uint256 nonce,
uint256 expiry,
bool allowed,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
文件 42 的 96:IERC721.sol
pragma solidity ^0.7.0;
import "../../introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}
文件 43 的 96:IERC721Enumerable.sol
pragma solidity ^0.7.0;
import "./IERC721.sol";
interface IERC721Enumerable is IERC721 {
function totalSupply() external view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
function tokenByIndex(uint256 index) external view returns (uint256);
}
文件 44 的 96:IERC721Metadata.sol
pragma solidity ^0.7.0;
import "./IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 45 的 96:IERC721Permit.sol
pragma solidity >=0.7.5;
import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
interface IERC721Permit is IERC721 {
function PERMIT_TYPEHASH() external pure returns (bytes32);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function permit(
address spender,
uint256 tokenId,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external payable;
}
文件 46 的 96:IERC721Receiver.sol
pragma solidity ^0.7.0;
interface IERC721Receiver {
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}
文件 47 的 96:IMulticall.sol
pragma solidity >=0.7.5;
pragma abicoder v2;
interface IMulticall {
function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);
}
文件 48 的 96:INonfungiblePositionManager.sol
pragma solidity >=0.7.5;
pragma abicoder v2;
import '@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol';
import '@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol';
import './IERC721Permit.sol';
import './IPeripheryPayments.sol';
import './IPeripheryImmutableState.sol';
import '../libraries/PoolAddress.sol';
interface INonfungiblePositionManager is
IPeripheryPayments,
IPeripheryImmutableState,
IERC721Metadata,
IERC721Enumerable,
IERC721Permit
{
event IncreaseLiquidity(uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);
event DecreaseLiquidity(uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1,uint256 collateral);
event Collect(uint256 indexed tokenId, address recipient, uint256 amount);
function positions(uint256 tokenId)
external
view
returns (
uint96 nonce,
address operator,
address pool,
int24 tickLower,
int24 tickUpper,
uint128 liquidity,
uint256 feeGrowthInsideLastX128,
uint128 tokensOwed,
uint256 lpamount0,
uint256 lpamount1,
uint256 lpcollateral
);
struct MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
function mint(MintParams calldata params)
external
returns (
uint256 tokenId,
uint128 liquidity,
uint256 amount0,
uint256 amount1,
uint256 collateral
);
struct IncreaseLiquidityParams {
uint256 tokenId;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
function increaseLiquidity(IncreaseLiquidityParams calldata params)
external
returns (
uint128 liquidity,
uint256 amount0,
uint256 amount1
);
struct DecreaseLiquidityParams {
uint256 tokenId;
uint128 liquidity;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
function decreaseLiquidity(DecreaseLiquidityParams calldata params)
external
returns (uint256 amount0, uint256 amount1);
struct CollectParams {
uint256 tokenId;
address recipient;
uint128 amountMax;
}
function collect(CollectParams calldata params) external returns (uint256 amount);
function burn(uint256 tokenId) external ;
}
文件 49 的 96:INonfungibleTokenPositionDescriptor.sol
pragma solidity >=0.5.0;
import './INonfungiblePositionManager.sol';
interface INonfungibleTokenPositionDescriptor {
function tokenURI(INonfungiblePositionManager positionManager, uint256 tokenId)
external
view
returns (string memory);
}
文件 50 的 96:IPeripheryImmutableState.sol
pragma solidity >=0.5.0;
interface IPeripheryImmutableState {
function factory() external view returns (address);
}
文件 51 的 96:IPeripheryPayments.sol
pragma solidity >=0.7.5;
interface IPeripheryPayments {
function refundETH() external payable;
function sweepToken(
address token,
uint256 amountMinimum,
address recipient
) external payable;
}
文件 52 的 96:IPeripheryPaymentsWithFee.sol
pragma solidity >=0.7.5;
import './IPeripheryPayments.sol';
interface IPeripheryPaymentsWithFee is IPeripheryPayments {
function sweepTokenWithFee(
address token,
uint256 amountMinimum,
address recipient,
uint256 feeBips,
address feeRecipient
) external payable;
}
文件 53 的 96:IPoolInitializer.sol
pragma solidity >=0.7.5;
pragma abicoder v2;
interface IPoolInitializer {
function createAndInitializePoolIfNecessary(
address token0,
address token1,
uint24 fee,
uint160 sqrtPriceX96
) external payable returns (address pool);
}
文件 54 的 96:IQuoterV2.sol
pragma solidity >=0.7.5;
pragma abicoder v2;
interface IQuoterV2 {
struct QuoteExactInputSingleParams {
address quoteToken;
address tokenIn;
address tokenOut;
uint256 amountIn;
uint24 fee;
uint160 sqrtPriceLimitX96;
bool isOpen;
}
function quoteExactInputSingle(QuoteExactInputSingleParams memory params)
external
returns (
uint256 amountOut,
uint160 sqrtPriceX96After,
uint256 gasEstimate
);
struct QuoteExactOutputSingleParams {
address quoteToken;
address tokenIn;
address tokenOut;
uint256 amount;
uint24 fee;
uint160 sqrtPriceLimitX96;
bool isOpen;
}
function quoteExactOutputSingle(QuoteExactOutputSingleParams memory params)
external
returns (
uint256 amountIn,
uint160 sqrtPriceX96After,
uint256 gasEstimate
);
}
文件 55 的 96:ISelfPermit.sol
pragma solidity >=0.7.5;
interface ISelfPermit {
function selfPermit(
address token,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external payable;
function selfPermitIfNecessary(
address token,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external payable;
function selfPermitAllowed(
address token,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) external payable;
function selfPermitAllowedIfNecessary(
address token,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) external payable;
}
文件 56 的 96:IWETH9.sol
pragma solidity =0.7.6;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
interface IWETH9 is IERC20 {
function deposit() external payable;
function withdraw(uint256) external;
}
文件 57 的 96:LiquidityAmounts.sol
pragma solidity >=0.5.0;
import './FullMath.sol';
import './FixedPoint96.sol';
library LiquidityAmounts {
function toUint128(uint256 x) private pure returns (uint128 y) {
require((y = uint128(x)) == x);
}
function getLiquidityForAmount0(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint256 amount0
) internal pure returns (uint128 liquidity) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);
return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));
}
function getLiquidityForAmount1(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint256 amount1
) internal pure returns (uint128 liquidity) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));
}
function getLiquidityForAmounts(
uint160 sqrtRatioX96,
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint256 amount0,
uint256 amount1
) internal pure returns (uint128 liquidity) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
if (sqrtRatioX96 <= sqrtRatioAX96) {
liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);
} else if (sqrtRatioX96 < sqrtRatioBX96) {
uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);
uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);
liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;
} else {
liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);
}
}
function getAmount0ForLiquidity(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint128 liquidity
) internal pure returns (uint256 amount0) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
return
FullMath.mulDiv(
uint256(liquidity) << FixedPoint96.RESOLUTION,
sqrtRatioBX96 - sqrtRatioAX96,
sqrtRatioBX96
) / sqrtRatioAX96;
}
function getAmount1ForLiquidity(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint128 liquidity
) internal pure returns (uint256 amount1) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);
}
function getAmountsForLiquidity(
uint160 sqrtRatioX96,
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint128 liquidity
) internal pure returns (uint256 amount0, uint256 amount1) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
if (sqrtRatioX96 <= sqrtRatioAX96) {
amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);
} else if (sqrtRatioX96 < sqrtRatioBX96) {
amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);
amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);
} else {
amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);
}
}
}
文件 58 的 96:LiquidityManagement.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import '../interfaces/IBubblyFactory.sol';
import '../interfaces/callback/IBubblyMintCallback.sol';
import '../libraries/TickMath.sol';
import '../libraries/PoolAddress.sol';
import '../libraries/CallbackValidation.sol';
import '../libraries/LiquidityAmounts.sol';
import './PeripheryPayments.sol';
import './PeripheryImmutableState.sol';
abstract contract LiquidityManagement is IBubblyMintCallback, PeripheryImmutableState, PeripheryPayments {
struct MintCallbackData {
PoolAddress.PoolKey poolKey;
address payer;
}
function BubblyMintCallback(
uint256 amount0Owed,
uint256 amount1Owed,
bytes calldata data
) external override {
MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));
CallbackValidation.verifyCallback(factory, decoded.poolKey);
uint256 collateral = amount0Owed > amount1Owed? amount0Owed : amount1Owed;
if (collateral > 0) pay(decoded.poolKey.token1, decoded.payer, msg.sender, collateral);
}
struct AddLiquidityParams {
address token0;
address token1;
uint24 fee;
address recipient;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
}
function addLiquidity(AddLiquidityParams memory params)
internal
returns (
uint128 liquidity,
uint256 amount0,
uint256 amount1,
uint256 collateral,
IBubblyPool pool
)
{
PoolAddress.PoolKey memory poolKey =
PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee});
pool = IBubblyPool(PoolAddress.computeAddress(factory,poolKey));
{
(uint160 sqrtPriceX96, , , , , , ) = pool.slot0();
uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(params.tickLower);
uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(params.tickUpper);
liquidity = LiquidityAmounts.getLiquidityForAmounts(
sqrtPriceX96,
sqrtRatioAX96,
sqrtRatioBX96,
params.amount0Desired,
params.amount1Desired
);
}
(amount0, amount1,collateral) = pool.mint(
params.recipient,
params.tickLower,
params.tickUpper,
liquidity,
abi.encode(MintCallbackData({poolKey: poolKey, payer: msg.sender}))
);
require(amount0 >= params.amount0Min && amount1 >= params.amount1Min, 'PSC');
}
}
文件 59 的 96:LiquidityMath.sol
pragma solidity >=0.5.0;
library LiquidityMath {
function addDelta(uint128 x, int128 y) internal pure returns (uint128 z) {
if (y < 0) {
require((z = x - uint128(-y)) < x, 'LS');
} else {
require((z = x + uint128(y)) >= x, 'LA');
}
}
}
文件 60 的 96:LowGasSafeMath.sol
pragma solidity >=0.7.0;
library LowGasSafeMath {
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(x == 0 || (z = x * y) / x == y);
}
function add(int256 x, int256 y) internal pure returns (int256 z) {
require((z = x + y) >= x == (y >= 0));
}
function sub(int256 x, int256 y) internal pure returns (int256 z) {
require((z = x - y) <= x == (y >= 0));
}
}
文件 61 的 96:LpCollateralCalculator.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import './interfaces/INonfungiblePositionManager.sol';
contract LpCollateralCalculator {
function getLPtotalcollateral(address lpAddress, address npmContract) external view returns (uint256 totalCollateral) {
INonfungiblePositionManager npm = INonfungiblePositionManager(npmContract);
uint256 balance = npm.balanceOf(lpAddress);
uint256 totalCollateral = 0;
for (uint256 i = 0; i < balance; i++) {
uint256 tokenId = npm.tokenOfOwnerByIndex(lpAddress, i);
(
,
,
,
,
,
,
,
,
,
,
uint256 lpcollateral
) = npm.positions(tokenId);
totalCollateral += lpcollateral;
}
return totalCollateral;
}
}
文件 62 的 96:Multicall.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import '../interfaces/IMulticall.sol';
abstract contract Multicall is IMulticall {
function multicall(bytes[] calldata data) public payable override returns (bytes[] memory results) {
results = new bytes[](data.length);
for (uint256 i = 0; i < data.length; i++) {
(bool success, bytes memory result) = address(this).delegatecall(data[i]);
if (!success) {
if (result.length < 68) revert();
assembly {
result := add(result, 0x04)
}
revert(abi.decode(result, (string)));
}
results[i] = result;
}
}
}
文件 63 的 96:NFTDescriptor.sol
pragma solidity >=0.7.0;
pragma abicoder v2;
import '../interfaces/IBubblyPool.sol';
import './TickMath.sol';
import './BitMath.sol';
import './FullMath.sol';
import '@openzeppelin/contracts/utils/Strings.sol';
import '@openzeppelin/contracts/math/SafeMath.sol';
import '@openzeppelin/contracts/math/SignedSafeMath.sol';
import 'base64-sol/base64.sol';
import './HexStrings.sol';
import './NFTSVG.sol';
library NFTDescriptor {
using TickMath for int24;
using Strings for uint256;
using SafeMath for uint256;
using SafeMath for uint160;
using SafeMath for uint8;
using SignedSafeMath for int256;
using HexStrings for uint256;
uint256 constant sqrt10X128 = 1076067327063303206878105757264492625226;
struct ConstructTokenURIParams {
uint256 tokenId;
address quoteTokenAddress;
address baseTokenAddress;
string quoteTokenSymbol;
string baseTokenSymbol;
uint8 quoteTokenDecimals;
uint8 baseTokenDecimals;
bool flipRatio;
int24 tickLower;
int24 tickUpper;
int24 tickCurrent;
int24 tickSpacing;
uint24 fee;
address poolAddress;
}
function constructTokenURI(ConstructTokenURIParams memory params) public pure returns (string memory) {
string memory name = generateName(params, feeToPercentString(params.fee));
string memory descriptionPartOne =
generateDescriptionPartOne(
escapeQuotes(params.quoteTokenSymbol),
escapeQuotes(params.baseTokenSymbol),
addressToString(params.poolAddress)
);
string memory descriptionPartTwo =
generateDescriptionPartTwo(
params.tokenId.toString(),
escapeQuotes(params.baseTokenSymbol),
addressToString(params.quoteTokenAddress),
addressToString(params.baseTokenAddress),
feeToPercentString(params.fee)
);
string memory image = Base64.encode(bytes(generateSVGImage(params)));
return
string(
abi.encodePacked(
'data:application/json;base64,',
Base64.encode(
bytes(
abi.encodePacked(
'{"name":"',
name,
'", "description":"',
descriptionPartOne,
descriptionPartTwo,
'", "image": "',
'data:image/svg+xml;base64,',
image,
'"}'
)
)
)
)
);
}
function escapeQuotes(string memory symbol) internal pure returns (string memory) {
bytes memory symbolBytes = bytes(symbol);
uint8 quotesCount = 0;
for (uint8 i = 0; i < symbolBytes.length; i++) {
if (symbolBytes[i] == '"') {
quotesCount++;
}
}
if (quotesCount > 0) {
bytes memory escapedBytes = new bytes(symbolBytes.length + (quotesCount));
uint256 index;
for (uint8 i = 0; i < symbolBytes.length; i++) {
if (symbolBytes[i] == '"') {
escapedBytes[index++] = '\\';
}
escapedBytes[index++] = symbolBytes[i];
}
return string(escapedBytes);
}
return symbol;
}
function generateDescriptionPartOne(
string memory quoteTokenSymbol,
string memory baseTokenSymbol,
string memory poolAddress
) private pure returns (string memory) {
return
string(
abi.encodePacked(
'This NFT represents a liquidity position in Bubbly ',
quoteTokenSymbol,
'-',
baseTokenSymbol,
' pool. ',
'The owner of this NFT can modify or redeem the position.\\n',
'\\nPool Address: ',
poolAddress,
'\\n',
quoteTokenSymbol
)
);
}
function generateDescriptionPartTwo(
string memory tokenId,
string memory baseTokenSymbol,
string memory quoteTokenAddress,
string memory baseTokenAddress,
string memory feeTier
) private pure returns (string memory) {
return
string(
abi.encodePacked(
' Address: ',
quoteTokenAddress,
'\\n',
baseTokenSymbol,
' Address: ',
baseTokenAddress,
'\\nFee Tier: ',
feeTier,
'\\nToken ID: ',
tokenId,
'\\n\\n',
unicode'⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure token addresses match the expected tokens, as token symbols may be imitated.'
)
);
}
function generateName(ConstructTokenURIParams memory params, string memory feeTier)
private
pure
returns (string memory)
{
return
string(
abi.encodePacked(
'Bubbly - ',
feeTier,
' - ',
escapeQuotes(params.quoteTokenSymbol),
'/',
escapeQuotes(params.baseTokenSymbol),
' - ',
tickToDecimalString(
!params.flipRatio ? params.tickLower : params.tickUpper,
params.tickSpacing,
params.baseTokenDecimals,
params.quoteTokenDecimals,
params.flipRatio
),
'<>',
tickToDecimalString(
!params.flipRatio ? params.tickUpper : params.tickLower,
params.tickSpacing,
params.baseTokenDecimals,
params.quoteTokenDecimals,
params.flipRatio
)
)
);
}
struct DecimalStringParams {
uint256 sigfigs;
uint8 bufferLength;
uint8 sigfigIndex;
uint8 decimalIndex;
uint8 zerosStartIndex;
uint8 zerosEndIndex;
bool isLessThanOne;
bool isPercent;
}
function generateDecimalString(DecimalStringParams memory params) private pure returns (string memory) {
bytes memory buffer = new bytes(params.bufferLength);
if (params.isPercent) {
buffer[buffer.length - 1] = '%';
}
if (params.isLessThanOne) {
buffer[0] = '0';
buffer[1] = '.';
}
for (uint256 zerosCursor = params.zerosStartIndex; zerosCursor < params.zerosEndIndex.add(1); zerosCursor++) {
buffer[zerosCursor] = bytes1(uint8(48));
}
while (params.sigfigs > 0) {
if (params.decimalIndex > 0 && params.sigfigIndex == params.decimalIndex) {
buffer[params.sigfigIndex--] = '.';
}
buffer[params.sigfigIndex--] = bytes1(uint8(uint256(48).add(params.sigfigs % 10)));
params.sigfigs /= 10;
}
return string(buffer);
}
function tickToDecimalString(
int24 tick,
int24 tickSpacing,
uint8 baseTokenDecimals,
uint8 quoteTokenDecimals,
bool flipRatio
) internal pure returns (string memory) {
if (tick == (TickMath.MIN_TICK / tickSpacing) * tickSpacing) {
return !flipRatio ? 'MIN' : 'MAX';
} else if (tick == (TickMath.MAX_TICK / tickSpacing) * tickSpacing) {
return !flipRatio ? 'MAX' : 'MIN';
} else {
uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick);
if (flipRatio) {
sqrtRatioX96 = uint160(uint256(1 << 192).div(sqrtRatioX96));
}
return fixedPointToDecimalString(sqrtRatioX96, baseTokenDecimals, quoteTokenDecimals);
}
}
function sigfigsRounded(uint256 value, uint8 digits) private pure returns (uint256, bool) {
bool extraDigit;
if (digits > 5) {
value = value.div((10**(digits - 5)));
}
bool roundUp = value % 10 > 4;
value = value.div(10);
if (roundUp) {
value = value + 1;
}
if (value == 100000) {
value /= 10;
extraDigit = true;
}
return (value, extraDigit);
}
function adjustForDecimalPrecision(
uint160 sqrtRatioX96,
uint8 baseTokenDecimals,
uint8 quoteTokenDecimals
) private pure returns (uint256 adjustedSqrtRatioX96) {
uint256 difference = abs(int256(baseTokenDecimals).sub(int256(quoteTokenDecimals)));
if (difference > 0 && difference <= 18) {
if (baseTokenDecimals > quoteTokenDecimals) {
adjustedSqrtRatioX96 = sqrtRatioX96.mul(10**(difference.div(2)));
if (difference % 2 == 1) {
adjustedSqrtRatioX96 = FullMath.mulDiv(adjustedSqrtRatioX96, sqrt10X128, 1 << 128);
}
} else {
adjustedSqrtRatioX96 = sqrtRatioX96.div(10**(difference.div(2)));
if (difference % 2 == 1) {
adjustedSqrtRatioX96 = FullMath.mulDiv(adjustedSqrtRatioX96, 1 << 128, sqrt10X128);
}
}
} else {
adjustedSqrtRatioX96 = uint256(sqrtRatioX96);
}
}
function abs(int256 x) private pure returns (uint256) {
return uint256(x >= 0 ? x : -x);
}
function fixedPointToDecimalString(
uint160 sqrtRatioX96,
uint8 baseTokenDecimals,
uint8 quoteTokenDecimals
) internal pure returns (string memory) {
uint256 adjustedSqrtRatioX96 = adjustForDecimalPrecision(sqrtRatioX96, baseTokenDecimals, quoteTokenDecimals);
uint256 value = FullMath.mulDiv(adjustedSqrtRatioX96, adjustedSqrtRatioX96, 1 << 64);
bool priceBelow1 = adjustedSqrtRatioX96 < 2**96;
if (priceBelow1) {
value = FullMath.mulDiv(value, 10**44, 1 << 128);
} else {
value = FullMath.mulDiv(value, 10**5, 1 << 128);
}
uint256 temp = value;
uint8 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
digits = digits - 1;
(uint256 sigfigs, bool extraDigit) = sigfigsRounded(value, digits);
if (extraDigit) {
digits++;
}
DecimalStringParams memory params;
if (priceBelow1) {
params.bufferLength = uint8(uint8(7).add(uint8(43).sub(digits)));
params.zerosStartIndex = 2;
params.zerosEndIndex = uint8(uint256(43).sub(digits).add(1));
params.sigfigIndex = uint8(params.bufferLength.sub(1));
} else if (digits >= 9) {
params.bufferLength = uint8(digits.sub(4));
params.zerosStartIndex = 5;
params.zerosEndIndex = uint8(params.bufferLength.sub(1));
params.sigfigIndex = 4;
} else {
params.bufferLength = 6;
params.sigfigIndex = 5;
params.decimalIndex = uint8(digits.sub(5).add(1));
}
params.sigfigs = sigfigs;
params.isLessThanOne = priceBelow1;
params.isPercent = false;
return generateDecimalString(params);
}
function feeToPercentString(uint24 fee) internal pure returns (string memory) {
if (fee == 0) {
return '0%';
}
uint24 temp = fee;
uint256 digits;
uint8 numSigfigs;
while (temp != 0) {
if (numSigfigs > 0) {
numSigfigs++;
} else if (temp % 10 != 0) {
numSigfigs++;
}
digits++;
temp /= 10;
}
DecimalStringParams memory params;
uint256 nZeros;
if (digits >= 5) {
uint256 decimalPlace = digits.sub(numSigfigs) >= 4 ? 0 : 1;
nZeros = digits.sub(5) < (numSigfigs.sub(1)) ? 0 : digits.sub(5).sub(numSigfigs.sub(1));
params.zerosStartIndex = numSigfigs;
params.zerosEndIndex = uint8(params.zerosStartIndex.add(nZeros).sub(1));
params.sigfigIndex = uint8(params.zerosStartIndex.sub(1).add(decimalPlace));
params.bufferLength = uint8(nZeros.add(numSigfigs.add(1)).add(decimalPlace));
} else {
nZeros = uint256(5).sub(digits);
params.zerosStartIndex = 2;
params.zerosEndIndex = uint8(nZeros.add(params.zerosStartIndex).sub(1));
params.bufferLength = uint8(nZeros.add(numSigfigs.add(2)));
params.sigfigIndex = uint8((params.bufferLength).sub(2));
params.isLessThanOne = true;
}
params.sigfigs = uint256(fee).div(10**(digits.sub(numSigfigs)));
params.isPercent = true;
params.decimalIndex = digits > 4 ? uint8(digits.sub(4)) : 0;
return generateDecimalString(params);
}
function addressToString(address addr) internal pure returns (string memory) {
return (uint256(addr)).toHexString(20);
}
function generateSVGImage(ConstructTokenURIParams memory params) internal pure returns (string memory svg) {
NFTSVG.SVGParams memory svgParams =
NFTSVG.SVGParams({
quoteToken: addressToString(params.quoteTokenAddress),
baseToken: addressToString(params.baseTokenAddress),
poolAddress: params.poolAddress,
quoteTokenSymbol: params.quoteTokenSymbol,
baseTokenSymbol: params.baseTokenSymbol,
feeTier: feeToPercentString(params.fee),
tickLower: params.tickLower,
tickUpper: params.tickUpper,
tickSpacing: params.tickSpacing,
overRange: overRange(params.tickLower, params.tickUpper, params.tickCurrent),
tokenId: params.tokenId,
color0: tokenToColorHex(uint256(params.quoteTokenAddress), 136),
color1: tokenToColorHex(uint256(params.baseTokenAddress), 136),
color2: tokenToColorHex(uint256(params.quoteTokenAddress), 0),
color3: tokenToColorHex(uint256(params.baseTokenAddress), 0),
x1: scale(getCircleCoord(uint256(params.quoteTokenAddress), 16, params.tokenId), 0, 255, 16, 274),
y1: scale(getCircleCoord(uint256(params.baseTokenAddress), 16, params.tokenId), 0, 255, 100, 484),
x2: scale(getCircleCoord(uint256(params.quoteTokenAddress), 32, params.tokenId), 0, 255, 16, 274),
y2: scale(getCircleCoord(uint256(params.baseTokenAddress), 32, params.tokenId), 0, 255, 100, 484),
x3: scale(getCircleCoord(uint256(params.quoteTokenAddress), 48, params.tokenId), 0, 255, 16, 274),
y3: scale(getCircleCoord(uint256(params.baseTokenAddress), 48, params.tokenId), 0, 255, 100, 484)
});
return NFTSVG.generateSVG(svgParams);
}
function overRange(
int24 tickLower,
int24 tickUpper,
int24 tickCurrent
) private pure returns (int8) {
if (tickCurrent < tickLower) {
return -1;
} else if (tickCurrent > tickUpper) {
return 1;
} else {
return 0;
}
}
function scale(
uint256 n,
uint256 inMn,
uint256 inMx,
uint256 outMn,
uint256 outMx
) private pure returns (string memory) {
return (n.sub(inMn).mul(outMx.sub(outMn)).div(inMx.sub(inMn)).add(outMn)).toString();
}
function tokenToColorHex(uint256 token, uint256 offset) internal pure returns (string memory str) {
return string((token >> offset).toHexStringNoPrefix(3));
}
function getCircleCoord(
uint256 tokenAddress,
uint256 offset,
uint256 tokenId
) internal pure returns (uint256) {
return (sliceTokenHex(tokenAddress, offset) * tokenId) % 255;
}
function sliceTokenHex(uint256 token, uint256 offset) internal pure returns (uint256) {
return uint256(uint8(token >> offset));
}
}
文件 64 的 96:NFTSVG.sol
pragma solidity >=0.7.6;
import '@openzeppelin/contracts/utils/Strings.sol';
import './BitMath.sol';
import 'base64-sol/base64.sol';
library NFTSVG {
using Strings for uint256;
string constant curve1 = 'M1 1C41 41 105 105 145 145';
string constant curve2 = 'M1 1C33 49 97 113 145 145';
string constant curve3 = 'M1 1C33 57 89 113 145 145';
string constant curve4 = 'M1 1C25 65 81 121 145 145';
string constant curve5 = 'M1 1C17 73 73 129 145 145';
string constant curve6 = 'M1 1C9 81 65 137 145 145';
string constant curve7 = 'M1 1C1 89 57.5 145 145 145';
string constant curve8 = 'M1 1C1 97 49 145 145 145';
struct SVGParams {
string quoteToken;
string baseToken;
address poolAddress;
string quoteTokenSymbol;
string baseTokenSymbol;
string feeTier;
int24 tickLower;
int24 tickUpper;
int24 tickSpacing;
int8 overRange;
uint256 tokenId;
string color0;
string color1;
string color2;
string color3;
string x1;
string y1;
string x2;
string y2;
string x3;
string y3;
}
function generateSVG(SVGParams memory params) internal pure returns (string memory svg) {
return
string(
abi.encodePacked(
generateSVGDefs(params),
generateSVGBorderText(
params.quoteToken,
params.baseToken,
params.quoteTokenSymbol,
params.baseTokenSymbol
),
generateSVGCardMantle(params.quoteTokenSymbol, params.baseTokenSymbol, params.feeTier),
generageSvgCurve(params.tickLower, params.tickUpper, params.tickSpacing, params.overRange),
generateSVGPositionDataAndLocationCurve(
params.tokenId.toString(),
params.tickLower,
params.tickUpper
),
generateSVGRareSparkle(params.tokenId, params.poolAddress),
'</svg>'
)
);
}
function generateSVGDefs(SVGParams memory params) private pure returns (string memory svg) {
svg = string(
abi.encodePacked(
'<svg width="290" height="500" viewBox="0 0 290 500" xmlns="http://www.w3.org/2000/svg"',
" xmlns:xlink='http://www.w3.org/1999/xlink'>",
'<defs>',
'<filter id="f1"><feImage result="p0" xlink:href="data:image/svg+xml;base64,',
Base64.encode(
bytes(
abi.encodePacked(
"<svg width='290' height='500' viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'><rect width='290px' height='500px' fill='#",
params.color0,
"'/></svg>"
)
)
),
'"/><feImage result="p1" xlink:href="data:image/svg+xml;base64,',
Base64.encode(
bytes(
abi.encodePacked(
"<svg width='290' height='500' viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'><circle cx='",
params.x1,
"' cy='",
params.y1,
"' r='120px' fill='#",
params.color1,
"'/></svg>"
)
)
),
'"/><feImage result="p2" xlink:href="data:image/svg+xml;base64,',
Base64.encode(
bytes(
abi.encodePacked(
"<svg width='290' height='500' viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'><circle cx='",
params.x2,
"' cy='",
params.y2,
"' r='120px' fill='#",
params.color2,
"'/></svg>"
)
)
),
'" />',
'<feImage result="p3" xlink:href="data:image/svg+xml;base64,',
Base64.encode(
bytes(
abi.encodePacked(
"<svg width='290' height='500' viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'><circle cx='",
params.x3,
"' cy='",
params.y3,
"' r='100px' fill='#",
params.color3,
"'/></svg>"
)
)
),
'" /><feBlend mode="overlay" in="p0" in2="p1" /><feBlend mode="exclusion" in2="p2" /><feBlend mode="overlay" in2="p3" result="blendOut" /><feGaussianBlur ',
'in="blendOut" stdDeviation="42" /></filter> <clipPath id="corners"><rect width="290" height="500" rx="42" ry="42" /></clipPath>',
'<path id="text-path-a" d="M40 12 H250 A28 28 0 0 1 278 40 V460 A28 28 0 0 1 250 488 H40 A28 28 0 0 1 12 460 V40 A28 28 0 0 1 40 12 z" />',
'<path id="minimap" d="M234 444C234 457.949 242.21 463 253 463" />',
'<filter id="top-region-blur"><feGaussianBlur in="SourceGraphic" stdDeviation="24" /></filter>',
'<linearGradient id="grad-up" x1="1" x2="0" y1="1" y2="0"><stop offset="0.0" stop-color="white" stop-opacity="1" />',
'<stop offset=".9" stop-color="white" stop-opacity="0" /></linearGradient>',
'<linearGradient id="grad-down" x1="0" x2="1" y1="0" y2="1"><stop offset="0.0" stop-color="white" stop-opacity="1" /><stop offset="0.9" stop-color="white" stop-opacity="0" /></linearGradient>',
'<mask id="fade-up" maskContentUnits="objectBoundingBox"><rect width="1" height="1" fill="url(#grad-up)" /></mask>',
'<mask id="fade-down" maskContentUnits="objectBoundingBox"><rect width="1" height="1" fill="url(#grad-down)" /></mask>',
'<mask id="none" maskContentUnits="objectBoundingBox"><rect width="1" height="1" fill="white" /></mask>',
'<linearGradient id="grad-symbol"><stop offset="0.7" stop-color="white" stop-opacity="1" /><stop offset=".95" stop-color="white" stop-opacity="0" /></linearGradient>',
'<mask id="fade-symbol" maskContentUnits="userSpaceOnUse"><rect width="290px" height="200px" fill="url(#grad-symbol)" /></mask></defs>',
'<g clip-path="url(#corners)">',
'<rect fill="',
params.color0,
'" x="0px" y="0px" width="290px" height="500px" />',
'<rect style="filter: url(#f1)" x="0px" y="0px" width="290px" height="500px" />',
' <g style="filter:url(#top-region-blur); transform:scale(1.5); transform-origin:center top;">',
'<rect fill="none" x="0px" y="0px" width="290px" height="500px" />',
'<ellipse cx="50%" cy="0px" rx="180px" ry="120px" fill="#000" opacity="0.85" /></g>',
'<rect x="0" y="0" width="290" height="500" rx="42" ry="42" fill="rgba(0,0,0,0)" stroke="rgba(255,255,255,0.2)" /></g>'
)
);
}
function generateSVGBorderText(
string memory quoteToken,
string memory baseToken,
string memory quoteTokenSymbol,
string memory baseTokenSymbol
) private pure returns (string memory svg) {
svg = string(
abi.encodePacked(
'<text text-rendering="optimizeSpeed">',
'<textPath startOffset="-100%" fill="white" font-family="\'Courier New\', monospace" font-size="10px" xlink:href="#text-path-a">',
baseToken,
unicode' • ',
baseTokenSymbol,
' <animate additive="sum" attributeName="startOffset" from="0%" to="100%" begin="0s" dur="30s" repeatCount="indefinite" />',
'</textPath> <textPath startOffset="0%" fill="white" font-family="\'Courier New\', monospace" font-size="10px" xlink:href="#text-path-a">',
baseToken,
unicode' • ',
baseTokenSymbol,
' <animate additive="sum" attributeName="startOffset" from="0%" to="100%" begin="0s" dur="30s" repeatCount="indefinite" /> </textPath>',
'<textPath startOffset="50%" fill="white" font-family="\'Courier New\', monospace" font-size="10px" xlink:href="#text-path-a">',
quoteToken,
unicode' • ',
quoteTokenSymbol,
' <animate additive="sum" attributeName="startOffset" from="0%" to="100%" begin="0s" dur="30s"',
' repeatCount="indefinite" /></textPath><textPath startOffset="-50%" fill="white" font-family="\'Courier New\', monospace" font-size="10px" xlink:href="#text-path-a">',
quoteToken,
unicode' • ',
quoteTokenSymbol,
' <animate additive="sum" attributeName="startOffset" from="0%" to="100%" begin="0s" dur="30s" repeatCount="indefinite" /></textPath></text>'
)
);
}
function generateSVGCardMantle(
string memory quoteTokenSymbol,
string memory baseTokenSymbol,
string memory feeTier
) private pure returns (string memory svg) {
svg = string(
abi.encodePacked(
'<g mask="url(#fade-symbol)"><rect fill="none" x="0px" y="0px" width="290px" height="200px" /> <text y="70px" x="32px" fill="white" font-family="\'Courier New\', monospace" font-weight="200" font-size="36px">',
quoteTokenSymbol,
'/',
baseTokenSymbol,
'</text><text y="115px" x="32px" fill="white" font-family="\'Courier New\', monospace" font-weight="200" font-size="36px">',
feeTier,
'</text></g>',
'<rect x="16" y="16" width="258" height="468" rx="26" ry="26" fill="rgba(0,0,0,0)" stroke="rgba(255,255,255,0.2)" />'
)
);
}
function generageSvgCurve(
int24 tickLower,
int24 tickUpper,
int24 tickSpacing,
int8 overRange
) private pure returns (string memory svg) {
string memory fade = overRange == 1 ? '#fade-up' : overRange == -1 ? '#fade-down' : '#none';
string memory curve = getCurve(tickLower, tickUpper, tickSpacing);
svg = string(
abi.encodePacked(
'<g mask="url(',
fade,
')"',
' style="transform:translate(72px,189px)">'
'<rect x="-16px" y="-16px" width="180px" height="180px" fill="none" />'
'<path d="',
curve,
'" stroke="rgba(0,0,0,0.3)" stroke-width="32px" fill="none" stroke-linecap="round" />',
'</g><g mask="url(',
fade,
')"',
' style="transform:translate(72px,189px)">',
'<rect x="-16px" y="-16px" width="180px" height="180px" fill="none" />',
'<path d="',
curve,
'" stroke="rgba(255,255,255,1)" fill="none" stroke-linecap="round" /></g>',
generateSVGCurveCircle(overRange)
)
);
}
function getCurve(
int24 tickLower,
int24 tickUpper,
int24 tickSpacing
) internal pure returns (string memory curve) {
int24 tickRange = (tickUpper - tickLower) / tickSpacing;
if (tickRange <= 4) {
curve = curve1;
} else if (tickRange <= 8) {
curve = curve2;
} else if (tickRange <= 16) {
curve = curve3;
} else if (tickRange <= 32) {
curve = curve4;
} else if (tickRange <= 64) {
curve = curve5;
} else if (tickRange <= 128) {
curve = curve6;
} else if (tickRange <= 256) {
curve = curve7;
} else {
curve = curve8;
}
}
function generateSVGCurveCircle(int8 overRange) internal pure returns (string memory svg) {
string memory curvex1 = '73';
string memory curvey1 = '190';
string memory curvex2 = '217';
string memory curvey2 = '334';
if (overRange == 1 || overRange == -1) {
svg = string(
abi.encodePacked(
'<circle cx="',
overRange == -1 ? curvex1 : curvex2,
'px" cy="',
overRange == -1 ? curvey1 : curvey2,
'px" r="4px" fill="white" /><circle cx="',
overRange == -1 ? curvex1 : curvex2,
'px" cy="',
overRange == -1 ? curvey1 : curvey2,
'px" r="24px" fill="none" stroke="white" />'
)
);
} else {
svg = string(
abi.encodePacked(
'<circle cx="',
curvex1,
'px" cy="',
curvey1,
'px" r="4px" fill="white" />',
'<circle cx="',
curvex2,
'px" cy="',
curvey2,
'px" r="4px" fill="white" />'
)
);
}
}
function generateSVGPositionDataAndLocationCurve(
string memory tokenId,
int24 tickLower,
int24 tickUpper
) private pure returns (string memory svg) {
string memory tickLowerStr = tickToString(tickLower);
string memory tickUpperStr = tickToString(tickUpper);
uint256 str1length = bytes(tokenId).length + 4;
uint256 str2length = bytes(tickLowerStr).length + 10;
uint256 str3length = bytes(tickUpperStr).length + 10;
(string memory xCoord, string memory yCoord) = rangeLocation(tickLower, tickUpper);
svg = string(
abi.encodePacked(
' <g style="transform:translate(29px, 384px)">',
'<rect width="',
uint256(7 * (str1length + 4)).toString(),
'px" height="26px" rx="8px" ry="8px" fill="rgba(0,0,0,0.6)" />',
'<text x="12px" y="17px" font-family="\'Courier New\', monospace" font-size="12px" fill="white"><tspan fill="rgba(255,255,255,0.6)">ID: </tspan>',
tokenId,
'</text></g>',
' <g style="transform:translate(29px, 414px)">',
'<rect width="',
uint256(7 * (str2length + 4)).toString(),
'px" height="26px" rx="8px" ry="8px" fill="rgba(0,0,0,0.6)" />',
'<text x="12px" y="17px" font-family="\'Courier New\', monospace" font-size="12px" fill="white"><tspan fill="rgba(255,255,255,0.6)">Min Tick: </tspan>',
tickLowerStr,
'</text></g>',
' <g style="transform:translate(29px, 444px)">',
'<rect width="',
uint256(7 * (str3length + 4)).toString(),
'px" height="26px" rx="8px" ry="8px" fill="rgba(0,0,0,0.6)" />',
'<text x="12px" y="17px" font-family="\'Courier New\', monospace" font-size="12px" fill="white"><tspan fill="rgba(255,255,255,0.6)">Max Tick: </tspan>',
tickUpperStr,
'</text></g>'
'<g style="transform:translate(226px, 433px)">',
'<rect width="36px" height="36px" rx="8px" ry="8px" fill="none" stroke="rgba(255,255,255,0.2)" />',
'<path stroke-linecap="round" d="M8 9C8.00004 22.9494 16.2099 28 27 28" fill="none" stroke="white" />',
'<circle style="transform:translate3d(',
xCoord,
'px, ',
yCoord,
'px, 0px)" cx="0px" cy="0px" r="4px" fill="white"/></g>'
)
);
}
function tickToString(int24 tick) private pure returns (string memory) {
string memory sign = '';
if (tick < 0) {
tick = tick * -1;
sign = '-';
}
return string(abi.encodePacked(sign, uint256(tick).toString()));
}
function rangeLocation(int24 tickLower, int24 tickUpper) internal pure returns (string memory, string memory) {
int24 midPoint = (tickLower + tickUpper) / 2;
if (midPoint < -125_000) {
return ('8', '7');
} else if (midPoint < -75_000) {
return ('8', '10.5');
} else if (midPoint < -25_000) {
return ('8', '14.25');
} else if (midPoint < -5_000) {
return ('10', '18');
} else if (midPoint < 0) {
return ('11', '21');
} else if (midPoint < 5_000) {
return ('13', '23');
} else if (midPoint < 25_000) {
return ('15', '25');
} else if (midPoint < 75_000) {
return ('18', '26');
} else if (midPoint < 125_000) {
return ('21', '27');
} else {
return ('24', '27');
}
}
function generateSVGRareSparkle(uint256 tokenId, address poolAddress) private pure returns (string memory svg) {
if (isRare(tokenId, poolAddress)) {
svg = string(
abi.encodePacked(
'<g style="transform:translate(226px, 392px)"><rect width="36px" height="36px" rx="8px" ry="8px" fill="none" stroke="rgba(255,255,255,0.2)" />',
'<g><path style="transform:translate(6px,6px)" d="M12 0L12.6522 9.56587L18 1.6077L13.7819 10.2181L22.3923 6L14.4341 ',
'11.3478L24 12L14.4341 12.6522L22.3923 18L13.7819 13.7819L18 22.3923L12.6522 14.4341L12 24L11.3478 14.4341L6 22.39',
'23L10.2181 13.7819L1.6077 18L9.56587 12.6522L0 12L9.56587 11.3478L1.6077 6L10.2181 10.2181L6 1.6077L11.3478 9.56587L12 0Z" fill="white" />',
'<animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="10s" repeatCount="indefinite"/></g></g>'
)
);
} else {
svg = '';
}
}
function isRare(uint256 tokenId, address poolAddress) internal pure returns (bool) {
bytes32 h = keccak256(abi.encodePacked(tokenId, poolAddress));
return uint256(h) < type(uint256).max / (1 + BitMath.mostSignificantBit(tokenId) * 2);
}
}
文件 65 的 96:NoDelegateCall.sol
pragma solidity =0.7.6;
abstract contract NoDelegateCall {
address private immutable original;
constructor() {
original = address(this);
}
function checkNotDelegateCall() private view {
require(address(this) == original);
}
modifier noDelegateCall() {
checkNotDelegateCall();
_;
}
}
文件 66 的 96:NonfungiblePositionManager.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import './interfaces/IBubblyPool.sol';
import './libraries/FixedPoint128.sol';
import './libraries/FullMath.sol';
import './interfaces/ICollateralPositionManager.sol';
import './interfaces/IBubblyFactory.sol';
import './interfaces/INonfungiblePositionManager.sol';
import './interfaces/INonfungibleTokenPositionDescriptor.sol';
import './libraries/PositionKey.sol';
import './libraries/PoolAddress.sol';
import './base/LiquidityManagement.sol';
import './base/PeripheryImmutableState.sol';
import './base/Multicall.sol';
import './base/ERC721Permit.sol';
import './base/PeripheryValidation.sol';
import './base/SelfPermit.sol';
import '@openzeppelin/contracts/math/SafeMath.sol';
import 'hardhat/console.sol';
contract NonfungiblePositionManager is
INonfungiblePositionManager,
Multicall,
ERC721Permit,
PeripheryImmutableState,
LiquidityManagement,
PeripheryValidation,
SelfPermit
{
struct Position {
uint96 nonce;
address operator;
uint80 poolId;
int24 tickLower;
int24 tickUpper;
uint128 liquidity;
uint256 feeGrowthInsideLastX128;
uint128 tokensOwed;
uint256 lpamount0;
uint256 lpamount1;
uint256 lpcollateral;
}
using SafeMath for uint256;
mapping(address => uint80) private _poolIds;
mapping(uint80 => PoolAddress.PoolKey) private _poolIdToPoolKey;
mapping(uint256 => Position) private _positions;
uint176 private _nextId = 1;
uint80 private _nextPoolId = 1;
address private _tokenDescriptor;
address public immutable CPM;
mapping (address => address) public EmergencyAdmin;
mapping (address => bool) public EmergencyPause;
event SetEmergencyAdmin(address indexed pool, address admin);
event SetEmergencyPause(address indexed pool, bool flag);
constructor(
address _factory,
address _tokenDescriptor_,
address _CPM
) ERC721Permit('Bubbly Positions NFT', 'BUL-POS', '1') PeripheryImmutableState(_factory) {
_tokenDescriptor = _tokenDescriptor_;
CPM = _CPM;
}
modifier onlyFactoryOwner() {
require(msg.sender == IBubblyFactory(factory).owner());
_;
}
modifier onlyFactoryOwnerOrAdmin(address pool) {
require(msg.sender == IBubblyFactory(factory).owner() || msg.sender == EmergencyAdmin[pool] );
_;
}
function settokenDescriptor(address _tokenDescriptor_) onlyFactoryOwner external {
_tokenDescriptor = _tokenDescriptor_;
}
function positions(uint256 tokenId)
external
view
override
returns (
uint96 nonce,
address operator,
address pool,
int24 tickLower,
int24 tickUpper,
uint128 liquidity,
uint256 feeGrowthInsideLastX128,
uint128 tokensOwed,
uint256 lpamount0,
uint256 lpamount1,
uint256 lpcollateral
)
{
Position memory position = _positions[tokenId];
require(position.poolId != 0, 'IID');
PoolAddress.PoolKey memory poolKey = _poolIdToPoolKey[position.poolId];
pool = address(IBubblyPool(PoolAddress.computeAddress(factory, poolKey)));
return (
position.nonce,
position.operator,
pool,
position.tickLower,
position.tickUpper,
position.liquidity,
position.feeGrowthInsideLastX128,
position.tokensOwed,
position.lpamount0,
position.lpamount1,
position.lpcollateral
);
}
function cachePoolKey(address pool, PoolAddress.PoolKey memory poolKey) private returns (uint80 poolId) {
poolId = _poolIds[pool];
if (poolId == 0) {
_poolIds[pool] = (poolId = _nextPoolId++);
_poolIdToPoolKey[poolId] = poolKey;
}
}
function mint(MintParams calldata params)
external
override
checkDeadline(params.deadline)
returns (
uint256 tokenId,
uint128 liquidity,
uint256 amount0,
uint256 amount1,
uint256 collateral
)
{
IBubblyPool pool;
(liquidity, amount0, amount1,collateral, pool) = addLiquidity(
AddLiquidityParams({
token0: params.token0,
token1: params.token1,
fee: params.fee,
recipient: address(this),
tickLower: params.tickLower,
tickUpper: params.tickUpper,
amount0Desired: params.amount0Desired,
amount1Desired: params.amount1Desired,
amount0Min: params.amount0Min,
amount1Min: params.amount1Min
})
);
require(EmergencyPause[address(pool)] == false);
_mint(params.recipient, (tokenId = _nextId++));
bytes32 positionKey = PositionKey.compute(address(this), params.tickLower, params.tickUpper);
(, uint256 feeGrowthInsideLastX128, ) = pool.positions(positionKey);
uint80 poolId =
cachePoolKey(
address(pool),
PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee})
);
_positions[tokenId] = Position({
nonce: 0,
operator: address(0),
poolId: poolId,
tickLower: params.tickLower,
tickUpper: params.tickUpper,
liquidity: liquidity,
feeGrowthInsideLastX128: feeGrowthInsideLastX128,
tokensOwed: 0,
lpamount0: amount0,
lpamount1: amount1,
lpcollateral: collateral
});
emit IncreaseLiquidity(tokenId, liquidity, amount0, amount1);
}
modifier isAuthorizedForToken(uint256 tokenId) {
require(_isApprovedOrOwner(msg.sender, tokenId), 'NP');
_;
}
function tokenURI(uint256 tokenId) public view override(ERC721, IERC721Metadata) returns (string memory) {
require(_exists(tokenId));
return INonfungibleTokenPositionDescriptor(_tokenDescriptor).tokenURI(this, tokenId);
}
function baseURI() public pure override returns (string memory) {}
function increaseLiquidity(IncreaseLiquidityParams calldata params)
external
override
checkDeadline(params.deadline)
returns (
uint128 liquidity,
uint256 amount0,
uint256 amount1
)
{
Position storage position = _positions[params.tokenId];
PoolAddress.PoolKey memory poolKey = _poolIdToPoolKey[position.poolId];
IBubblyPool pool;
uint256 collateral;
(liquidity, amount0, amount1, collateral,pool) = addLiquidity(
AddLiquidityParams({
token0: poolKey.token0,
token1: poolKey.token1,
fee: poolKey.fee,
tickLower: position.tickLower,
tickUpper: position.tickUpper,
amount0Desired: params.amount0Desired,
amount1Desired: params.amount1Desired,
amount0Min: params.amount0Min,
amount1Min: params.amount1Min,
recipient: address(this)
})
);
require(EmergencyPause[address(pool)] == false);
bytes32 positionKey = PositionKey.compute(address(this), position.tickLower, position.tickUpper);
(, uint256 feeGrowthInsideLastX128, ) = pool.positions(positionKey);
position.tokensOwed += uint128(
FullMath.mulDiv(
feeGrowthInsideLastX128 - position.feeGrowthInsideLastX128,
position.liquidity,
FixedPoint128.Q128
)
);
position.feeGrowthInsideLastX128 = feeGrowthInsideLastX128;
position.liquidity = position.liquidity + liquidity;
position.lpcollateral = position.lpcollateral.add(collateral);
position.lpamount0 = position.lpamount0.add(amount0);
position.lpamount1 = position.lpamount1.add(amount1);
emit IncreaseLiquidity(params.tokenId, liquidity, amount0, amount1);
}
function decreaseLiquidity(DecreaseLiquidityParams calldata params)
external
override
isAuthorizedForToken(params.tokenId)
checkDeadline(params.deadline)
returns (uint256 amount0, uint256 amount1)
{
require(params.liquidity > 0);
Position storage position = _positions[params.tokenId];
uint128 positionLiquidity = position.liquidity;
require(positionLiquidity >= params.liquidity);
uint256 amount0used;
uint256 amount1used;
uint256 amountowed;
PoolAddress.PoolKey memory poolKey = _poolIdToPoolKey[position.poolId];
IBubblyPool pool = IBubblyPool(PoolAddress.computeAddress(factory, poolKey));
require(EmergencyPause[address(pool)] == false);
(amount0, amount1,amount0used,amount1used,amountowed) = pool.burn(
position.tickLower,
position.tickUpper,
params.liquidity,
IBubblyPoolActions.burnParams({
liquidity:position.liquidity,
lpamount0:position.lpamount0,
lpamount1:position.lpamount1,
lpcollateral:position.lpcollateral
})
);
require(amount0 >= params.amount0Min && amount1 >= params.amount1Min, 'PLC');
{
bytes32 positionKey = PositionKey.compute(address(this), position.tickLower, position.tickUpper);
(, uint256 feeGrowthInsideLastX128, ) = pool.positions(positionKey);
position.tokensOwed +=
uint128(amountowed) +
uint128(
FullMath.mulDiv(
feeGrowthInsideLastX128 - position.feeGrowthInsideLastX128,
positionLiquidity,
FixedPoint128.Q128
)
);
position.feeGrowthInsideLastX128 = feeGrowthInsideLastX128;
position.liquidity = positionLiquidity - params.liquidity;
position.lpcollateral = position.lpcollateral.sub(amountowed) ;
}
position.lpamount0 = position.lpamount0 - amount0used;
position.lpamount1 = position.lpamount1 - amount1used;
if(position.lpamount0 == 0 && position.lpamount1 ==0) position.lpcollateral = 0;
emit DecreaseLiquidity(params.tokenId, params.liquidity, amount0, amount1,amountowed);
if(amount1 != amount1used ){
address owner = ownerOf(params.tokenId);
ICollateralPositionManager(CPM).mintWithoutSwap(ICollateralPositionManager.MintWithoutSwapParams({
pool:address(pool),
amount0: amount0,
amount1: amount1,
amount0used: amount0used,
amount1used: amount1used,
recipient: owner
}));
}
}
function collect(CollectParams memory params)
public
override
isAuthorizedForToken(params.tokenId)
returns (uint256 amount)
{
require(params.amountMax > 0 );
address recipient = params.recipient == address(0) ? address(this) : params.recipient;
Position storage position = _positions[params.tokenId];
PoolAddress.PoolKey memory poolKey = _poolIdToPoolKey[position.poolId];
IBubblyPool pool = IBubblyPool(PoolAddress.computeAddress(factory, poolKey));
require(EmergencyPause[address(pool)] == false);
uint128 tokensOwed = position.tokensOwed;
if (position.liquidity > 0) {
IBubblyPoolActions.burnParams memory emptyBurn;
pool.burn(position.tickLower, position.tickUpper, 0 ,emptyBurn);
(, uint256 feeGrowthInsideLastX128, ) =
pool.positions(PositionKey.compute(address(this), position.tickLower, position.tickUpper));
tokensOwed += uint128(
FullMath.mulDiv(
feeGrowthInsideLastX128 - position.feeGrowthInsideLastX128,
position.liquidity,
FixedPoint128.Q128
)
);
position.feeGrowthInsideLastX128 = feeGrowthInsideLastX128;
}
uint128 amountCollect = params.amountMax > tokensOwed ? tokensOwed : params.amountMax;
amount = pool.collect(
recipient,
position.tickLower,
position.tickUpper,
amountCollect
);
position.tokensOwed = tokensOwed - amountCollect ;
emit Collect(params.tokenId, recipient, amountCollect);
}
function burn(uint256 tokenId) external override isAuthorizedForToken(tokenId) {
Position storage position = _positions[tokenId];
require(position.liquidity == 0 && position.tokensOwed == 0 , 'NC');
delete _positions[tokenId];
_burn(tokenId);
}
function _getAndIncrementNonce(uint256 tokenId) internal override returns (uint256) {
return uint256(_positions[tokenId].nonce++);
}
function getApproved(uint256 tokenId) public view override(ERC721, IERC721) returns (address) {
require(_exists(tokenId), 'NET');
return _positions[tokenId].operator;
}
function _approve(address to, uint256 tokenId) internal override(ERC721) {
_positions[tokenId].operator = to;
emit Approval(ownerOf(tokenId), to, tokenId);
}
function batchCollect(uint256[] calldata ids, uint128[] calldata amounts) public returns (uint256 totalfee) {
for (uint256 i = 0; i < ids.length; i++) {
totalfee += collect(CollectParams({
tokenId : ids[i],
recipient : msg.sender,
amountMax : amounts[i]
}));
}
}
function setEmergencyAdmin (address _pool ,address _admin) external onlyFactoryOwnerOrAdmin(_pool) {
EmergencyAdmin[_pool] = _admin;
emit SetEmergencyAdmin(_pool, _admin);
}
function setEmergencyPause (address _pool ,bool _flag ) external onlyFactoryOwnerOrAdmin(_pool) {
EmergencyPause[_pool] = _flag;
emit SetEmergencyPause(_pool, _flag);
}
}
文件 67 的 96:Oracle.sol
pragma solidity >=0.5.0 <0.8.0;
library Oracle {
struct Observation {
uint32 blockTimestamp;
int56 tickCumulative;
uint160 secondsPerLiquidityCumulativeX128;
bool initialized;
}
function transform(
Observation memory last,
uint32 blockTimestamp,
int24 tick,
uint128 liquidity
) private pure returns (Observation memory) {
uint32 delta = blockTimestamp - last.blockTimestamp;
return
Observation({
blockTimestamp: blockTimestamp,
tickCumulative: last.tickCumulative + int56(tick) * delta,
secondsPerLiquidityCumulativeX128: last.secondsPerLiquidityCumulativeX128 +
((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)),
initialized: true
});
}
function initialize(Observation[65535] storage self, uint32 time)
internal
returns (uint16 cardinality, uint16 cardinalityNext)
{
self[0] = Observation({
blockTimestamp: time,
tickCumulative: 0,
secondsPerLiquidityCumulativeX128: 0,
initialized: true
});
return (1, 1);
}
function write(
Observation[65535] storage self,
uint16 index,
uint32 blockTimestamp,
int24 tick,
uint128 liquidity,
uint16 cardinality,
uint16 cardinalityNext
) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated) {
Observation memory last = self[index];
if (last.blockTimestamp == blockTimestamp) return (index, cardinality);
if (cardinalityNext > cardinality && index == (cardinality - 1)) {
cardinalityUpdated = cardinalityNext;
} else {
cardinalityUpdated = cardinality;
}
indexUpdated = (index + 1) % cardinalityUpdated;
self[indexUpdated] = transform(last, blockTimestamp, tick, liquidity);
}
function grow(
Observation[65535] storage self,
uint16 current,
uint16 next
) internal returns (uint16) {
require(current > 0, 'I');
if (next <= current) return current;
for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;
return next;
}
function lte(
uint32 time,
uint32 a,
uint32 b
) private pure returns (bool) {
if (a <= time && b <= time) return a <= b;
uint256 aAdjusted = a > time ? a : a + 2**32;
uint256 bAdjusted = b > time ? b : b + 2**32;
return aAdjusted <= bAdjusted;
}
function binarySearch(
Observation[65535] storage self,
uint32 time,
uint32 target,
uint16 index,
uint16 cardinality
) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {
uint256 l = (index + 1) % cardinality;
uint256 r = l + cardinality - 1;
uint256 i;
while (true) {
i = (l + r) / 2;
beforeOrAt = self[i % cardinality];
if (!beforeOrAt.initialized) {
l = i + 1;
continue;
}
atOrAfter = self[(i + 1) % cardinality];
bool targetAtOrAfter = lte(time, beforeOrAt.blockTimestamp, target);
if (targetAtOrAfter && lte(time, target, atOrAfter.blockTimestamp)) break;
if (!targetAtOrAfter) r = i - 1;
else l = i + 1;
}
}
function getSurroundingObservations(
Observation[65535] storage self,
uint32 time,
uint32 target,
int24 tick,
uint16 index,
uint128 liquidity,
uint16 cardinality
) private view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {
beforeOrAt = self[index];
if (lte(time, beforeOrAt.blockTimestamp, target)) {
if (beforeOrAt.blockTimestamp == target) {
return (beforeOrAt, atOrAfter);
} else {
return (beforeOrAt, transform(beforeOrAt, target, tick, liquidity));
}
}
beforeOrAt = self[(index + 1) % cardinality];
if (!beforeOrAt.initialized) beforeOrAt = self[0];
require(lte(time, beforeOrAt.blockTimestamp, target), 'OLD');
return binarySearch(self, time, target, index, cardinality);
}
function observeSingle(
Observation[65535] storage self,
uint32 time,
uint32 secondsAgo,
int24 tick,
uint16 index,
uint128 liquidity,
uint16 cardinality
) internal view returns (int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128) {
if (secondsAgo == 0) {
Observation memory last = self[index];
if (last.blockTimestamp != time) last = transform(last, time, tick, liquidity);
return (last.tickCumulative, last.secondsPerLiquidityCumulativeX128);
}
uint32 target = time - secondsAgo;
(Observation memory beforeOrAt, Observation memory atOrAfter) =
getSurroundingObservations(self, time, target, tick, index, liquidity, cardinality);
if (target == beforeOrAt.blockTimestamp) {
return (beforeOrAt.tickCumulative, beforeOrAt.secondsPerLiquidityCumulativeX128);
} else if (target == atOrAfter.blockTimestamp) {
return (atOrAfter.tickCumulative, atOrAfter.secondsPerLiquidityCumulativeX128);
} else {
uint32 observationTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;
uint32 targetDelta = target - beforeOrAt.blockTimestamp;
return (
beforeOrAt.tickCumulative +
((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / observationTimeDelta) *
targetDelta,
beforeOrAt.secondsPerLiquidityCumulativeX128 +
uint160(
(uint256(
atOrAfter.secondsPerLiquidityCumulativeX128 - beforeOrAt.secondsPerLiquidityCumulativeX128
) * targetDelta) / observationTimeDelta
)
);
}
}
function observe(
Observation[65535] storage self,
uint32 time,
uint32[] memory secondsAgos,
int24 tick,
uint16 index,
uint128 liquidity,
uint16 cardinality
) internal view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) {
require(cardinality > 0, 'I');
tickCumulatives = new int56[](secondsAgos.length);
secondsPerLiquidityCumulativeX128s = new uint160[](secondsAgos.length);
for (uint256 i = 0; i < secondsAgos.length; i++) {
(tickCumulatives[i], secondsPerLiquidityCumulativeX128s[i]) = observeSingle(
self,
time,
secondsAgos[i],
tick,
index,
liquidity,
cardinality
);
}
}
}
文件 68 的 96:OracleLibrary.sol
pragma solidity >=0.5.0 <0.8.0;
import './FullMath.sol';
import './TickMath.sol';
import '../interfaces/IBubblyPool.sol';
library OracleLibrary {
}
文件 69 的 96:Path.sol
pragma solidity >=0.6.0;
import './BytesLib.sol';
library Path {
using BytesLib for bytes;
uint256 private constant ADDR_SIZE = 20;
uint256 private constant FEE_SIZE = 3;
uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE;
uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE;
uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET;
function hasMultiplePools(bytes memory path) internal pure returns (bool) {
return path.length >= MULTIPLE_POOLS_MIN_LENGTH;
}
function numPools(bytes memory path) internal pure returns (uint256) {
return ((path.length - ADDR_SIZE) / NEXT_OFFSET);
}
function decodeFirstPool(bytes memory path)
internal
pure
returns (
address tokenA,
address tokenB,
uint24 fee
)
{
tokenA = path.toAddress(0);
fee = path.toUint24(ADDR_SIZE);
tokenB = path.toAddress(NEXT_OFFSET);
}
function getFirstPool(bytes memory path) internal pure returns (bytes memory) {
return path.slice(0, POP_OFFSET);
}
function skipToken(bytes memory path) internal pure returns (bytes memory) {
return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET);
}
}
文件 70 的 96:PeripheryImmutableState.sol
pragma solidity =0.7.6;
import '../interfaces/IPeripheryImmutableState.sol';
abstract contract PeripheryImmutableState is IPeripheryImmutableState {
address public immutable override factory;
constructor(address _factory) {
factory = _factory;
}
}
文件 71 的 96:PeripheryPayments.sol
pragma solidity >=0.7.5;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '../interfaces/IPeripheryPayments.sol';
import '../libraries/TransferHelper.sol';
import './PeripheryImmutableState.sol';
abstract contract PeripheryPayments is IPeripheryPayments, PeripheryImmutableState {
receive() external payable {
}
function sweepToken(
address token,
uint256 amountMinimum,
address recipient
) public payable override {
uint256 balanceToken = IERC20(token).balanceOf(address(this));
require(balanceToken >= amountMinimum, 'Insufficient token');
if (balanceToken > 0) {
TransferHelper.safeTransfer(token, recipient, balanceToken);
}
}
function refundETH() external payable override {
if (address(this).balance > 0) TransferHelper.safeTransferETH(msg.sender, address(this).balance);
}
function pay(
address token,
address payer,
address recipient,
uint256 value
) internal {
if (payer == address(this)) {
TransferHelper.safeTransfer(token, recipient, value);
} else {
TransferHelper.safeTransferFrom(token, payer, recipient, value);
}
}
}
文件 72 的 96:PeripheryPaymentsWithFee.sol
pragma solidity >=0.7.5;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '../libraries/LowGasSafeMath.sol';
import './PeripheryPayments.sol';
import '../interfaces/IPeripheryPaymentsWithFee.sol';
import '../interfaces/external/IWETH9.sol';
import '../libraries/TransferHelper.sol';
abstract contract PeripheryPaymentsWithFee is PeripheryPayments, IPeripheryPaymentsWithFee {
using LowGasSafeMath for uint256;
function sweepTokenWithFee(
address token,
uint256 amountMinimum,
address recipient,
uint256 feeBips,
address feeRecipient
) public payable override {
require(feeBips > 0 && feeBips <= 100);
uint256 balanceToken = IERC20(token).balanceOf(address(this));
require(balanceToken >= amountMinimum, 'Insufficient token');
if (balanceToken > 0) {
uint256 feeAmount = balanceToken.mul(feeBips) / 10_000;
if (feeAmount > 0) TransferHelper.safeTransfer(token, feeRecipient, feeAmount);
TransferHelper.safeTransfer(token, recipient, balanceToken - feeAmount);
}
}
}
文件 73 的 96:PeripheryValidation.sol
pragma solidity =0.7.6;
import './BlockTimestamp.sol';
abstract contract PeripheryValidation is BlockTimestamp {
modifier checkDeadline(uint256 deadline) {
require(_blockTimestamp() <= deadline, 'Transaction too old');
_;
}
}
文件 74 的 96:PoolAddress.sol
pragma solidity =0.7.6;
library PoolAddress {
bytes32 internal constant POOL_INIT_CODE_HASH = 0x70b0f306879b08155c12dbd7a63bd39e670667c1ef03b364ccffae58d1fb0841;
struct PoolKey {
address token0;
address token1;
uint24 fee;
}
function getPoolKey(
address tokenA,
address tokenB,
uint24 fee,
address quoteToken
) internal pure returns (PoolKey memory) {
if (tokenB != quoteToken) (tokenA, tokenB) = (tokenB, tokenA);
return PoolKey({token0: tokenA, token1: tokenB, fee: fee});
}
function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {
pool = address(
uint256(
keccak256(
abi.encodePacked(
hex'ff',
factory,
keccak256(abi.encode(key.token0, key.token1, key.fee)),
POOL_INIT_CODE_HASH
)
)
)
);
}
}
文件 75 的 96:PoolInitializer.sol
pragma solidity =0.7.6;
import '../interfaces/IBubblyFactory.sol';
import '../interfaces/IBubblyPool.sol';
import './PeripheryImmutableState.sol';
import '../interfaces/IPoolInitializer.sol';
abstract contract PoolInitializer is IPoolInitializer, PeripheryImmutableState {
function createAndInitializePoolIfNecessary(
address token0,
address token1,
uint24 fee,
uint160 sqrtPriceX96
) external payable override returns (address pool) {
pool = IBubblyFactory(factory).getPool(token0, token1, fee);
if (pool == address(0)) {
pool = IBubblyFactory(factory).createPool(token0, token1, fee);
IBubblyPool(pool).initialize(sqrtPriceX96);
} else {
(uint160 sqrtPriceX96Existing, , , , , , ) = IBubblyPool(pool).slot0();
if (sqrtPriceX96Existing == 0) {
IBubblyPool(pool).initialize(sqrtPriceX96);
}
}
}
}
文件 76 的 96:PoolTicksCounter.sol
pragma solidity =0.7.6;
import '../interfaces/IBubblyPool.sol';
library PoolTicksCounter {
function countInitializedTicksCrossed(
IBubblyPool self,
int24 tickBefore,
int24 tickAfter
) internal view returns (uint32 initializedTicksCrossed) {
int16 wordPosLower;
int16 wordPosHigher;
uint8 bitPosLower;
uint8 bitPosHigher;
bool tickBeforeInitialized;
bool tickAfterInitialized;
{
int16 wordPos = int16((tickBefore / self.tickSpacing()) >> 8);
uint8 bitPos = uint8((tickBefore / self.tickSpacing()) % 256);
int16 wordPosAfter = int16((tickAfter / self.tickSpacing()) >> 8);
uint8 bitPosAfter = uint8((tickAfter / self.tickSpacing()) % 256);
tickAfterInitialized =
((self.tickBitmap(wordPosAfter) & (1 << bitPosAfter)) > 0) &&
((tickAfter % self.tickSpacing()) == 0) &&
(tickBefore > tickAfter);
tickBeforeInitialized =
((self.tickBitmap(wordPos) & (1 << bitPos)) > 0) &&
((tickBefore % self.tickSpacing()) == 0) &&
(tickBefore < tickAfter);
if (wordPos < wordPosAfter || (wordPos == wordPosAfter && bitPos <= bitPosAfter)) {
wordPosLower = wordPos;
bitPosLower = bitPos;
wordPosHigher = wordPosAfter;
bitPosHigher = bitPosAfter;
} else {
wordPosLower = wordPosAfter;
bitPosLower = bitPosAfter;
wordPosHigher = wordPos;
bitPosHigher = bitPos;
}
}
uint256 mask = type(uint256).max << bitPosLower;
while (wordPosLower <= wordPosHigher) {
if (wordPosLower == wordPosHigher) {
mask = mask & (type(uint256).max >> (255 - bitPosHigher));
}
uint256 masked = self.tickBitmap(wordPosLower) & mask;
initializedTicksCrossed += countOneBits(masked);
wordPosLower++;
mask = type(uint256).max;
}
if (tickAfterInitialized) {
initializedTicksCrossed -= 1;
}
if (tickBeforeInitialized) {
initializedTicksCrossed -= 1;
}
return initializedTicksCrossed;
}
function countOneBits(uint256 x) private pure returns (uint16) {
uint16 bits = 0;
while (x != 0) {
bits++;
x &= (x - 1);
}
return bits;
}
}
文件 77 的 96:Position.sol
pragma solidity >=0.5.0 <0.8.0;
import './FullMath.sol';
import './FixedPoint128.sol';
import './LiquidityMath.sol';
library Position {
struct Info {
uint128 liquidity;
uint256 feeGrowthInsideLastX128;
uint128 tokensOwed;
}
function get(
mapping(bytes32 => Info) storage self,
address owner,
int24 tickLower,
int24 tickUpper
) internal view returns (Position.Info storage position) {
position = self[keccak256(abi.encodePacked(owner, tickLower, tickUpper))];
}
function update(
Info storage self,
int128 liquidityDelta,
uint256 feeGrowthInsideX128
) internal {
Info memory _self = self;
uint128 liquidityNext;
if (liquidityDelta == 0) {
require(_self.liquidity > 0, 'NP');
liquidityNext = _self.liquidity;
} else {
liquidityNext = LiquidityMath.addDelta(_self.liquidity, liquidityDelta);
}
uint128 tokensOwed =
uint128(
FullMath.mulDiv(
feeGrowthInsideX128 - _self.feeGrowthInsideLastX128,
_self.liquidity,
FixedPoint128.Q128
)
);
if (liquidityDelta != 0) self.liquidity = liquidityNext;
self.feeGrowthInsideLastX128 = feeGrowthInsideX128;
if (tokensOwed > 0 ) {
self.tokensOwed += tokensOwed;
}
}
}
文件 78 的 96:PositionKey.sol
pragma solidity >=0.5.0;
library PositionKey {
function compute(
address owner,
int24 tickLower,
int24 tickUpper
) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(owner, tickLower, tickUpper));
}
}
文件 79 的 96:QuoterV2.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import './libraries/SafeCast.sol';
import './libraries/TickMath.sol';
import './libraries/TickBitmap.sol';
import './interfaces/IBubblyPool.sol';
import './interfaces/callback/IBubblySwapCallback.sol';
import './interfaces/ICollateralPositionManager.sol';
import './interfaces/IQuoterV2.sol';
import './base/PeripheryImmutableState.sol';
import './libraries/Path.sol';
import './libraries/PoolAddress.sol';
import './libraries/CallbackValidation.sol';
import './libraries/PoolTicksCounter.sol';
import './libraries/LiquidityAmounts.sol';
import './libraries/SqrtPriceMathPartial.sol';
import 'hardhat/console.sol';
interface IBubblypool{
function CPM() external view returns (address);
}
contract QuoterV2 is IQuoterV2, IBubblySwapCallback, PeripheryImmutableState {
using Path for bytes;
using SafeCast for uint256;
using PoolTicksCounter for IBubblyPool;
uint256 private amountOutCached;
constructor(address _factory) PeripheryImmutableState(_factory) {}
struct PreMintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
}
function getPool(
address quoteToken,
address tokenA,
address tokenB,
uint24 fee
) private view returns (IBubblyPool) {
return IBubblyPool(PoolAddress.computeAddress(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee, quoteToken)));
}
function BubblySwapCallback(
bool isOpen,
int256 amount0Delta,
int256 amount1Delta,
bytes memory path
) external view override {
require(amount1Delta > 0 || amount0Delta > 0 );
(address tokenIn, address tokenOut, uint24 fee) = path.decodeFirstPool();
address quoteToken = IBubblyPool(msg.sender).token1();
(bool isExactInput, uint256 amountToPay, uint256 amountReceived) =
amount0Delta > 0
? (tokenIn != quoteToken, uint256(amount0Delta), uint256(-amount1Delta))
: (tokenOut != quoteToken, uint256(amount1Delta), uint256(-amount0Delta));
IBubblyPool pool = getPool(quoteToken, tokenIn, tokenOut, fee);
(uint160 sqrtPriceX96After, int24 tickAfter, , , , , ) = pool.slot0();
if (isExactInput) {
assembly {
let ptr := mload(0x40)
mstore(ptr, amountReceived)
mstore(add(ptr, 0x20), sqrtPriceX96After)
mstore(add(ptr, 0x40), tickAfter)
revert(ptr, 96)
}
} else {
assembly {
let ptr := mload(0x40)
mstore(ptr, amountToPay)
mstore(add(ptr, 0x20), sqrtPriceX96After)
mstore(add(ptr, 0x40), tickAfter)
revert(ptr, 96)
}
}
}
function parseRevertReason(bytes memory reason)
private
pure
returns (
uint256 amount,
uint160 sqrtPriceX96After,
int24 tickAfter
)
{
if (reason.length != 96) {
if (reason.length < 68) revert('Unexpected error');
assembly {
reason := add(reason, 0x04)
}
revert(abi.decode(reason, (string)));
}
return abi.decode(reason, (uint256, uint160, int24));
}
function handleRevert(
bytes memory reason,
IBubblyPool pool,
uint256 gasEstimate
)
private
view
returns (
uint256 amount,
uint160 sqrtPriceX96After,
uint256
)
{
int24 tickBefore;
int24 tickAfter;
(, tickBefore, , , , , ) = pool.slot0();
(amount, sqrtPriceX96After, tickAfter) = parseRevertReason(reason);
return (amount, sqrtPriceX96After, gasEstimate);
}
function quoteExactInputSingle(QuoteExactInputSingleParams memory params)
public
override
returns (
uint256 amountOut,
uint160 sqrtPriceX96After,
uint256 gasEstimate
)
{
bool zeroForOne = params.tokenIn != params.quoteToken;
IBubblyPool pool = getPool(params.quoteToken, params.tokenIn, params.tokenOut, params.fee);
uint256 gasBefore = gasleft();
try
pool.swap(
IBubblyPoolActions.SwapParams({
recipient : address(this),
zeroForOne : zeroForOne,
amountSpecified : params.amountIn.toInt256(),
isOpen : params.isOpen,
collateralamount : uint256(0),
sqrtPriceLimitX96: params.sqrtPriceLimitX96 == 0
? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1)
: params.sqrtPriceLimitX96
}),
abi.encodePacked(params.tokenIn, params.fee, params.tokenOut)
)
{} catch (bytes memory reason) {
gasEstimate = gasBefore - gasleft();
return handleRevert(reason, pool, gasEstimate);
}
}
function quoteExactOutputSingle(QuoteExactOutputSingleParams memory params)
public
override
returns (
uint256 amountIn,
uint160 sqrtPriceX96After,
uint256 gasEstimate
)
{
bool zeroForOne = params.tokenIn != params.quoteToken;
IBubblyPool pool = getPool(params.quoteToken ,params.tokenIn, params.tokenOut, params.fee);
address CPM = IBubblypool(address(pool)).CPM();
(uint256 collater0,uint256 collateral) = ICollateralPositionManager(CPM).getShortPosition(address(pool), msg.sender);
if (params.sqrtPriceLimitX96 == 0) amountOutCached = params.amount;
uint256 gasBefore = gasleft();
try
pool.swap(
IBubblyPoolActions.SwapParams({
recipient : address(this),
zeroForOne : zeroForOne,
amountSpecified : -params.amount.toInt256(),
isOpen : params.isOpen,
collateralamount : collateral,
sqrtPriceLimitX96: params.sqrtPriceLimitX96 == 0
? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1)
: params.sqrtPriceLimitX96
}),
abi.encodePacked(params.tokenOut, params.fee, params.tokenIn)
)
{} catch (bytes memory reason) {
gasEstimate = gasBefore - gasleft();
if (params.sqrtPriceLimitX96 == 0) delete amountOutCached;
return handleRevert(reason, pool, gasEstimate);
}
}
function mintPreview(PreMintParams calldata params)
view
public
returns (
uint128 liquidity,
uint256 amount0,
uint256 amount1,
uint256 collateral
)
{
IBubblyPool pool;
PoolAddress.PoolKey memory poolKey =
PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee});
pool = IBubblyPool(PoolAddress.computeAddress(factory,poolKey));
(uint160 sqrtPriceX96, , , , , , ) = pool.slot0();
uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(params.tickLower);
uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(params.tickUpper);
{
liquidity = LiquidityAmounts.getLiquidityForAmounts(
sqrtPriceX96,
sqrtRatioAX96,
sqrtRatioBX96,
params.amount0Desired,
params.amount1Desired
);
}
uint256 amount0inUSD;
if ( sqrtPriceX96 < sqrtRatioAX96 ){
amount0inUSD = SqrtPriceMathPartial.getAmount1Delta(
sqrtRatioAX96,
sqrtRatioBX96,
liquidity,
true
);
}else if(sqrtPriceX96 > sqrtRatioBX96){
amount1 = SqrtPriceMathPartial.getAmount1Delta(
sqrtRatioAX96,
sqrtRatioBX96,
liquidity,
true
);
}
else {
amount0inUSD = SqrtPriceMathPartial.getAmount1Delta(
sqrtPriceX96,
sqrtRatioBX96,
liquidity,
true
);
amount0 = SqrtPriceMathPartial.getAmount1Delta(
sqrtPriceX96,
sqrtRatioBX96,
liquidity,
true
);
amount1 = SqrtPriceMathPartial.getAmount1Delta(
sqrtRatioAX96,
sqrtPriceX96,
liquidity,
true
);
}
collateral = amount0inUSD > amount1 ? amount0inUSD : amount1;
}
}
文件 80 的 96:SafeCast.sol
pragma solidity >=0.5.0;
library SafeCast {
function toUint160(uint256 y) internal pure returns (uint160 z) {
require((z = uint160(y)) == y);
}
function toInt128(int256 y) internal pure returns (int128 z) {
require((z = int128(y)) == y);
}
function toInt256(uint256 y) internal pure returns (int256 z) {
require(y < 2**255);
z = int256(y);
}
}
文件 81 的 96:SafeMath.sol
pragma solidity ^0.7.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
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) {
if (b == 0) return (false, 0);
return (true, a / b);
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
文件 82 的 96:SelfPermit.sol
pragma solidity >=0.5.0;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/drafts/IERC20Permit.sol';
import '../interfaces/ISelfPermit.sol';
import '../interfaces/external/IERC20PermitAllowed.sol';
abstract contract SelfPermit is ISelfPermit {
function selfPermit(
address token,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public payable override {
IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s);
}
function selfPermitIfNecessary(
address token,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external payable override {
if (IERC20(token).allowance(msg.sender, address(this)) < value) selfPermit(token, value, deadline, v, r, s);
}
function selfPermitAllowed(
address token,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) public payable override {
IERC20PermitAllowed(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s);
}
function selfPermitAllowedIfNecessary(
address token,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) external payable override {
if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max)
selfPermitAllowed(token, nonce, expiry, v, r, s);
}
}
文件 83 的 96:SignedSafeMath.sol
pragma solidity ^0.7.0;
library SignedSafeMath {
int256 constant private _INT256_MIN = -2**255;
function mul(int256 a, int256 b) internal pure returns (int256) {
if (a == 0) {
return 0;
}
require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");
int256 c = a * b;
require(c / a == b, "SignedSafeMath: multiplication overflow");
return c;
}
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0, "SignedSafeMath: division by zero");
require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");
int256 c = a / b;
return c;
}
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");
return c;
}
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");
return c;
}
}
文件 84 的 96:SqrtPriceMath.sol
pragma solidity >=0.5.0;
import './LowGasSafeMath.sol';
import './SafeCast.sol';
import './FullMath.sol';
import './UnsafeMath.sol';
import './FixedPoint96.sol';
library SqrtPriceMath {
using LowGasSafeMath for uint256;
using SafeCast for uint256;
function getNextSqrtPriceFromAmount0RoundingUp(
uint160 sqrtPX96,
uint128 liquidity,
uint256 amount,
bool add
) internal pure returns (uint160) {
if (amount == 0) return sqrtPX96;
uint256 numerator1 = uint256(liquidity) << FixedPoint96.RESOLUTION;
if (add) {
uint256 product;
if ((product = amount * sqrtPX96) / amount == sqrtPX96) {
uint256 denominator = numerator1 + product;
if (denominator >= numerator1)
return uint160(FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator));
}
return uint160(UnsafeMath.divRoundingUp(numerator1, (numerator1 / sqrtPX96).add(amount)));
} else {
uint256 product;
require((product = amount * sqrtPX96) / amount == sqrtPX96 && numerator1 > product);
uint256 denominator = numerator1 - product;
return FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator).toUint160();
}
}
function getNextSqrtPriceFromAmount1RoundingDown(
uint160 sqrtPX96,
uint128 liquidity,
uint256 amount,
bool add
) internal pure returns (uint160) {
if (add) {
uint256 quotient =
(
amount <= type(uint160).max
? (amount << FixedPoint96.RESOLUTION) / liquidity
: FullMath.mulDiv(amount, FixedPoint96.Q96, liquidity)
);
return uint256(sqrtPX96).add(quotient).toUint160();
} else {
uint256 quotient =
(
amount <= type(uint160).max
? UnsafeMath.divRoundingUp(amount << FixedPoint96.RESOLUTION, liquidity)
: FullMath.mulDivRoundingUp(amount, FixedPoint96.Q96, liquidity)
);
require(sqrtPX96 > quotient);
return uint160(sqrtPX96 - quotient);
}
}
function getNextSqrtPriceFromInput(
uint160 sqrtPX96,
uint128 liquidity,
uint256 amountIn,
bool zeroForOne
) internal pure returns (uint160 sqrtQX96) {
require(sqrtPX96 > 0);
require(liquidity > 0);
return
zeroForOne
? getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountIn, true)
: getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountIn, true);
}
function getNextSqrtPriceFromOutput(
uint160 sqrtPX96,
uint128 liquidity,
uint256 amountOut,
bool zeroForOne
) internal pure returns (uint160 sqrtQX96) {
require(sqrtPX96 > 0);
require(liquidity > 0);
return
zeroForOne
? getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountOut, false)
: getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountOut, false);
}
function getAmount0Delta(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint128 liquidity,
bool roundUp
) internal pure returns (uint256 amount0) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
uint256 numerator1 = uint256(liquidity) << FixedPoint96.RESOLUTION;
uint256 numerator2 = sqrtRatioBX96 - sqrtRatioAX96;
require(sqrtRatioAX96 > 0);
return
roundUp
? UnsafeMath.divRoundingUp(
FullMath.mulDivRoundingUp(numerator1, numerator2, sqrtRatioBX96),
sqrtRatioAX96
)
: FullMath.mulDiv(numerator1, numerator2, sqrtRatioBX96) / sqrtRatioAX96;
}
function getAmount1Delta(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint128 liquidity,
bool roundUp
) internal pure returns (uint256 amount1) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
return
roundUp
? FullMath.mulDivRoundingUp(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96)
: FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);
}
function getAmount0Delta(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
int128 liquidity
) internal pure returns (int256 amount0) {
return
liquidity < 0
? -getAmount0Delta(sqrtRatioAX96, sqrtRatioBX96, uint128(-liquidity), false).toInt256()
: getAmount0Delta(sqrtRatioAX96, sqrtRatioBX96, uint128(liquidity), true).toInt256();
}
function getAmount1Delta(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
int128 liquidity
) internal pure returns (int256 amount1) {
return
liquidity < 0
? -getAmount1Delta(sqrtRatioAX96, sqrtRatioBX96, uint128(-liquidity), false).toInt256()
: getAmount1Delta(sqrtRatioAX96, sqrtRatioBX96, uint128(liquidity), true).toInt256();
}
}
文件 85 的 96:SqrtPriceMathPartial.sol
pragma solidity >=0.5.0;
import './FullMath.sol';
import './UnsafeMath.sol';
import './FixedPoint96.sol';
library SqrtPriceMathPartial {
function getAmount0Delta(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint128 liquidity,
bool roundUp
) internal pure returns (uint256 amount0) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
uint256 numerator1 = uint256(liquidity) << FixedPoint96.RESOLUTION;
uint256 numerator2 = sqrtRatioBX96 - sqrtRatioAX96;
require(sqrtRatioAX96 > 0);
return
roundUp
? UnsafeMath.divRoundingUp(
FullMath.mulDivRoundingUp(numerator1, numerator2, sqrtRatioBX96),
sqrtRatioAX96
)
: FullMath.mulDiv(numerator1, numerator2, sqrtRatioBX96) / sqrtRatioAX96;
}
function getAmount1Delta(
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96,
uint128 liquidity,
bool roundUp
) internal pure returns (uint256 amount1) {
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
return
roundUp
? FullMath.mulDivRoundingUp(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96)
: FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);
}
}
文件 86 的 96:Strings.sol
pragma solidity ^0.7.0;
library Strings {
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
uint256 index = digits - 1;
temp = value;
while (temp != 0) {
buffer[index--] = bytes1(uint8(48 + temp % 10));
temp /= 10;
}
return string(buffer);
}
}
文件 87 的 96:SwapMath.sol
pragma solidity >=0.5.0;
import './FullMath.sol';
import './SqrtPriceMath.sol';
library SwapMath {
function computeSwapStep(
uint160 sqrtRatioCurrentX96,
uint160 sqrtRatioTargetX96,
uint128 liquidity,
int256 amountRemaining,
uint24 feePips
)
internal
pure
returns (
uint160 sqrtRatioNextX96,
uint256 amountIn,
uint256 amountOut,
uint256 feeAmount
)
{
bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96;
bool exactIn = amountRemaining >= 0;
if (exactIn) {
uint256 amountRemainingLessFee = FullMath.mulDiv(uint256(amountRemaining), 1e6 - feePips, 1e6);
amountIn = zeroForOne
? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true)
: SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true);
if (amountRemainingLessFee >= amountIn) sqrtRatioNextX96 = sqrtRatioTargetX96;
else
sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromInput(
sqrtRatioCurrentX96,
liquidity,
amountRemainingLessFee,
zeroForOne
);
} else {
amountOut = zeroForOne
? SqrtPriceMath.getAmount1Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false)
: SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false);
if (uint256(-amountRemaining) >= amountOut) sqrtRatioNextX96 = sqrtRatioTargetX96;
else
sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromOutput(
sqrtRatioCurrentX96,
liquidity,
uint256(-amountRemaining),
zeroForOne
);
}
bool max = sqrtRatioTargetX96 == sqrtRatioNextX96;
if (zeroForOne) {
amountIn = max && exactIn
? amountIn
: SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true);
amountOut = max && !exactIn
? amountOut
: SqrtPriceMath.getAmount1Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, false);
} else {
amountIn = max && exactIn
? amountIn
: SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true);
amountOut = max && !exactIn
? amountOut
: SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, false);
}
if (!exactIn && amountOut > uint256(-amountRemaining)) {
amountOut = uint256(-amountRemaining);
}
if (exactIn && sqrtRatioNextX96 != sqrtRatioTargetX96) {
feeAmount = uint256(amountRemaining) - amountIn;
} else {
feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, 1e6 - feePips);
}
}
}
文件 88 的 96:Tick.sol
pragma solidity >=0.5.0 <0.8.0;
import './LowGasSafeMath.sol';
import './SafeCast.sol';
import './TickMath.sol';
import './LiquidityMath.sol';
library Tick {
using LowGasSafeMath for int256;
using SafeCast for int256;
struct Info {
uint128 liquidityGross;
int128 liquidityNet;
uint256 feeGrowthOutsideX128;
int56 tickCumulativeOutside;
uint160 secondsPerLiquidityOutsideX128;
uint32 secondsOutside;
bool initialized;
}
function tickSpacingToMaxLiquidityPerTick(int24 tickSpacing) internal pure returns (uint128) {
int24 minTick = (TickMath.MIN_TICK / tickSpacing) * tickSpacing;
int24 maxTick = (TickMath.MAX_TICK / tickSpacing) * tickSpacing;
uint24 numTicks = uint24((maxTick - minTick) / tickSpacing) + 1;
return type(uint128).max / numTicks;
}
function getFeeGrowthInside(
mapping(int24 => Tick.Info) storage self,
int24 tickLower,
int24 tickUpper,
int24 tickCurrent,
uint256 feeGrowthGlobalX128
) internal view returns (uint256 feeGrowthInsideX128) {
Info storage lower = self[tickLower];
Info storage upper = self[tickUpper];
uint256 feeGrowthBelowX128;
if (tickCurrent >= tickLower) {
feeGrowthBelowX128 = lower.feeGrowthOutsideX128;
} else {
feeGrowthBelowX128 = feeGrowthGlobalX128 - lower.feeGrowthOutsideX128;
}
uint256 feeGrowthAboveX128;
if (tickCurrent < tickUpper) {
feeGrowthAboveX128 = upper.feeGrowthOutsideX128;
} else {
feeGrowthAboveX128 = feeGrowthGlobalX128 - upper.feeGrowthOutsideX128;
}
feeGrowthInsideX128 = feeGrowthGlobalX128 - feeGrowthBelowX128 - feeGrowthAboveX128;
}
function update(
mapping(int24 => Tick.Info) storage self,
int24 tick,
int24 tickCurrent,
int128 liquidityDelta,
uint256 feeGrowthGlobalX128,
uint160 secondsPerLiquidityCumulativeX128,
int56 tickCumulative,
uint32 time,
bool upper,
uint128 maxLiquidity
) internal returns (bool flipped) {
Tick.Info storage info = self[tick];
uint128 liquidityGrossBefore = info.liquidityGross;
uint128 liquidityGrossAfter = LiquidityMath.addDelta(liquidityGrossBefore, liquidityDelta);
require(liquidityGrossAfter <= maxLiquidity, 'LO');
flipped = (liquidityGrossAfter == 0) != (liquidityGrossBefore == 0);
if (liquidityGrossBefore == 0) {
if (tick <= tickCurrent) {
info.feeGrowthOutsideX128 = feeGrowthGlobalX128;
info.secondsPerLiquidityOutsideX128 = secondsPerLiquidityCumulativeX128;
info.tickCumulativeOutside = tickCumulative;
info.secondsOutside = time;
}
info.initialized = true;
}
info.liquidityGross = liquidityGrossAfter;
info.liquidityNet = upper
? int256(info.liquidityNet).sub(liquidityDelta).toInt128()
: int256(info.liquidityNet).add(liquidityDelta).toInt128();
}
function clear(mapping(int24 => Tick.Info) storage self, int24 tick) internal {
delete self[tick];
}
function cross(
mapping(int24 => Tick.Info) storage self,
int24 tick,
uint256 feeGrowthGlobalX128,
uint160 secondsPerLiquidityCumulativeX128,
int56 tickCumulative,
uint32 time
) internal returns (int128 liquidityNet) {
Tick.Info storage info = self[tick];
info.feeGrowthOutsideX128 = feeGrowthGlobalX128 - info.feeGrowthOutsideX128;
info.secondsPerLiquidityOutsideX128 = secondsPerLiquidityCumulativeX128 - info.secondsPerLiquidityOutsideX128;
info.tickCumulativeOutside = tickCumulative - info.tickCumulativeOutside;
info.secondsOutside = time - info.secondsOutside;
liquidityNet = info.liquidityNet;
}
}
文件 89 的 96:TickBitmap.sol
pragma solidity =0.7.6;
import './BitMath.sol';
library TickBitmap {
function position(int24 tick) private pure returns (int16 wordPos, uint8 bitPos) {
wordPos = int16(tick >> 8);
bitPos = uint8(tick % 256);
}
function flipTick(
mapping(int16 => uint256) storage self,
int24 tick,
int24 tickSpacing
) internal {
require(tick % tickSpacing == 0);
(int16 wordPos, uint8 bitPos) = position(tick / tickSpacing);
uint256 mask = 1 << bitPos;
self[wordPos] ^= mask;
}
function nextInitializedTickWithinOneWord(
mapping(int16 => uint256) storage self,
int24 tick,
int24 tickSpacing,
bool lte
) internal view returns (int24 next, bool initialized) {
int24 compressed = tick / tickSpacing;
if (tick < 0 && tick % tickSpacing != 0) compressed--;
if (lte) {
(int16 wordPos, uint8 bitPos) = position(compressed);
uint256 mask = (1 << bitPos) - 1 + (1 << bitPos);
uint256 masked = self[wordPos] & mask;
initialized = masked != 0;
next = initialized
? (compressed - int24(bitPos - BitMath.mostSignificantBit(masked))) * tickSpacing
: (compressed - int24(bitPos)) * tickSpacing;
} else {
(int16 wordPos, uint8 bitPos) = position(compressed + 1);
uint256 mask = ~((1 << bitPos) - 1);
uint256 masked = self[wordPos] & mask;
initialized = masked != 0;
next = initialized
? (compressed + 1 + int24(BitMath.leastSignificantBit(masked) - bitPos)) * tickSpacing
: (compressed + 1 + int24(type(uint8).max - bitPos)) * tickSpacing;
}
}
}
文件 90 的 96:TickMath.sol
pragma solidity >=0.5.0 <0.8.0;
library TickMath {
int24 internal constant MIN_TICK = -887272;
int24 internal constant MAX_TICK = -MIN_TICK;
uint160 internal constant MIN_SQRT_RATIO = 4295128739;
uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;
function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {
uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
require(absTick <= uint256(MAX_TICK), 'T');
uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;
if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;
if (tick > 0) ratio = type(uint256).max / ratio;
sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
}
function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {
require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');
uint256 ratio = uint256(sqrtPriceX96) << 32;
uint256 r = ratio;
uint256 msb = 0;
assembly {
let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(5, gt(r, 0xFFFFFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(4, gt(r, 0xFFFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(3, gt(r, 0xFF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(2, gt(r, 0xF))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := shl(1, gt(r, 0x3))
msb := or(msb, f)
r := shr(f, r)
}
assembly {
let f := gt(r, 0x1)
msb := or(msb, f)
}
if (msb >= 128) r = ratio >> (msb - 127);
else r = ratio << (127 - msb);
int256 log_2 = (int256(msb) - 128) << 64;
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(63, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(62, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(61, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(60, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(59, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(58, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(57, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(56, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(55, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(54, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(53, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(52, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(51, f))
r := shr(f, r)
}
assembly {
r := shr(127, mul(r, r))
let f := shr(128, r)
log_2 := or(log_2, shl(50, f))
}
int256 log_sqrt10001 = log_2 * 255738958999603826347141;
int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);
int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);
tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;
}
}
文件 91 的 96:TransferHelper.sol
pragma solidity >=0.6.0;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
library TransferHelper {
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
(bool success, bytes memory data) =
token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF');
}
function safeTransfer(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST');
}
function safeApprove(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA');
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, 'STE');
}
}
文件 92 的 96:UnsafeMath.sol
pragma solidity >=0.5.0;
library UnsafeMath {
function divRoundingUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
assembly {
z := add(div(x, y), gt(mod(x, y), 0))
}
}
}
文件 93 的 96:base64.sol
library Base64 {
string internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
function encode(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return '';
string memory table = TABLE;
uint256 encodedLen = 4 * ((data.length + 2) / 3);
string memory result = new string(encodedLen + 32);
assembly {
mstore(result, encodedLen)
let tablePtr := add(table, 1)
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
let resultPtr := add(result, 32)
for {} lt(dataPtr, endPtr) {}
{
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F)))))
resultPtr := add(resultPtr, 1)
}
switch mod(mload(data), 3)
case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
}
return result;
}
}
文件 94 的 96:batchTx.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import './interfaces/IDelivery.sol';
import './interfaces/ICollateralPositionManager.sol';
import './interfaces/IBubblyPool.sol';
import './interfaces/IBubblyFactory.sol';
import './libraries/LowGasSafeMath.sol';
import './libraries/TransferHelper.sol';
import './libraries/FullMath.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import './interfaces/IERC20Minimal.sol';
import 'hardhat/console.sol';
contract batchTx{
constructor(){
}
function approveToContract(address token, address spender, uint256 amount) external {
IERC20(token).approve(spender, amount);
}
function batchCall(address[] calldata contractAddr, bytes[] calldata calldataArray ) external {
uint256 length = contractAddr.length;
for(uint256 i = 0; i < length; i++){
console.log("come into tx:" ,i);
(bool success, ) = address(contractAddr[i]).call(calldataArray[i]);
if (!success) {
assembly {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
}
}
文件 95 的 96:console.sol
pragma solidity >= 0.4.22 <0.9.0;
library console {
address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);
function _sendLogPayload(bytes memory payload) private view {
uint256 payloadLength = payload.length;
address consoleAddress = CONSOLE_ADDRESS;
assembly {
let payloadStart := add(payload, 32)
let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
}
}
function log() internal view {
_sendLogPayload(abi.encodeWithSignature("log()"));
}
function logInt(int256 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
}
function logUint(uint256 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function logString(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function logBool(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function logAddress(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function logBytes(bytes memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
}
function logBytes1(bytes1 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
}
function logBytes2(bytes2 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
}
function logBytes3(bytes3 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
}
function logBytes4(bytes4 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
}
function logBytes5(bytes5 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
}
function logBytes6(bytes6 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
}
function logBytes7(bytes7 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
}
function logBytes8(bytes8 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
}
function logBytes9(bytes9 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
}
function logBytes10(bytes10 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
}
function logBytes11(bytes11 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
}
function logBytes12(bytes12 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
}
function logBytes13(bytes13 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
}
function logBytes14(bytes14 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
}
function logBytes15(bytes15 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
}
function logBytes16(bytes16 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
}
function logBytes17(bytes17 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
}
function logBytes18(bytes18 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
}
function logBytes19(bytes19 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
}
function logBytes20(bytes20 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
}
function logBytes21(bytes21 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
}
function logBytes22(bytes22 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
}
function logBytes23(bytes23 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
}
function logBytes24(bytes24 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
}
function logBytes25(bytes25 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
}
function logBytes26(bytes26 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
}
function logBytes27(bytes27 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
}
function logBytes28(bytes28 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
}
function logBytes29(bytes29 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
}
function logBytes30(bytes30 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
}
function logBytes31(bytes31 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
}
function logBytes32(bytes32 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
}
function log(uint256 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function log(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function log(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function log(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function log(uint256 p0, uint256 p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
}
function log(uint256 p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
}
function log(uint256 p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
}
function log(uint256 p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
}
function log(string memory p0, uint256 p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
}
function log(string memory p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
}
function log(string memory p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
}
function log(string memory p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
}
function log(bool p0, uint256 p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
}
function log(bool p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
}
function log(bool p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
}
function log(bool p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
}
function log(address p0, uint256 p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
}
function log(address p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
}
function log(address p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
}
function log(address p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
}
function log(uint256 p0, uint256 p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
}
function log(uint256 p0, bool p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
}
function log(uint256 p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
}
function log(uint256 p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
}
function log(uint256 p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
}
function log(uint256 p0, address p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
}
function log(uint256 p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
}
function log(uint256 p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
}
function log(uint256 p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
}
function log(string memory p0, string memory p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
}
function log(string memory p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
}
function log(string memory p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
}
function log(string memory p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
}
function log(string memory p0, bool p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
}
function log(string memory p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
}
function log(string memory p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
}
function log(string memory p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
}
function log(string memory p0, address p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
}
function log(string memory p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
}
function log(string memory p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
}
function log(string memory p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
}
function log(bool p0, uint256 p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
}
function log(bool p0, uint256 p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
}
function log(bool p0, uint256 p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
}
function log(bool p0, uint256 p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
}
function log(bool p0, string memory p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
}
function log(bool p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
}
function log(bool p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
}
function log(bool p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
}
function log(bool p0, bool p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
}
function log(bool p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
}
function log(bool p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
}
function log(bool p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
}
function log(bool p0, address p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
}
function log(bool p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
}
function log(bool p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
}
function log(bool p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
}
function log(address p0, uint256 p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
}
function log(address p0, uint256 p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
}
function log(address p0, uint256 p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
}
function log(address p0, uint256 p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
}
function log(address p0, string memory p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
}
function log(address p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
}
function log(address p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
}
function log(address p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
}
function log(address p0, bool p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
}
function log(address p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
}
function log(address p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
}
function log(address p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
}
function log(address p0, address p1, uint256 p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
}
function log(address p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
}
function log(address p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
}
function log(address p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, uint256 p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
}
}
文件 96 的 96:newDelivery.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import './interfaces/IDelivery.sol';
import './interfaces/ICollateralPositionManager.sol';
import './interfaces/IBubblyPool.sol';
import './interfaces/IBubblyFactory.sol';
import './libraries/LowGasSafeMath.sol';
import './libraries/TransferHelper.sol';
import './libraries/FullMath.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import './interfaces/IERC20Minimal.sol';
interface INonfungiblePositionManager{
struct DecreaseLiquidityParams {
uint256 tokenId;
uint128 liquidity;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
function decreaseLiquidity(DecreaseLiquidityParams calldata params)
external
returns (uint256 amount0, uint256 amount1);
function batchCollect(uint256[] calldata ids, uint128[] calldata amounts) external returns (uint256 totalfee);
function ownerOf(uint256 tokenId) external view returns (address owner);
}
contract newDelivery {
struct BuyerDeliveryInfo{
uint256 amount0Bought;
uint256 amount0Distributed;
uint256 amount1Collateral;
uint256 amount0Delivered;
}
struct SellerDeliveryInfo{
uint256 amount0Sold;
uint256 amount1Collateral;
uint256 amount0Delivered;
}
mapping(address => address) public vtokenToToken;
mapping(address => uint256) public poolTotalToken;
mapping(address => uint256) public poolTotalQuoteToken;
mapping(address => uint256) public poolReserve;
mapping(address => uint32) public DeliverBeginTime;
mapping(address => uint32) public DeliverEpoch;
mapping(address => address[]) public sellersList;
mapping(address => address[]) public buyersSortedList;
mapping(address => uint256) public undividedCollateral;
mapping(address => uint256[]) public auxiliaryList;
mapping(address => uint256) public listPoint;
mapping(address => mapping(address => BuyerDeliveryInfo)) public buyersInfo;
mapping(address => mapping(address => SellerDeliveryInfo)) public sellersInfo;
address immutable CPM;
address immutable factory;
mapping (address => address) public EmergencyAdmin;
mapping (address => bool) public EmergencyPause;
using LowGasSafeMath for uint256;
event SetEmergencyAdmin(address indexed pool, address admin);
event SetEmergencyPause(address indexed pool, bool flag);
event DeliverBeforeDeadline(address indexed recipient, uint256 amount0, uint256 amount1, bool forX,address pool, uint256 amountToDeliver);
event DeliverAfterDeadline(address indexed recipient, uint256 amountX, uint256 amountY, address pool,uint256 amountToDeliver);
event SetDeliveryToken(address indexed pool, address vtoken ,address token);
event SetDeliveryTime(address indexed pool, uint32 timeStamp);
event SetDeliveryEpoch(address indexed pool, uint32 epoch);
event SetUndividedCollateral(address indexed pool, uint256 collateral);
event Withdraw(address indexed recipient, uint256 amount0, uint256 amount1, bool forX,address pool);
constructor(address _factory, address _CPM) {
CPM = _CPM;
factory = _factory;
}
modifier onlyFactoryOwnerOrAdmin(address pool) {
require(msg.sender == IBubblyFactory(factory).owner() || msg.sender == EmergencyAdmin[pool] );
_;
}
modifier onlyFactoryOwner() {
require(msg.sender == IBubblyFactory(factory).owner());
_;
}
function _bSerach (address pool, uint256 target) public returns (uint256){
uint256 low = 0;
uint256 high = auxiliaryList[pool].length - 1;
while(low <= high)
{
uint256 mid = (low + high) / 2 ;
if(auxiliaryList[pool][mid] <= target){
low = mid + 1;
}
else{
if(high == 0){
break;
}
high = mid -1;
}
}
return low;
}
function setDeliverEpoch(address pool, uint32 epoch) onlyFactoryOwner public{
DeliverEpoch[pool] = epoch;
emit SetDeliveryEpoch(pool, epoch);
}
function setUndividedCollateral(address pool, uint256 collateralamount) onlyFactoryOwner public{
require(DeliverBeginTime[pool] != uint32(0),'Time not set');
require(DeliverEpoch[pool] != uint32(0));
require(_blockTimestamp() > DeliverBeginTime[pool] + DeliverEpoch[pool], 'set before 24hs');
undividedCollateral[pool] = collateralamount;
emit SetUndividedCollateral(pool, collateralamount);
}
function setsellersList(address[] calldata sellers, SellerDeliveryInfo[] calldata info ,address pool) onlyFactoryOwner public{
require(sellers.length == info.length,'length error');
uint256 length = sellersList[pool].length;
if(length == 0){
sellersList[pool] = sellers;
for(uint256 i = 0; i < sellers.length; i++){
sellersInfo[pool][sellers[i]] = info[i];
}
}else{
for(uint256 i = 0; i < sellers.length; i++){
sellersList[pool].push(sellers[i]);
sellersInfo[pool][sellers[i]] = info[i];
}
}
}
function setBuyerSortedList(address[] calldata buyers, BuyerDeliveryInfo[] calldata info ,address pool) onlyFactoryOwner public{
require(buyers.length == info.length,'length error');
uint256 length = buyersSortedList[pool].length;
if(length == 0){
buyersSortedList[pool] = buyers;
auxiliaryList[pool] = new uint256[](buyers.length);
for(uint256 i = 0; i < buyers.length; i++){
buyersInfo[pool][buyers[i]] = info[i];
if (i == 0){
auxiliaryList[pool][i] = info[i].amount0Bought;
}else{
auxiliaryList[pool][i] = info[i].amount0Bought + auxiliaryList[pool][i-1];
}
}
}else{
for(uint256 i = 0; i < buyers.length; i++){
buyersSortedList[pool].push(buyers[i]);
buyersInfo[pool][buyers[i]] = info[i];
auxiliaryList[pool].push(info[i].amount0Bought + auxiliaryList[pool][length + i -1]);
}
}
}
function Deliver(address pool, bool forX, uint256 amountToDeliver) public returns (uint256 amount0,uint256 amount1 ,bool getToken){
require(amountToDeliver > uint256(0));
require(EmergencyPause[pool] == false);
require(DeliverBeginTime[pool] != uint32(0),'Time not set');
require(_blockTimestamp() >= DeliverBeginTime[pool], 'Delivery not start');
require(DeliverEpoch[pool] != uint32(0));
require(buyersSortedList[pool].length != uint256(0),'buyerlist not init');
require(sellersList[pool].length != uint256(0),'sellerlist not init');
require(_blockTimestamp() <= DeliverBeginTime[pool] + DeliverEpoch[pool], 'Delivery after 24hs');
require(IBubblyPool(pool).deliveryflag());
require(vtokenToToken[IBubblyPool(pool).token0()]!= address(0));
getToken = forX;
(amount0, amount1) = _getPosition(pool, forX);
if(!forX){
sellersInfo[pool][msg.sender].amount0Delivered = sellersInfo[pool][msg.sender].amount0Delivered + amountToDeliver;
require(sellersInfo[pool][msg.sender].amount0Delivered <= sellersInfo[pool][msg.sender].amount0Sold, 'not enough position' );
TransferHelper.safeTransferFrom(vtokenToToken[IBubblyPool(pool).token0()], msg.sender,address(this), amountToDeliver);
uint256 amount1ToPay = FullMath.mulDiv(amount1, amountToDeliver , amount0);
TransferHelper.safeTransferFrom(IBubblyPool(pool).token1(), pool, msg.sender, 2 * amount1ToPay);
poolTotalToken[pool] = poolTotalToken[pool].add(amountToDeliver);
poolReserve[pool] = poolReserve[pool].add(amountToDeliver);
uint256 oldPoint = listPoint[pool];
uint256 point = _bSerach(pool, poolTotalToken[pool]);
for(uint256 i = oldPoint ; i < point ; i++){
buyersInfo[pool][buyersSortedList[pool][i]].amount0Distributed = buyersInfo[pool][buyersSortedList[pool][i]].amount0Bought;
}
if(point != buyersSortedList[pool].length && point > 0){
buyersInfo[pool][buyersSortedList[pool][point]].amount0Distributed = poolTotalToken[pool] - auxiliaryList[pool][point-1];
}
else if (point == 0){
buyersInfo[pool][buyersSortedList[pool][point]].amount0Distributed += amountToDeliver;
}
listPoint[pool] = point;
}
else{
require(poolReserve[pool] >= amountToDeliver , 'not enough balance');
require(buyersInfo[pool][msg.sender].amount0Bought == buyersInfo[pool][msg.sender].amount0Distributed);
buyersInfo[pool][msg.sender].amount0Delivered = buyersInfo[pool][msg.sender].amount0Delivered + amountToDeliver;
require(buyersInfo[pool][msg.sender].amount0Delivered <= buyersInfo[pool][msg.sender].amount0Bought,"not enough position");
TransferHelper.safeTransfer(vtokenToToken[IBubblyPool(pool).token0()], msg.sender, amountToDeliver);
poolReserve[pool] = poolReserve[pool].sub(amountToDeliver);
}
emit DeliverBeforeDeadline(msg.sender, amount0, amount1, forX, pool,amountToDeliver);
}
function DeliverforX(address pool, uint256 amountToDeliver) public returns (uint256 amountX,uint256 amountY){
require(EmergencyPause[pool] == false);
require(DeliverBeginTime[pool] != uint32(0),'Time not set');
require(DeliverEpoch[pool] != uint32(0));
require(_blockTimestamp() > DeliverBeginTime[pool] + DeliverEpoch[pool], 'Delivery before 24hs');
require(IBubblyPool(pool).deliveryflag());
require(vtokenToToken[IBubblyPool(pool).token0()]!= address(0));
(uint256 amount0, uint256 amount1) = _getPosition(pool, true);
uint256 amount0Distributed = buyersInfo[pool][msg.sender].amount0Distributed;
uint256 amount0Bought = buyersInfo[pool][msg.sender].amount0Bought;
buyersInfo[pool][msg.sender].amount0Delivered = buyersInfo[pool][msg.sender].amount0Delivered + amountToDeliver;
require(buyersInfo[pool][msg.sender].amount0Delivered <= buyersInfo[pool][msg.sender].amount0Bought,"not enough position");
if(amount0Distributed >= amount0Bought ){
amountX = amountToDeliver;
TransferHelper.safeTransfer(vtokenToToken[IBubblyPool(pool).token0()], msg.sender, amountX);
poolReserve[pool] = poolReserve[pool].sub(amountToDeliver);
}
else if(amount0Distributed == uint256(0)){
amountY = 2 * FullMath.mulDiv(amount1, amountToDeliver , amount0);
TransferHelper.safeTransferFrom(IBubblyPool(pool).token1(), pool, msg.sender, amountY > balance1(pool) ? balance1(pool) : amountY);
}
else{
amountX = FullMath.mulDiv(amountToDeliver , amount0Distributed , amount0);
TransferHelper.safeTransfer(vtokenToToken[IBubblyPool(pool).token0()], msg.sender, amountX);
poolReserve[pool] = poolReserve[pool].sub(amountX);
uint256 amount1ToPay = FullMath.mulDiv(amount1 , amountToDeliver , amount0);
amountY = 2 * (amount1ToPay - FullMath.mulDiv(amount1ToPay , amountX , amountToDeliver));
if(amountY != 0) TransferHelper.safeTransferFrom(IBubblyPool(pool).token1(), pool, msg.sender, amountY > balance1(pool) ? balance1(pool) : amountY);
}
emit DeliverAfterDeadline(msg.sender, amountX, amountY, pool, amountToDeliver);
}
function _blockTimestamp() internal view virtual returns (uint32) {
return uint32(block.timestamp);
}
function setToken(
address pool,
address token,
address vtoken
) external onlyFactoryOwner {
vtokenToToken[vtoken] = token;
emit SetDeliveryToken(pool, vtoken ,token);
}
function setDeliveryTime(
address pool,
uint32 time
) external onlyFactoryOwner {
DeliverBeginTime[pool] = time;
emit SetDeliveryTime(pool, time);
}
function _getPosition(address pool, bool forX) internal view returns (uint256 amount0 ,uint256 amount1){
if(!forX){
amount0 = sellersInfo[pool][msg.sender].amount0Sold;
amount1 = sellersInfo[pool][msg.sender].amount1Collateral;
}else{
amount0 = buyersInfo[pool][msg.sender].amount0Bought;
amount1 = buyersInfo[pool][msg.sender].amount1Collateral;
}
}
function balance1(address pool) private view returns (uint256) {
(bool success, bytes memory data) =
IBubblyPool(pool).token1().staticcall(abi.encodeWithSelector(IERC20Minimal.balanceOf.selector, pool));
require(success && data.length >= 32);
return abi.decode(data, (uint256));
}
function emergencyTokenTransfer(address token, address to, uint256 amount) external onlyFactoryOwner {
TransferHelper.safeTransfer(token, to, amount);
}
function setEmergencyAdmin (address _pool ,address _admin) external onlyFactoryOwnerOrAdmin(_pool) {
EmergencyAdmin[_pool] = _admin;
emit SetEmergencyAdmin(_pool, _admin);
}
function setEmergencyPause (address _pool ,bool _flag ) external onlyFactoryOwnerOrAdmin(_pool) {
EmergencyPause[_pool] = _flag;
emit SetEmergencyPause(_pool, _flag);
}
function undividedCollateralTransfer(address token, address from, address to, address pool) external onlyFactoryOwner {
require(DeliverBeginTime[pool] != uint32(0),'Time not set');
require(DeliverEpoch[pool] != uint32(0));
require(_blockTimestamp() > DeliverBeginTime[pool] + DeliverEpoch[pool], 'transfer before 24hs');
TransferHelper.safeTransferFrom(token, from, to, undividedCollateral[pool]);
}
function withdraw(address pool, bool forX, uint256 amountToWithdraw) public returns (uint256 amount0,uint256 amount1 ,bool getToken){
require(amountToWithdraw > uint256(0));
require(EmergencyPause[pool] == false);
require(DeliverBeginTime[pool] != uint32(0),'Time not set');
require(_blockTimestamp() >= DeliverBeginTime[pool], 'Delivery not start');
require(DeliverEpoch[pool] != uint32(0));
require(buyersSortedList[pool].length != uint256(0),'buyerlist not init');
require(sellersList[pool].length != uint256(0),'sellerlist not init');
require(IBubblyPool(pool).deliveryflag());
require(vtokenToToken[IBubblyPool(pool).token0()] == address(0),"has delivertoken");
getToken = forX;
(amount0, amount1) = _getPosition(pool, forX);
if(!forX){
sellersInfo[pool][msg.sender].amount0Delivered = sellersInfo[pool][msg.sender].amount0Delivered + amountToWithdraw;
require(sellersInfo[pool][msg.sender].amount0Delivered <= sellersInfo[pool][msg.sender].amount0Sold, 'not enough position');
}
else{
buyersInfo[pool][msg.sender].amount0Delivered = buyersInfo[pool][msg.sender].amount0Delivered + amountToWithdraw;
require(buyersInfo[pool][msg.sender].amount0Delivered <= buyersInfo[pool][msg.sender].amount0Bought,"not enough position");
}
TransferHelper.safeTransferFrom(IBubblyPool(pool).token1(), pool, msg.sender, amountToWithdraw);
emit Withdraw(msg.sender, amount0, amount1, forX, pool);
}
function deliverThenDecrease(address pool, bool forX, uint256 amountToDeliver ,address NPMaddr ,uint256[] calldata ids, uint128[] calldata amounts,INonfungiblePositionManager.DecreaseLiquidityParams calldata params) public returns (uint256 amount0,uint256 amount1 ,bool getToken){
(amount0,amount1,getToken) = Deliver(pool, forX, amountToDeliver);
INonfungiblePositionManager(NPMaddr).decreaseLiquidity(params);
address token1 = IBubblyPool(pool).token1();
uint256 balanceBeforeCollect = IERC20Minimal(token1).balanceOf(address(this));
INonfungiblePositionManager(NPMaddr).batchCollect(ids,amounts);
uint256 balanceAfterCollect = IERC20Minimal(token1).balanceOf(address(this));
address owner = INonfungiblePositionManager(NPMaddr).ownerOf(params.tokenId);
TransferHelper.safeTransfer(token1, owner, balanceAfterCollect - balanceBeforeCollect );
}
function deliverForXThenDecrease(address pool, uint256 amountToDeliver ,address NPMaddr ,uint256[] calldata ids, uint128[] calldata amounts,INonfungiblePositionManager.DecreaseLiquidityParams calldata params) public returns (uint256 amountX,uint256 amountY ){
(amountX,amountY) = DeliverforX(pool,amountToDeliver);
INonfungiblePositionManager(NPMaddr).decreaseLiquidity(params);
address token1 = IBubblyPool(pool).token1();
uint256 balanceBeforeCollect = IERC20Minimal(token1).balanceOf(address(this));
INonfungiblePositionManager(NPMaddr).batchCollect(ids,amounts);
uint256 balanceAfterCollect = IERC20Minimal(token1).balanceOf(address(this));
address owner = INonfungiblePositionManager(NPMaddr).ownerOf(params.tokenId);
TransferHelper.safeTransfer(token1, owner, balanceAfterCollect - balanceBeforeCollect );
}
function withdrawThenDecrease(address pool, bool forX, uint256 amountToDeliver ,address NPMaddr ,uint256[] calldata ids, uint128[] calldata amounts,INonfungiblePositionManager.DecreaseLiquidityParams calldata params) public returns (uint256 amount0,uint256 amount1 ,bool getToken){
(amount0,amount1,getToken) = withdraw(pool, forX, amountToDeliver);
INonfungiblePositionManager(NPMaddr).decreaseLiquidity(params);
address token1 = IBubblyPool(pool).token1();
uint256 balanceBeforeCollect = IERC20Minimal(token1).balanceOf(address(this));
INonfungiblePositionManager(NPMaddr).batchCollect(ids,amounts);
uint256 balanceAfterCollect = IERC20Minimal(token1).balanceOf(address(this));
address owner = INonfungiblePositionManager(NPMaddr).ownerOf(params.tokenId);
TransferHelper.safeTransfer(token1, owner, balanceAfterCollect - balanceBeforeCollect );
}
}
{
"compilationTarget": {
"contracts/newDelivery.sol": "newDelivery"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 100
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_CPM","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountX","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountY","type":"uint256"},{"indexed":false,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountToDeliver","type":"uint256"}],"name":"DeliverAfterDeadline","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"},{"indexed":false,"internalType":"bool","name":"forX","type":"bool"},{"indexed":false,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountToDeliver","type":"uint256"}],"name":"DeliverBeforeDeadline","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"SetDeliveryEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint32","name":"timeStamp","type":"uint32"}],"name":"SetDeliveryTime","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"vtoken","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"SetDeliveryToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"SetEmergencyAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"bool","name":"flag","type":"bool"}],"name":"SetEmergencyPause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateral","type":"uint256"}],"name":"SetUndividedCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"},{"indexed":false,"internalType":"bool","name":"forX","type":"bool"},{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bool","name":"forX","type":"bool"},{"internalType":"uint256","name":"amountToDeliver","type":"uint256"}],"name":"Deliver","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bool","name":"getToken","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"DeliverBeginTime","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"DeliverEpoch","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"amountToDeliver","type":"uint256"}],"name":"DeliverforX","outputs":[{"internalType":"uint256","name":"amountX","type":"uint256"},{"internalType":"uint256","name":"amountY","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"EmergencyAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"EmergencyPause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"target","type":"uint256"}],"name":"_bSerach","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"auxiliaryList","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"buyersInfo","outputs":[{"internalType":"uint256","name":"amount0Bought","type":"uint256"},{"internalType":"uint256","name":"amount0Distributed","type":"uint256"},{"internalType":"uint256","name":"amount1Collateral","type":"uint256"},{"internalType":"uint256","name":"amount0Delivered","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"buyersSortedList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"amountToDeliver","type":"uint256"},{"internalType":"address","name":"NPMaddr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint128[]","name":"amounts","type":"uint128[]"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct INonfungiblePositionManager.DecreaseLiquidityParams","name":"params","type":"tuple"}],"name":"deliverForXThenDecrease","outputs":[{"internalType":"uint256","name":"amountX","type":"uint256"},{"internalType":"uint256","name":"amountY","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bool","name":"forX","type":"bool"},{"internalType":"uint256","name":"amountToDeliver","type":"uint256"},{"internalType":"address","name":"NPMaddr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint128[]","name":"amounts","type":"uint128[]"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct INonfungiblePositionManager.DecreaseLiquidityParams","name":"params","type":"tuple"}],"name":"deliverThenDecrease","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bool","name":"getToken","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"listPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolTotalQuoteToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolTotalToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"sellersInfo","outputs":[{"internalType":"uint256","name":"amount0Sold","type":"uint256"},{"internalType":"uint256","name":"amount1Collateral","type":"uint256"},{"internalType":"uint256","name":"amount0Delivered","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"sellersList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"buyers","type":"address[]"},{"components":[{"internalType":"uint256","name":"amount0Bought","type":"uint256"},{"internalType":"uint256","name":"amount0Distributed","type":"uint256"},{"internalType":"uint256","name":"amount1Collateral","type":"uint256"},{"internalType":"uint256","name":"amount0Delivered","type":"uint256"}],"internalType":"struct newDelivery.BuyerDeliveryInfo[]","name":"info","type":"tuple[]"},{"internalType":"address","name":"pool","type":"address"}],"name":"setBuyerSortedList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"setDeliverEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint32","name":"time","type":"uint32"}],"name":"setDeliveryTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"address","name":"_admin","type":"address"}],"name":"setEmergencyAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setEmergencyPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"vtoken","type":"address"}],"name":"setToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"collateralamount","type":"uint256"}],"name":"setUndividedCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"sellers","type":"address[]"},{"components":[{"internalType":"uint256","name":"amount0Sold","type":"uint256"},{"internalType":"uint256","name":"amount1Collateral","type":"uint256"},{"internalType":"uint256","name":"amount0Delivered","type":"uint256"}],"internalType":"struct newDelivery.SellerDeliveryInfo[]","name":"info","type":"tuple[]"},{"internalType":"address","name":"pool","type":"address"}],"name":"setsellersList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"undividedCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"pool","type":"address"}],"name":"undividedCollateralTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"vtokenToToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bool","name":"forX","type":"bool"},{"internalType":"uint256","name":"amountToWithdraw","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bool","name":"getToken","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bool","name":"forX","type":"bool"},{"internalType":"uint256","name":"amountToDeliver","type":"uint256"},{"internalType":"address","name":"NPMaddr","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint128[]","name":"amounts","type":"uint128[]"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct INonfungiblePositionManager.DecreaseLiquidityParams","name":"params","type":"tuple"}],"name":"withdrawThenDecrease","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bool","name":"getToken","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]