Closed code423n4 closed 1 year ago
minhquanym marked the issue as duplicate of #1044
dmvt changed the severity to QA (Quality Assurance)
dmvt marked the issue as grade-c
Overinflated severity
Hello @dmvt , Can I ask what is the reasoning behind the comment that this finding is an overinflated severity? Users' assets are at risk when doing swaps, I consider that to be a high severity.
As for the comment made in issue #1044, when I looked at the tests for this functionality I realized that an EOA was being used as the user, that lead me to think that EOAs were expected to use this functionality as well as contract accounts, that is why I wrote up in the recommendation to pull the assets from the caller instead of expecting the assets to be already transferred into the Swapper contract.
Could you take a second look at my report please?
As a general rule I always mark High -> Low as overinflated. This is a low risk issue in my view. EOAs should not be doing this, making it user error if they do.
@dmvt Have we got confirmation from the sponsor if this functionality is intended to be used only by Contract Accounts?
From what I can remember, I didn't see anywhere that those functions were intended to be used only by Contract accounts?
Hello! The issue is indeed valid if the contract is used as a standalone one. However, the swappers implementation is supposed to be used inside our other contracts, and transfer + swap is called within the same method. So there won't be a transfer to the contract and then a swap
Ruling stands. This is a user error / mistake. User should not call these functions directly. The sponsor should consider adding a notice to that effect in the code comments and other documentation.
Lines of code
https://github.com/Tapioca-DAO/tapioca-periph-audit/blob/023751a4e987cf7c203ab25d3abba58f7344f213/contracts/Swapper/BaseSwapper.sol#L152-L161
Vulnerability details
Impact
Proof of Concept
The
UniswapV2Swapper::swap()
&UniswapV3Swapper::swap()
executes theBaseSwapper:_extractTokens()
which it can withdraw assets from the yieldbox and debit them to the swapper contract.As demonstrated in the below coded PoC, if a user already has their tokens in the YieldBox and wants to do a swap, the user will transfer the assets that are deposited in the YieldBox to the Swapper contract, and then it will need to call the swap(), the problem is when an attacker calls first the swap() and steals the user's assets from the YieldBox.
Coded PoC
attacker
account in thetest.utils.ts
file, make sure to add it in the registerFork()diff --git a/test.utils.ts b/test.utils_PoC.ts index 00fc388..5e7b19a 100755 --- a/test.utils.ts +++ b/test.utils_PoC.ts @@ -1496,6 +1496,8 @@ export async function registerFork() { binanceWallet = await ethers.getSigner(process.env.BINANCE_WALLET_ADDRESS!);
await setBalance(attacker.address, 100000);
const usdcAddress = process.env.USDC!; const usdtAddress = process.env.USDT!; @@ -1589,6 +1591,7 @@ export async function registerFork() { usdcAssetId, usdtAssetId, deployer,
attacker, binanceWallet, yieldBox, uniswapV2Swapper, @@ -1717,4 +1720,4 @@ const createSimpleSwapData = ( };
return swapData; -}; +};
tapioca-periph-audit/test/
folderdescribe('UniswapV2Swapper', () => { describe('Attacker steal user assets abusing the Swapper swap() function', () => { it('Attacker should swap assets available in YB', async () => { const { uniswapV2Swapper, yieldBox, deployer, attacker, binanceWallet, weth, usdc, wethAssetId, usdcAssetId, createYbSwapData, } = await loadFixture(registerFork);
});
UniswapV2Swapper Attacker steal user assets abusing the Swapper swap() function Accounts before the attack ybWethUserBalanceBefore: BigNumber { value: "100000000000000000000000000" } ybUsdcUserBalanceBefore: BigNumber { value: "0" } ybWethAttackerBalanceBefore: BigNumber { value: "0" } ybUsdcAttackerBalanceBefore: BigNumber { value: "0" }
===================================================
Accounts After the attack ybWethUserBalanceAfter: BigNumber { value: "0" } ybWetAttackerBalanceAfter: BigNumber { value: "0" } ybUsdcUserBalanceAfter: BigNumber { value: "0" } ybUsdcAttackerBalanceAfter: BigNumber { value: "208042688800000000" } ✔ Attacker should swap assets available in YB (8593ms)
Assessed type
Other