You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Sep 17, 2023. It is now read-only.
sherlock-admin opened this issue
Mar 13, 2023
· 0 comments
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelMediumA valid Medium severity issueRewardA payout will be made for this issue
UniswapSwapAdapter.swap() only works for paths formed by two tokens
Summary
If UniswapSwapAdapter.swap() receives in the parameter _swapData a path with more than two tokens, it will revert.
Vulnerability Detail
In the UniswapSwapAdapter.swap() function the is a check to ensure that the path ends in _outputToken.
The path value will be right padded with zeroes to fit a 32 byte word. However, when extracting the value of the last token in the path, the length of the padding is hardcoded for a two token path.
function swap(address_outputToken, bytescalldata_swapData) externalreturns (uint256) {
// Decode swap data
(uint256deadline, uint256_amountIn, uint256_amountOutMinimum, bytesmemory_path) =abi.decode(
_swapData,
(uint256, uint256, uint256, bytes)
);
// Check that the outputToken is the final token in the pathuint256 length = _swapData.length;
address swapOutputToken =address(bytes20(_swapData[length -41:length -21])); // 👈 values hardcoded for two token pathif (swapOutputToken != _outputToken) {
// The keeper-inputted Output Token differs from what the contract says it must be.revertincorrectOutputToken();
}
// ...
Thus, if a path with more than two tokens is passed in the parameters, swapOutputToken will not match _outputToken and the transaction will revert.
Impact
For yield tokens whose Uniswap route to TAU involves more tokens the yield pull process will fail when SwapHandler.swapForTau() is called by a keeper.
This test shows how a swap fails when we add a third token in the middle of the path.
describe.only("Swap",async()=>{// let path: string;
let basicSwapParams: string;constsetupTokensFixture=deployments.createFixture(async()=>{// Approve DAIawaitswapAdapter.connect(keeper).approveTokens(testDAI.address);expect(awaittestDAI.allowance(swapAdapter.address,swapRouter.address)).to.equal(ethers.constants.MaxUint256);// Get generic swap parametersbasicSwapParams=buildUniswapSwapAdapterData([testDAI.address,"0x1111111111111111111111111111111111111111",testUSDT.address],[3000,3000],testDepositAmount,expectedReturnAmount,0,).swapData;});beforeEach(asyncfunction(){awaitsetupTokensFixture();});it.only("fails to swap if there are more than two tokens",async()=>{awaitexpect(swapAdapter.swap(testUSDT.address,basicSwapParams)).to.be.revertedWithCustomError(swapAdapter,"incorrectOutputToken",);});});
Tool used
Manual Review
Recommendation
Adapt the code so that it works for any number of tokens int he path.
// Check that the outputToken is the final token in the path
uint256 length = _swapData.length;
-- address swapOutputToken = address(bytes20(_swapData[length - 41:length - 21]));++ uint256 pathLength = _path.length;++ uint256 rightPaddingLength = length - 160 - _path.length; // offset of 160 is the length of 3 uint256 params + bytes header++ address swapOutputToken = address(bytes20(_swapData[length - (rightPaddingLength + 20):length - rightPaddingLength]));
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelMediumA valid Medium severity issueRewardA payout will be made for this issue
shaka
medium
UniswapSwapAdapter.swap()
only works for paths formed by two tokensSummary
If
UniswapSwapAdapter.swap()
receives in the parameter_swapData
a path with more than two tokens, it will revert.Vulnerability Detail
In the
UniswapSwapAdapter.swap()
function the is a check to ensure that the path ends in_outputToken
.The path value will be right padded with zeroes to fit a 32 byte word. However, when extracting the value of the last token in the path, the length of the padding is hardcoded for a two token path.
Thus, if a path with more than two tokens is passed in the parameters,
swapOutputToken
will not match_outputToken
and the transaction will revert.Impact
For yield tokens whose Uniswap route to TAU involves more tokens the yield pull process will fail when
SwapHandler.swapForTau()
is called by a keeper.Code Snippet
https://github.com/sherlock-audit/2023-03-taurus/blob/main/taurus-contracts/contracts/SwapAdapters/UniswapSwapAdapter.sol#L21-L35
Proof of concept
This test shows how a swap fails when we add a third token in the middle of the path.
Tool used
Manual Review
Recommendation
Adapt the code so that it works for any number of tokens int he path.
Duplicate of #160
The text was updated successfully, but these errors were encountered: