Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add maxAndMinWBNB #62

Merged
merged 4 commits into from
Sep 6, 2024
Merged

add maxAndMinWBNB #62

merged 4 commits into from
Sep 6, 2024

Conversation

YouStillAlive
Copy link
Member

closes #61

Copy link

github-actions bot commented Sep 5, 2024

Methods

Symbol Meaning
Execution gas for this method does not include intrinsic gas overhead
Cost was non-zero but below the precision setting for the currency display (see options)
Min Max Avg Calls usd avg
BNBPartyFactory
       createParty(string,string) 5,728,876 5,904,124 5,763,684 36 14.41
       joinParty(address,uint256) 143,982 5,707,644 2,076,919 26 5.19
       leaveParty(address,uint256,uint256) 177,077 201,896 182,433 5 0.46
       pause() - - 46,851 5 0.12
       setBNBPartySwapRouter(address) 24,135 46,275 45,045 18 0.11
       setNonfungiblePositionManager(address,address) 27,416 68,950 66,640 18 0.17
       setSwapRouter(address) - - 46,298 16 0.12
       unpause() - - 24,885 5 0.06
       withdrawFee() - - 31,766 2 0.08
       withdrawLPFee(address[]) - - 173,634 1 0.43
       withdrawPartyLPFee(address[]) - - 173,814 2 0.43
NonfungiblePositionManager
       approve(address,uint256) 46,052 46,395 46,303 4 0.12
SwapRouter
       exactInput((bytes,address,uint256,uint256,uint256)) 134,897 144,523 141,314 3 0.35
       multicall(bytes[]) - - 162,583 2 0.41

Deployments

Min Max Avg Block % usd avg
BNBPartyFactory 3,709,974 3,709,986 3,709,985 2.9 % 9.27
MockContract - - 107,817 0.1 % 0.27
MockNonfungibleTokenPositionDescriptor - - 111,537 0.1 % 0.28
NonfungiblePositionManager 5,171,500 5,171,524 5,171,518 4 % 12.93
SqrtPriceCalculator - - 278,712 0.2 % 0.70
SwapRouter 2,201,066 2,201,090 2,201,085 1.7 % 5.50
UniswapV3Factory 5,437,097 5,437,109 5,437,108 4.2 % 13.59

Solidity and Network Config

Settings Value
Solidity: version 0.8.24
Solidity: optimized true
Solidity: runs 200
Solidity: viaIR false
Block Limit 130,000,000
L1 Gas Price 5 gwei
Token Price 499.87 usd/bnb
Network BINANCE
Toolchain hardhat

@codecov-commenter
Copy link

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

All modified and coverable lines are covered by tests ✅

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Copy link

github-actions bot commented Sep 5, 2024

Slither report

THIS CHECKLIST IS NOT COMPLETE. Use --show-ignored-findings to show all the results.
Summary

reentrancy-no-eth

Impact: Medium
Confidence: Medium

function _handleLiquidity(address recipient) internal {
IUniswapV3Pool pool = IUniswapV3Pool(msg.sender);
(uint160 sqrtPriceX96, , , , , , ) = pool.slot0();
address token0 = pool.token0();
address token1 = pool.token1();
uint128 liquidity = pool.liquidity();
uint256 unwrapAmount = party.bonusTargetReach + party.bonusPartyCreator + party.targetReachFee;
uint160 newSqrtPriceX96;
// Decrease liquidity and collect tokens
(uint256 amount0, uint256 amount1) = _decreaseAndCollect(lpToTokenId[msg.sender], liquidity);
if (token0 == address(WBNB)) {
amount0 -= unwrapAmount; // Deduct unwrap amount from token0 if it is WBNB
isTokenOnPartyLP[token1] = false;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount0RoundingUp(
sqrtPriceX96,
liquidity,
unwrapAmount,
false
);
} else {
amount1 -= unwrapAmount; // Deduct unwrap amount from token1 if it is WBNB
isTokenOnPartyLP[token0] = false;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount1RoundingDown(
sqrtPriceX96,
liquidity,
unwrapAmount / 2,
false
);
}
// Approve tokens for the new liquidity pool creation
IERC20(token0).safeIncreaseAllowance(address(positionManager), amount0);
IERC20(token1).safeIncreaseAllowance(address(positionManager), amount1);
// Create new Liquidity Pool
_createLP(positionManager, token0, token1, amount0, amount1, newSqrtPriceX96, party.lpFee, party.lpTicks);
// Send bonuses
_unwrapAndSendBNB(recipient, unwrapAmount);
// burn meme tokens
_burnMemeToken(token0 == address(WBNB) ? token1 : token0);
}

unused-return

Impact: Medium
Confidence: Medium

function _handleLiquidity(address recipient) internal {
IUniswapV3Pool pool = IUniswapV3Pool(msg.sender);
(uint160 sqrtPriceX96, , , , , , ) = pool.slot0();
address token0 = pool.token0();
address token1 = pool.token1();
uint128 liquidity = pool.liquidity();
uint256 unwrapAmount = party.bonusTargetReach + party.bonusPartyCreator + party.targetReachFee;
uint160 newSqrtPriceX96;
// Decrease liquidity and collect tokens
(uint256 amount0, uint256 amount1) = _decreaseAndCollect(lpToTokenId[msg.sender], liquidity);
if (token0 == address(WBNB)) {
amount0 -= unwrapAmount; // Deduct unwrap amount from token0 if it is WBNB
isTokenOnPartyLP[token1] = false;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount0RoundingUp(
sqrtPriceX96,
liquidity,
unwrapAmount,
false
);
} else {
amount1 -= unwrapAmount; // Deduct unwrap amount from token1 if it is WBNB
isTokenOnPartyLP[token0] = false;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount1RoundingDown(
sqrtPriceX96,
liquidity,
unwrapAmount / 2,
false
);
}
// Approve tokens for the new liquidity pool creation
IERC20(token0).safeIncreaseAllowance(address(positionManager), amount0);
IERC20(token1).safeIncreaseAllowance(address(positionManager), amount1);
// Create new Liquidity Pool
_createLP(positionManager, token0, token1, amount0, amount1, newSqrtPriceX96, party.lpFee, party.lpTicks);
// Send bonuses
_unwrapAndSendBNB(recipient, unwrapAmount);
// burn meme tokens
_burnMemeToken(token0 == address(WBNB) ? token1 : token0);
}

function _createLP(
INonfungiblePositionManager liquidityManager,
address token0,
address token1,
uint256 amount0,
uint256 amount1,
uint160 sqrtPriceX96,
uint24 fee,
Ticks memory ticks
) internal returns (address liquidityPool) {
// Create LP
liquidityPool = liquidityManager.createAndInitializePoolIfNecessary(
token0,
token1,
fee,
sqrtPriceX96
);
// Mint LP
(lpToTokenId[liquidityPool], , , ) = liquidityManager.mint(
INonfungiblePositionManager.MintParams({
token0: token0,
token1: token1,
fee: fee,
tickLower: ticks.tickLower,
tickUpper: ticks.tickUpper,
amount0Desired: amount0,
amount1Desired: amount1,
amount0Min: 0,
amount1Min: 0,
recipient: address(this),
deadline: block.timestamp
})
);
}

function _getFeeGrowthInsideLastX128(
IUniswapV3Pool pool,
bytes32 key
)
internal
view
returns (
uint256 feeGrowthInside0LastX128,
uint256 feeGrowthInside1LastX128
)
{
(, feeGrowthInside0LastX128, feeGrowthInside1LastX128, , ) = pool.positions(key);
}

function _decreaseAndCollect(
uint256 tokenId,
uint128 liquidity
) internal returns (uint256 amount0, uint256 amount1) {
// Decrease liquidity from the position and receive the amount of token0 and token1
(amount0, amount1) = BNBPositionManager.decreaseLiquidity(
INonfungiblePositionManager.DecreaseLiquidityParams({
tokenId: tokenId,
liquidity: liquidity,
amount0Min: 0, // Minimum amount of token0 to collect, set to 0 for flexibility
amount1Min: 0, // Minimum amount of token1 to collect, set to 0 for flexibility
deadline: block.timestamp // Deadline for the transaction to be completed
})
);
// Collect the tokens from the position after liquidity decrease
BNBPositionManager.collect(
INonfungiblePositionManager.CollectParams({
tokenId: tokenId,
recipient: address(this), // Collect tokens to this contract address
amount0Max: uint128(amount0), // Maximum amount of token0 to collect
amount1Max: uint128(amount1) // Maximum amount of token1 to collect
})
);
}

function _collectFee(
address liquidityPool,
INonfungiblePositionManager manager
) internal notZeroAddress(liquidityPool) {
manager.collect(
INonfungiblePositionManager.CollectParams({
tokenId: lpToTokenId[liquidityPool],
recipient: msg.sender,
amount0Max: type(uint128).max,
amount1Max: type(uint128).max
})
); // Collects fees from the specified liquidity pool
}

function _executeSwap(
ISwapRouter router,
ISwapRouter.ExactInputParams memory params
) internal notZeroAddress(address(router)) {
uint256 value = msg.value > 0 ? params.amountIn : 0; // Set value if msg.value is greater than zero
ISwapRouter(router).exactInput{value: value}(params); // Executes the swap
}

reentrancy-benign

Impact: Low
Confidence: Medium

function _createLP(
INonfungiblePositionManager liquidityManager,
address token0,
address token1,
uint256 amount0,
uint256 amount1,
uint160 sqrtPriceX96,
uint24 fee,
Ticks memory ticks
) internal returns (address liquidityPool) {
// Create LP
liquidityPool = liquidityManager.createAndInitializePoolIfNecessary(
token0,
token1,
fee,
sqrtPriceX96
);
// Mint LP
(lpToTokenId[liquidityPool], , , ) = liquidityManager.mint(
INonfungiblePositionManager.MintParams({
token0: token0,
token1: token1,
fee: fee,
tickLower: ticks.tickLower,
tickUpper: ticks.tickUpper,
amount0Desired: amount0,
amount1Desired: amount1,
amount0Min: 0,
amount1Min: 0,
recipient: address(this),
deadline: block.timestamp
})
);
}

function _createFLP(address _token) internal returns (address liquidityPool) {
(address token0, address token1, uint160 sqrtPrice) = _getTokenPairAndPrice(_token);
// Determine the token amounts
(uint256 amount0, uint256 amount1) = _calculateAmounts(token0);
IERC20(_token).safeIncreaseAllowance(address(BNBPositionManager), party.initialTokenAmount);
liquidityPool = _createLP(
BNBPositionManager,
token0,
token1,
amount0,
amount1,
sqrtPrice,
party.partyLpFee,
party.partyTicks
);
isParty[liquidityPool] = true; // Mark the liquidity pool as a party pool
isTokenOnPartyLP[_token] = true; // Mark the token as part of the party LP
}

function _handleLiquidity(address recipient) internal {
IUniswapV3Pool pool = IUniswapV3Pool(msg.sender);
(uint160 sqrtPriceX96, , , , , , ) = pool.slot0();
address token0 = pool.token0();
address token1 = pool.token1();
uint128 liquidity = pool.liquidity();
uint256 unwrapAmount = party.bonusTargetReach + party.bonusPartyCreator + party.targetReachFee;
uint160 newSqrtPriceX96;
// Decrease liquidity and collect tokens
(uint256 amount0, uint256 amount1) = _decreaseAndCollect(lpToTokenId[msg.sender], liquidity);
if (token0 == address(WBNB)) {
amount0 -= unwrapAmount; // Deduct unwrap amount from token0 if it is WBNB
isTokenOnPartyLP[token1] = false;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount0RoundingUp(
sqrtPriceX96,
liquidity,
unwrapAmount,
false
);
} else {
amount1 -= unwrapAmount; // Deduct unwrap amount from token1 if it is WBNB
isTokenOnPartyLP[token0] = false;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount1RoundingDown(
sqrtPriceX96,
liquidity,
unwrapAmount / 2,
false
);
}
// Approve tokens for the new liquidity pool creation
IERC20(token0).safeIncreaseAllowance(address(positionManager), amount0);
IERC20(token1).safeIncreaseAllowance(address(positionManager), amount1);
// Create new Liquidity Pool
_createLP(positionManager, token0, token1, amount0, amount1, newSqrtPriceX96, party.lpFee, party.lpTicks);
// Send bonuses
_unwrapAndSendBNB(recipient, unwrapAmount);
// burn meme tokens
_burnMemeToken(token0 == address(WBNB) ? token1 : token0);
}

reentrancy-events

Impact: Low
Confidence: Medium

function _unwrapAndSendBNB(address recipient, uint256 unwrapAmount) internal {
address creator = lpToCreator[msg.sender];
WBNB.withdraw(unwrapAmount); // Unwrap WBNB to BNB
if (recipient == creator) {
_transferBNB(recipient, party.bonusTargetReach + party.bonusPartyCreator); // Send total bonus to creator
} else {
_transferBNB(recipient, party.bonusTargetReach); // Send bonus to recipient
_transferBNB(creator, party.bonusPartyCreator); // Send bonus to creator
}
}

function _unwrapAndSendBNB(address recipient, uint256 unwrapAmount) internal {
address creator = lpToCreator[msg.sender];
WBNB.withdraw(unwrapAmount); // Unwrap WBNB to BNB
if (recipient == creator) {
_transferBNB(recipient, party.bonusTargetReach + party.bonusPartyCreator); // Send total bonus to creator
} else {
_transferBNB(recipient, party.bonusTargetReach); // Send bonus to recipient
_transferBNB(creator, party.bonusPartyCreator); // Send bonus to creator
}
}

function _unwrapAndSendBNB(address recipient, uint256 unwrapAmount) internal {
address creator = lpToCreator[msg.sender];
WBNB.withdraw(unwrapAmount); // Unwrap WBNB to BNB
if (recipient == creator) {
_transferBNB(recipient, party.bonusTargetReach + party.bonusPartyCreator); // Send total bonus to creator
} else {
_transferBNB(recipient, party.bonusTargetReach); // Send bonus to recipient
_transferBNB(creator, party.bonusPartyCreator); // Send bonus to creator
}
}

function _handleLiquidity(address recipient) internal {
IUniswapV3Pool pool = IUniswapV3Pool(msg.sender);
(uint160 sqrtPriceX96, , , , , , ) = pool.slot0();
address token0 = pool.token0();
address token1 = pool.token1();
uint128 liquidity = pool.liquidity();
uint256 unwrapAmount = party.bonusTargetReach + party.bonusPartyCreator + party.targetReachFee;
uint160 newSqrtPriceX96;
// Decrease liquidity and collect tokens
(uint256 amount0, uint256 amount1) = _decreaseAndCollect(lpToTokenId[msg.sender], liquidity);
if (token0 == address(WBNB)) {
amount0 -= unwrapAmount; // Deduct unwrap amount from token0 if it is WBNB
isTokenOnPartyLP[token1] = false;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount0RoundingUp(
sqrtPriceX96,
liquidity,
unwrapAmount,
false
);
} else {
amount1 -= unwrapAmount; // Deduct unwrap amount from token1 if it is WBNB
isTokenOnPartyLP[token0] = false;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount1RoundingDown(
sqrtPriceX96,
liquidity,
unwrapAmount / 2,
false
);
}
// Approve tokens for the new liquidity pool creation
IERC20(token0).safeIncreaseAllowance(address(positionManager), amount0);
IERC20(token1).safeIncreaseAllowance(address(positionManager), amount1);
// Create new Liquidity Pool
_createLP(positionManager, token0, token1, amount0, amount1, newSqrtPriceX96, party.lpFee, party.lpTicks);
// Send bonuses
_unwrapAndSendBNB(recipient, unwrapAmount);
// burn meme tokens
_burnMemeToken(token0 == address(WBNB) ? token1 : token0);
}

naming-convention

Impact: Informational
Confidence: High

IWBNB public immutable WBNB; // Wrapped BNB token contract

INonfungiblePositionManager public BNBPositionManager; // BNB Party position manager

ISwapRouter _swapRouter

INonfungiblePositionManager _BNBPositionManager,

function WETH9() external view returns (address);

INonfungiblePositionManager _positionManager

ISwapRouter _swapRouter

ISwapRouter public BNBSwapRouter; // V3 swap router

reentrancy-unlimited-gas

Impact: Informational
Confidence: Medium

function _unwrapAndSendBNB(address recipient, uint256 unwrapAmount) internal {
address creator = lpToCreator[msg.sender];
WBNB.withdraw(unwrapAmount); // Unwrap WBNB to BNB
if (recipient == creator) {
_transferBNB(recipient, party.bonusTargetReach + party.bonusPartyCreator); // Send total bonus to creator
} else {
_transferBNB(recipient, party.bonusTargetReach); // Send bonus to recipient
_transferBNB(creator, party.bonusPartyCreator); // Send bonus to creator
}
}

@YouStillAlive YouStillAlive marked this pull request as ready for review September 6, 2024 07:46
@YouStillAlive YouStillAlive merged commit a14d9f8 into master Sep 6, 2024
4 checks passed
@YouStillAlive YouStillAlive deleted the issue_61 branch September 6, 2024 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

sqrt test for different token positions in the second liquidity pool
3 participants