Platform: Code4rena
Start Date: 18/05/2023
Pot Size: $24,500 USDC
Total HM: 3
Participants: 72
Period: 4 days
Judge: LSDan
Id: 237
League: ETH
Rank: 34/72
Findings: 1
Award: $16.19
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: ABA
Also found by: 0x4non, 0xHati, 0xMosh, 0xSmartContract, 0xWaitress, 0xhacksmithh, 0xnev, 0xprinc, Arabadzhiev, BLACK-PANDA-REACH, Deekshith99, Dimagu, KKat7531, Kose, LosPollosHermanos, MohammedRizwan, QiuhaoLi, RaymondFam, Rickard, Rolezn, SAAJ, Sathish9098, Shubham, SmartGooofy, Tripathi, Udsen, V1235816, adriro, arpit, ayden, bigtone, codeVolcan, d3e4, dwward3n, fatherOfBlocks, favelanky, jovemjeune, kutugu, lfzkoala, lukris02, matrix_0wl, minhquanym, ni8mare, parsely, pxng0lin, radev_sw, ravikiranweb3, rbserver, sces60107, souilos, tnevler, turvy_fuzz, yellowBirdy
16.1907 USDC - $16.19
payParams()
will cause override
to state variables mintedAmount
and reservedRate
Instances(1)
file:: juice-buyback/contracts/JBXBuybackDelegate.sol https://github.com/code-423n4/2023-05-juicebox/blob/main/juice-buyback/contracts/JBXBuybackDelegate.sol#L144
<
it should <=
in if (_tokenCount < _quote - (_quote * _slippage / SLIPPAGE_DENOMINATOR))
condition checkfunction payParams(JBPayParamsData calldata _data) // @audit-issue multi time call to this function will cuse state variable to oveeride external override returns (uint256 weight, string memory memo, JBPayDelegateAllocation[] memory delegateAllocations) { // Find the total number of tokens to mint, as a fixed point number with 18 decimals uint256 _tokenCount = PRBMath.mulDiv(_data.amount.value, _data.weight, 10 ** 18); // Unpack the quote from the pool, given by the frontend (,, uint256 _quote, uint256 _slippage) = abi.decode(_data.metadata, (bytes32, bytes32, uint256, uint256)); // If the amount swapped is bigger than the lowest received when minting, use the swap pathway // @audit-info _quote - (_quote * _slippage / SLIPPAGE_DENOMINATOR) == _minimumReceivedFromSwap if (_tokenCount < _quote - (_quote * _slippage / SLIPPAGE_DENOMINATOR)) { // @audit should be <= // Pass the quote and reserve rate via a mutex mintedAmount = _tokenCount; reservedRate = _data.reservedRate; // Return this delegate as the one to use, and do not mint from the terminal delegateAllocations = new JBPayDelegateAllocation[](1); delegateAllocations[0] = JBPayDelegateAllocation({delegate: IJBPayDelegate(this), amount: _data.amount.value}); // @audit gas optimized return (0, _data.memo, delegateAllocations); // @audit-info 0 => for swapping, or the one corresponding to the reserved token to mint if minting }
Instances(1)
file:: juice-buyback/contracts/JBXBuybackDelegate.sol https://github.com/code-423n4/2023-05-juicebox/blob/main/juice-buyback/contracts/JBXBuybackDelegate.sol#L156
payable
as they handling ETH
function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external override { // @audit payable // Check if this is really a callback if (msg.sender != address(pool)) revert JuiceBuyback_Unauthorized(); // Unpack the data (uint256 _minimumAmountReceived) = abi.decode(data, (uint256)); // Assign 0 and 1 accordingly uint256 _amountReceived = uint256(-(_projectTokenIsZero ? amount0Delta : amount1Delta)); uint256 _amountToSend = uint256(_projectTokenIsZero ? amount1Delta : amount0Delta); // Revert if slippage is too high if (_amountReceived < _minimumAmountReceived) revert JuiceBuyback_MaximumSlippage(); // Wrap and transfer the weth to the pool weth.deposit{value: _amountToSend}(); weth.transfer(address(pool), _amountToSend); }
And
function _mint(JBDidPayData calldata _data, uint256 _amount) internal { IJBController controller = IJBController(jbxTerminal.directory().controllerOf(_data.projectId)); // Mint to the beneficiary with the fc reserve rate controller.mintTokensOf({ _projectId: _data.projectId, _tokenCount: _amount, _beneficiary: _data.beneficiary, _memo: _data.memo, _preferClaimedTokens: _data.preferClaimedTokens, _useReservedRate: true }); // Send the eth back to the terminal balance jbxTerminal.addToBalanceOf{value: _data.amount.value}( // @audit-issue is payable required, is transaction fail revert _data.projectId, _data.amount.value, JBTokens.ETH, "", new bytes(0) ); emit JBXBuybackDelegate_Mint(_data.projectId); }
Instances(2)
file:: juice-buyback/contracts/JBXBuybackDelegate.sol https://github.com/code-423n4/2023-05-juicebox/blob/main/juice-buyback/contracts/JBXBuybackDelegate.sol#L216 https://github.com/code-423n4/2023-05-juicebox/blob/main/juice-buyback/contracts/JBXBuybackDelegate.sol#L334
Instances(1)
file:: juice-buyback/contracts/JBXBuybackDelegate.sol https://github.com/code-423n4/2023-05-juicebox/blob/main/juice-buyback/contracts/JBXBuybackDelegate.sol#L237
#0 - c4-judge
2023-06-02T10:56:30Z
dmvt marked the issue as grade-b