nikhil840096 - The implementation of `payExecutionFee()` didn't take `EIP-150` into consideration. Keepers can steal additional execution fee from users. #95
The implementation of payExecutionFee() didn't take EIP-150 into consideration. Keepers can steal additional execution fee from users.
Summary
The implementation of processExecutionFee() didn't take EIP-150 into consideration. Keepers can steal additional execution fee from users
Vulnerability Detail
The issue arises on L18 of GasProcess.sol:processExecutionFee(), as it's an external function, callingprocessExecutionFee() is subject to EIP-150.
Only 63/64 gas is passed to the GasProcess sub-contract(external library), and the remaning 1/64 gas is reserved in the caller contract which will be refunded to keeper after the execution of the whole transaction. But calculation of usedGas includes this portion of the cost as well.
A malicious keeper can exploit this issue to drain out all execution fee, regardless of the actual execution cost.
Let's take executeMintStakeToken() operation as an example to show how it works:
As setting of tx.gaslimit doesn't affect the actual gas cost of the whole transaction, the excess gas will be refunded to msg.sender. Now, the keeper increases tx.gaslimit to make startGas = 6500K, the calculation of usedGas would be
nikhil840096
High
The implementation of
payExecutionFee()
didn't takeEIP-150
into consideration. Keepers can steal additional execution fee from users.Summary
The implementation of
processExecutionFee()
didn't takeEIP-150
into consideration. Keepers can steal additional execution fee from usersVulnerability Detail
The issue arises on
L18
ofGasProcess.sol:processExecutionFee()
, as it's an external function, callingprocessExecutionFee()
is subject to EIP-150. Only63/64
gas is passed to theGasProcess
sub-contract(external library
), and the remaning1/64
gas is reserved in the caller contract which will be refunded tokeeper
after the execution of the whole transaction. But calculation ofusedGas
includes this portion of the cost as well.A malicious keeper can exploit this issue to drain out all execution fee, regardless of the actual execution cost. Let's take
executeMintStakeToken()
operation as an example to show how it works:actualUsedGas
is the gas cost sincestartGas
(L76 ofStakeFacet .sol
) but before callingprocessExecutionFee()
(L88 ofStakeFacet.sol
)Let's say, the keeper sets tx.gaslimit to make
Then the calculation of
usedGas
,L18
ofGasProcess.sol
, would beand
As setting of
tx.gaslimit
doesn't affect the actual gas cost of the whole transaction, the excess gas will be refunded tomsg.sender
. Now, the keeper increasestx.gaslimit
to makestartGas = 6500K
, the calculation ofusedGas
would beand
We can see the keeper successfully drain out all execution fee, the user gets nothing refunded.
Impact
Keepers can steal additional execution fee from users.
Code Snippet
https://github.com/sherlock-audit/2024-05-elfi-protocol/blob/main/elfi-perp-contracts/contracts/process/GasProcess.sol#L18C17-L18C25
Tool used
Manual Review
Recommendation