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 Mar 3, 2024. It is now read-only.
sherlock-admin opened this issue
Aug 29, 2023
· 0 comments
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
Router double accounting problem and exposed funds in smart contract
Summary
LMPVaultRouter serves as a gateway for users to interact with LMPVault. When the user approves WETH and sends ETH with the deposit function call, the router still transfers WETH from the user even though it already got ETH with the call. Another user can watch for this and collect ETH from the router using an exposed function.
Vulnerability Detail
Users should use LMPVaultRouter to interact with LMPVault. There are two basic functions in LMPVaultRouterBase - deposit and mint. Users can use them to deposit tokens to LMPVault. Both functions share this problem. Let's take a look at deposit function. It is payable so the user can send ETH with it.
Both deposit and mint contain _processEthIn(vault) function calls. This function converts incoming ETH to WETH if possible.
function _processEthIn(ILMPVault vault) internal {
// if any eth sent, wrap it firstif (msg.value>0) {
// if asset is not weth, revertif (address(vault.asset()) !=address(weth9)) {
revertInvalidAsset();
}
// wrap eth
weth9.deposit{ value: msg.value }();
}
}
After ETH is processed, the router pulls the token which in this case would be WETH. This pulled WETH would be transfered to the LMPVault but the incoming wrapped ETH would stay in the router.
Here comes the second problem. LMPVaultRouterBase inherits from PeripheryPayments. This smart contract has public functions to pull tokens out of the smart contract and anyone can call them. If the hacker is faster than the user or the user doesn't know about this, the hacker can call the function to sweep the user's WETH from the router.
function sweepToken(IERC20token, uint256amountMinimum, addressrecipient) publicpayable {
uint256 balanceToken = token.balanceOf(address(this));
if (balanceToken < amountMinimum) revertInsufficientToken();
if (balanceToken >0) {
token.safeTransfer(recipient, balanceToken);
}
}
Add this test function to LMPVaultRouter.t.sol. Run it with the command forge test --match-contract LMPVaultRouterTest --match-test test_DoubleAccountingSweep.
function test_DoubleAccountingSweep() public {
// create cyril and donaldaddress cyril =makeAddr("cyril");
address donald =makeAddr("donald");
// deal etherdeal(cyril, 100 ether);
deal(donald, 100 ether);
// cyril approves and deposits etheruint amount =10ether;
vm.startPrank(cyril);
weth.approve(address(lmpVaultRouter), amount);
weth.deposit{value: amount}();
lmpVaultRouter.deposit{value: amount}(lmpVault, cyril, amount, 0);
vm.stopPrank();
assert(weth.balanceOf(address(lmpVaultRouter)) ==10 ether); // cyril's WETH is left in router// donald sees free weth and sweeps it
vm.prank(donald);
lmpVaultRouter.sweepToken(weth, weth.balanceOf(address(lmpVaultRouter)), donald);
assert(cyril.balance ==80 ether); // Cyril sent 10 ether to router and changed 10 ether to WETHassert(weth.balanceOf(cyril) ==0); // Router pulled cyrils 10 WETHassert(weth.balanceOf(address(lmpVaultRouter)) ==0); // No weth left in routerassert(weth.balanceOf(donald) ==10 ether); // Donald stole WETH from router
}
Impact
The user loses WETH because of router double accounting and it can be stolen from the router by anyone.
sherlock-admin2
changed the title
Clean Fuchsia Blackbird - Router double accounting problem and exposed funds in smart contract
0xJuda - Router double accounting problem and exposed funds in smart contract
Oct 3, 2023
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` labelHighA valid High severity issueRewardA payout will be made for this issue
0xJuda
high
Router double accounting problem and exposed funds in smart contract
Summary
LMPVaultRouter serves as a gateway for users to interact with LMPVault. When the user approves WETH and sends ETH with the deposit function call, the router still transfers WETH from the user even though it already got ETH with the call. Another user can watch for this and collect ETH from the router using an exposed function.
Vulnerability Detail
Users should use LMPVaultRouter to interact with LMPVault. There are two basic functions in LMPVaultRouterBase - deposit and mint. Users can use them to deposit tokens to LMPVault. Both functions share this problem. Let's take a look at deposit function. It is payable so the user can send ETH with it.
Both deposit and mint contain
_processEthIn(vault)
function calls. This function converts incoming ETH to WETH if possible.After ETH is processed, the router pulls the token which in this case would be WETH. This pulled WETH would be transfered to the LMPVault but the incoming wrapped ETH would stay in the router.
Here comes the second problem. LMPVaultRouterBase inherits from PeripheryPayments. This smart contract has public functions to pull tokens out of the smart contract and anyone can call them. If the hacker is faster than the user or the user doesn't know about this, the hacker can call the function to sweep the user's WETH from the router.
POC
Add this test function to LMPVaultRouter.t.sol. Run it with the command
forge test --match-contract LMPVaultRouterTest --match-test test_DoubleAccountingSweep
.Impact
The user loses WETH because of router double accounting and it can be stolen from the router by anyone.
Code Snippet
https://github.com/sherlock-audit/2023-06-tokemak/blob/main/v2-core-audit-2023-07-14/src/vault/LMPVaultRouterBase.sol#L43C1-L57C6
https://github.com/sherlock-audit/2023-06-tokemak/blob/main/v2-core-audit-2023-07-14/src/vault/LMPVaultRouterBase.sol#L111C1-L122C6
https://github.com/sherlock-audit/2023-06-tokemak/blob/main/v2-core-audit-2023-07-14/src/utils/PeripheryPayments.sol#L58C1-L65C6
Tool used
Manual Review
Recommendation
Change the logic so it wouldn't pull WETH from the user if enough ETH is included in the message call.
Duplicate of #1
The text was updated successfully, but these errors were encountered: