File: NapierRouter.sol
85: function swapCallback(int256 underlyingDelta, int256 ptDelta, bytes calldata data) external override {
..SNIP..
152: // Pull underlying from payer.
153: // Economically, it's almost unlikely that the payer doesn't need to pay underlying asset.
154: // But if the above case happens, it would be reverted.
155: if (params.underlyingDeposit <= uReceived) revert Errors.RouterNonSituationSwapUnderlyingForYt();
156: uint256 uPull = params.underlyingDeposit - uReceived;
157: if (uPull > params.maxUnderlyingPull) revert Errors.RouterExceededLimitUnderlyingIn();
158: _pay(underlying, params.payer, address(this), uPull);
Before execution, the user does not know the exact amount of Native ETH to be sent to the contract as the actual on-chain condition might be different from the result during off-chain simulation. Thus, users will often send more ETH as a buffer to avoid unnecessary revert.
Bob transferred 100 ETH to the contract. However, in the end, only needs 99 ETH and the uPull is set to 99 ETH. Thus, the remaining 1 ETH is stuck in the contract at the end of the TX and will be stolen by MEV or front-runner after the TX.
xiaoming90
high
swapUnderlyingForYt
function did not sweep unused ETH back to usersSummary
swapUnderlyingForYt
does not sweep the remaining unused ETH back to users, resulting in a loss of assets for the victim.Vulnerability Detail
The Napier Router is designed to support both WETH and native ETH for its operation.
The
swapUnderlyingForYt
function allows the users to pay in Native ETH with the support of the payable modifier.https://github.com/sherlock-audit/2024-01-napier/blob/main/v1-pool/src/NapierRouter.sol#L297
During the swap, it will make a callback to the Router, and the Router will need to ensure that
uPull
amount of ETH has been collected.https://github.com/sherlock-audit/2024-01-napier/blob/main/v1-pool/src/NapierRouter.sol#L157
Before execution, the user does not know the exact amount of Native ETH to be sent to the contract as the actual on-chain condition might be different from the result during off-chain simulation. Thus, users will often send more ETH as a buffer to avoid unnecessary revert.
Bob transferred 100 ETH to the contract. However, in the end, only needs 99 ETH and the
uPull
is set to 99 ETH. Thus, the remaining 1 ETH is stuck in the contract at the end of the TX and will be stolen by MEV or front-runner after the TX.https://github.com/sherlock-audit/2024-01-napier/blob/main/v1-pool/src/base/PeripheryPayments.sol#L82
Impact
Loss of assets for the victim.
Code Snippet
https://github.com/sherlock-audit/2024-01-napier/blob/main/v1-pool/src/NapierRouter.sol#L297
Tool used
Manual Review
Recommendation
The remaining unused ETH should be returned to the caller after the TX.
Duplicate of #81