Omniscia Teahouse Finance Audit
UniswapV3PathRecommender Manual Review Findings
UniswapV3PathRecommender Manual Review Findings
UVP-01M: Inexistent Sorting of Tokens
Type | Severity | Location |
---|---|---|
Gas Optimization | UniswapV3PathRecommender.sol:L43, L48 |
Description:
The swapPath
mapping may end up with an inefficient data structure as it does not sort the srcToken
and dstToken
values prior to writing to them.
Impact:
This change is classified under manual review findings given that it pertains to a design adjustment that we deem important for the long-term viability of the project.
Example:
17function setRecommendedPath(18 address[] calldata _tokens,19 uint24[] calldata _fees20) external onlyOwner returns (21 bytes memory pathExactInput,22 bytes memory pathExactOutput23) {24 uint256 feesLength = _fees.length;25 uint256 tokensLength = _tokens.length;26 if (tokensLength != feesLength + 1) revert TokensFeesLengthMismatch();27
28 address srcToken = _tokens[0];29 address dstToken = _tokens[tokensLength - 1];30 // swap router path:31 // exact input: abi.encodePacked(srcToken, fee, intermediaryToken, ..., fee, dstToken)32 // exact output: abi.encodePacked(dstToken, fee, intermediaryToken, ..., fee, srcToken)33 // sample of DAI => WETH9: DAI to USDC and then USDC to WETH934 // exact input: the path encoding is (DAI, 0.3%, USDC, 0.3%, WETH9)35 // exact output: the path encoding is (WETH9, 0.3%, USDC, 0.3%, DAI)36 pathExactInput = abi.encodePacked(srcToken);37 pathExactOutput = abi.encodePacked(dstToken);38 for (uint256 i; i < feesLength; i = i + 1) {39 pathExactInput = bytes.concat(pathExactInput, abi.encodePacked(_fees[i], _tokens[i + 1]));40 pathExactOutput = bytes.concat(pathExactOutput, abi.encodePacked(_fees[feesLength - i - 1], _tokens[feesLength - i - 1]));41 }42
43 swapPath[srcToken][dstToken] = [pathExactInput, pathExactOutput];44 emit SwapPathSet(block.timestamp, srcToken, dstToken, pathExactInput, pathExactOutput);45}46
47function getRecommendedPath(bool _isExactInput, address _srcToken, address _dstToken) external view returns (bytes memory path) {48 return _isExactInput ? swapPath[_srcToken][_dstToken][0] : swapPath[_srcToken][_dstToken][1];49}
Recommendation:
We advise the swapPath
to contain the sorted tokens as keys to it, permitting callers to acquire the swapPath
of any token combination via a single entry given that the swapPath
array contains both input and output paths.
Alleviation (302b96f324a88038a0872015466cd43783c14543):
The Teahouse Finance team stated that a token path between two tokens is not necessarily interchangeable.
As such, we consider the exhibit nullified given that its recommendation is inapplicable based on the business requirements of the UniswapV3PathRecommender
.