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 party token LP validation 1639710081 #82

Merged
merged 8 commits into from
Sep 25, 2024
Merged

add party token LP validation 1639710081 #82

merged 8 commits into from
Sep 25, 2024

Conversation

YouStillAlive
Copy link
Member

closes #77

Copy link

github-actions bot commented Sep 24, 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,709,285 5,883,329 5,743,268 37 17.12
       joinParty(address,uint256) 145,214 5,729,461 1,944,865 29 5.80
       leaveParty(address,uint256,uint256) 177,916 203,322 183,624 5 0.55
       pause() - - 49,174 5 0.15
       setBNBPartySwapRouter(address) 26,439 48,579 47,348 18 0.14
       setNonfungiblePositionManager(address,address) 29,248 71,239 68,904 18 0.21
       setSwapRouter(address) 48,556 48,580 48,578 16 0.14
       unpause() - - 27,186 5 0.08
       withdrawFee() - - 34,122 2 0.10
       withdrawLPFee(address[]) - - 176,452 1 0.53
       withdrawPartyLPFee(address[]) - - 176,588 2 0.53
ERC20Token
       approve(address,uint256) 46,383 46,395 46,392 4 0.14
NonfungiblePositionManager
       approve(address,uint256) 46,052 46,395 46,270 6 0.14
       createAndInitializePoolIfNecessary(address,address,uint24,uint160) 4,592,181 4,613,717 4,597,565 4 13.70
       mint((address,address,uint24,int24,int24,uint256,uint256,uint256,uint256,address,uint256)) 510,896 610,880 544,442 4 1.62
SwapRouter
       exactInput((bytes,address,uint256,uint256,uint256)) 135,944 145,502 142,316 3 0.42
       multicall(bytes[]) - - 163,958 2 0.49

Deployments

Min Max Avg Block % usd avg
BNBPartyFactory - - 5,290,679 4.1 % 15.77
ERC20Token - - 598,865 0.5 % 1.79
MockContract - - 107,813 0.1 % 0.32
MockNonfungibleTokenPositionDescriptor - - 111,329 0.1 % 0.33
NonfungiblePositionManager 5,171,512 5,171,524 5,171,523 4 % 15.42
SqrtPriceCalculator - - 278,712 0.2 % 0.83
SwapRouter 2,201,078 2,201,090 2,201,089 1.7 % 6.56
UniswapV3Factory 5,437,097 5,437,109 5,437,108 4.2 % 16.21

Solidity and Network Config

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

@YouStillAlive YouStillAlive changed the title add token LP party validation add party token LP validation Sep 24, 2024
Copy link

github-actions bot commented Sep 24, 2024

Slither report

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

unused-return

Impact: Medium
Confidence: Medium

function _handleLiquidity(address recipient) internal returns (address liquidityPool, uint256 tokenId){
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
isTokenTargetReached[token1] = true;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount0RoundingUp(
sqrtPriceX96,
liquidity,
unwrapAmount,
false
);
} else {
amount1 -= unwrapAmount; // Deduct unwrap amount from token1 if it is WBNB
isTokenTargetReached[token0] = true;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount1RoundingDown(
sqrtPriceX96,
liquidity,
unwrapAmount,
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
(liquidityPool, tokenId) = _createLP(positionManager, token0, token1, amount0, amount1, newSqrtPriceX96, party.lpFee, _getTicks(token0, party.lpTicks));
// Send bonuses
_unwrapAndSendBNB(recipient, unwrapAmount);
// burn meme tokens
_burnMemeToken(token0 == address(WBNB) ? token1 : token0);
}

function _collectFee(
address liquidityPool,
INonfungiblePositionManager manager
) internal firewallProtectedSig(0xbbd73307) 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 _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 _getFeeGrowthInsideLastX128(
IUniswapV3Pool pool,
bytes32 key
)
internal
view
returns (
uint256 feeGrowthInside0LastX128,
uint256 feeGrowthInside1LastX128
)
{
(, feeGrowthInside0LastX128, feeGrowthInside1LastX128, , ) = pool.positions(key);
}

function _createLP(
INonfungiblePositionManager liquidityManager,
address token0,
address token1,
uint256 amount0,
uint256 amount1,
uint160 sqrtPriceX96,
uint24 fee,
Ticks memory ticks
) internal returns (address liquidityPool, uint256 tokenId) {
// Create LP
liquidityPool = liquidityManager.createAndInitializePoolIfNecessary(
token0,
token1,
fee,
sqrtPriceX96
);
// Mint LP
(tokenId, , , ) = 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 _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 _handleLiquidity(address recipient) internal returns (address liquidityPool, uint256 tokenId){
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
isTokenTargetReached[token1] = true;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount0RoundingUp(
sqrtPriceX96,
liquidity,
unwrapAmount,
false
);
} else {
amount1 -= unwrapAmount; // Deduct unwrap amount from token1 if it is WBNB
isTokenTargetReached[token0] = true;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount1RoundingDown(
sqrtPriceX96,
liquidity,
unwrapAmount,
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
(liquidityPool, tokenId) = _createLP(positionManager, token0, token1, amount0, amount1, newSqrtPriceX96, party.lpFee, _getTicks(token0, 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 returns (address liquidityPool, uint256 tokenId){
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
isTokenTargetReached[token1] = true;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount0RoundingUp(
sqrtPriceX96,
liquidity,
unwrapAmount,
false
);
} else {
amount1 -= unwrapAmount; // Deduct unwrap amount from token1 if it is WBNB
isTokenTargetReached[token0] = true;
newSqrtPriceX96 = sqrtPriceCalculator.getNextSqrtPriceFromAmount1RoundingDown(
sqrtPriceX96,
liquidity,
unwrapAmount,
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
(liquidityPool, tokenId) = _createLP(positionManager, token0, token1, amount0, amount1, newSqrtPriceX96, party.lpFee, _getTicks(token0, 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
}
}

@codecov-commenter
Copy link

codecov-commenter commented Sep 24, 2024

⚠️ 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.

Files with missing lines Coverage Δ
contracts/BNBPartyFactory.sol 100.00% <100.00%> (ø)
contracts/BNBPartySwaps.sol 100.00% <ø> (ø)

@Lomet Lomet changed the title add party token LP validation add party token LP validation 1639710081 Sep 24, 2024
@YouStillAlive YouStillAlive marked this pull request as ready for review September 25, 2024 11:56
@Lomet Lomet merged commit db1f431 into master Sep 25, 2024
4 checks passed
@Lomet Lomet deleted the issue-77 branch September 25, 2024 12:07
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.

add lp check for joinParty, leaveParty 1639710081
3 participants