The owner has the ability to drain all GM
tokens from the strategy contract by instructing the keeper to call the compound() function with GM
tokens as the tokenIn
and the all balance of the contract as amountIn
.
The compound()
function, triggered by the keeper
, swaps a token (likely received from an airdrop or mistakenly sent to the vault contract) through the swapRouter
contract. It adds liquidity to GMX
to generate profit and is exclusively callable by the keeper
. However,
The owner can appoint a new keeper
and update the swapRouter
contract. With this authority, the owner can change the swapRouter
to a malicious contract.
The owner can then make the keeper call compound
with GM
LP tokens as tokenIn
and the entire vault balance as amountIn
.
The compound
function approves all tokens to the malicious swapRouter
contract and triggers swapExactTokensForTokens()
.
The malicious swapRouter
drains all LP tokens and transfers a nominal amount (e.g., 1 USDT) to prevent the function from reverting when adding liquidity to the GMX
protocol.
Consequently, the owner gains control of all LP tokens, leaving the contract with a meager 1 USD worth of investment.
This protocol's centralized management of strategies is understood, but the ability to drain all user funds poses a substantial risk, especially in the context of web3 applications.
example of malicious swapRouter
:
depositor and lenders lose all their investment.
vs code
manual review
in the compound function check that the tokenIn
is not the GM
lp token.
Impact: High Likelihood: Low Centralization risk is regarded a known issue. This tag will include all submissions : - Admin setter functions without validations
Impact: High Likelihood: Low Centralization risk is regarded a known issue. This tag will include all submissions : - Admin setter functions without validations
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.