Trader Joe v2 contest - 8olidity's results

One-stop-shop decentralized trading on Avalanche.

General Information

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

Trader Joe

Findings Distribution

Researcher Performance

Rank: 36/75

Findings: 2

Award: $1.30

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Awards

0.3268 USDC - $0.33

Labels

bug
3 (High Risk)
satisfactory
duplicate-299

External Links

Lines of code

https://github.com/code-423n4/2022-10-traderjoe/blob/main/src/LBToken.sol#L176-L196

Vulnerability details

Impact

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

Proof of Concept

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

Tools Used

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

Findings Information

🌟 Selected for report: rbserver

Also found by: 8olidity, ElKu, Rahoz, TomJ, Trust, cccz, d3e4, hyh, lukris02, m_Rassska, neumo, pashov, vv7

Labels

bug
2 (Med Risk)
satisfactory
duplicate-469

Awards

0.9728 USDC - $0.97

External Links

Lines of code

https://github.com/code-423n4/2022-10-traderjoe/blob/main/src/LBRouter.sol#L520

Vulnerability details

Impact

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 }

Proof of Concept

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); }

Tools Used

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

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter