User can make deposits/withdrawals (adding/removing liquidity from GMX) while sending msg.value
less than required execution fees
Users can deposit tokens in vaults by calling GMXVault.deposit
payable function with the required deposit parameters (such as token, amount, minimum share amount, slippage & execution fees), then this function will invoke GMXDeposit.deposit
with a msg.value
to cover the execution fees required by the GMX exchange router to add liquidity(3rd party).
In GMXDeposit.deposit
: various checks are made to ensure the sanity of the deposit parameters and the elligibility of the user to deposit,and to calculate the required tokenA
& tokenB
required to deposit in the GMX
protoco.
Then a AddLiquidityParams
struct is prepared to send with the GMXWorker.addLiquidity
where it will call the GMX exchange router to add liquidity.
The execution fee is going to be extracted from the deposit params sent by the user (_alp.executionFee = dp.executionFee;
), where a check is made by GMXChecks.beforeDepositChecks
function to ensure that deposit execution fees set in the params by the user (which doesn't neccessarily equals the msg.value
) is greater than or equals the minimum vault execution fees:
And as can be noticed; there's no check on the dp.executionFee
if it equals the msg.value
sent by the user.
The same issue is spotted in GMXWithdraw.withdraw
function when the user removes liquidity from GMX.
This can be exploited by any user by making a deposit with a very low (or zero) msg.value
, and using the residual native tokens in the vault contract to make these deposits.
GMXWorker.addLiquidity function
GMXWorker.removeLiquidity function
Manual Review.
When depositing non-native tokens; add a check to ensure that dp.executionFee == msg.value
.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.