DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: low
Invalid

Create order will always revert because of different address in approving and transfering funds

[H-2] Create order will always revert because of different address in approving and transfering funds

Vulnerability Details:
In createOrder function different address is used to approve and send token, This will cause revert when an address is approved to transfer tokens and a different address now transfered the token

In below code address(gmxRouter) was approved to transfer tokens and gExchangeRouter address is used to transfer the token

function createOrder(
// function implementations before the vulnerable part
if (
orderType == Order.OrderType.MarketSwap ||
orderType == Order.OrderType.MarketIncrease
) {
IERC20(orderData.initialCollateralToken).safeApprove(
- // this address was approved
address(gmxRouter), // this address was approved
orderData.amountIn
);
gExchangeRouter.sendTokens(
orderData.initialCollateralToken,
orderVault,
orderData.amountIn
);

And according to the GmxProxy script both address are diffrent address

// GMX ExchangeRouter
"0x7452c558d45f8afC8c83dAe62C3f8A5BE19c71f6",
// GMX Router
"0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8",

Impact:
This will lead to createOrder unable to work , causing reverts on createOrder

Proof of Concept:

GMX proxy Deployment script

async function main() {
const GmxProxy = await hre.ethers.getContractFactory("GmxProxy");
const gmxProxy = await upgrades.deployProxy(
GmxProxy,
[
"0xB0Fc2a48b873da40e7bc25658e5E6137616AC2Ee", // GMX OrderHandler
"0x08A902113F7F41a8658eBB1175f9c847bf4fB9D8", // GMX LiquidationHandler
"0x26BC03c944A4800299B4bdfB5EdCE314dD497511", // GMX AdlHandler
"0x69C527fC77291722b52649E45c838e41be8Bf5d5", // GMX ExchangeRouter
"0x7452c558d45f8afC8c83dAe62C3f8A5BE19c71f6", // GMX Router
"0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8", // GMX DataStore
"0x31eF83a530Fde1B38EE9A18093A333D8Bbbc40D5", // GMX OrderVault
"0x5Ca84c34a381434786738735265b9f3FD814b824", // GMX Reader
"0xe6fab3F0c7199b0d34d7FbE83394fc0e0D06e99d" // GMX ReferralStorage
]
);

initialize function

function initialize(
address _orderHandler,
address _liquidationHandler,
address _adlHandler,
address _gExchangeRouter,
address _gmxRouter,
address _dataStore,
address _orderVault,
address _gmxReader,
address _referralStorage
) external initializer {
__Ownable2Step_init();
orderHandler = _orderHandler;
liquidationHandler = _liquidationHandler;
adlHandler = _adlHandler;
gExchangeRouter = IExchangeRouter(_gExchangeRouter);
gmxRouter = _gmxRouter;
dataStore = IDataStore(_dataStore);
orderVault = _orderVault;
gmxReader = IGmxReader(_gmxReader);
referralStorage = _referralStorage;
minEth = 0.002 ether;
}
function createOrder(
Order.OrderType orderType,
IGmxProxy.OrderData memory orderData
) public returns (bytes32) {
require(msg.sender == perpVault, "invalid caller");
uint256 positionExecutionFee = getExecutionGasLimit(
orderType,
orderData.callbackGasLimit
) * tx.gasprice;
require(
address(this).balance >= positionExecutionFee,
"insufficient eth balance"
);
// check if execution feature is enabled
bytes32 executeOrderFeatureKey = keccak256(
abi.encode(
EXECUTE_ORDER_FEATURE_DISABLED,
orderHandler,
orderType
)
);
require(
dataStore.getBool(executeOrderFeatureKey) == false,
"gmx execution disabled"
);
gExchangeRouter.sendWnt{value: positionExecutionFee}(
orderVault,
positionExecutionFee
);
if (
orderType == Order.OrderType.MarketSwap ||
orderType == Order.OrderType.MarketIncrease
) {
// @audit : approved diffrent address and uses another address to transfer causing revert
IERC20(orderData.initialCollateralToken).safeApprove(
address(gmxRouter),
orderData.amountIn
);
gExchangeRouter.sendTokens(
orderData.initialCollateralToken,
orderVault,
orderData.amountIn
);
}

Recommended Mitigation:
Kindly fix the code to allow same address to approve and send

IERC20(orderData.initialCollateralToken).safeApprove(
address(gmxRouter),
orderData.amountIn
);
- gExchangeRouter.sendTokens(
+ gmxRouter.sendTokens(
orderData.initialCollateralToken,
orderVault,
orderData.amountIn
);
Updates

Lead Judging Commences

n0kto Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

invalid_approval_gmxRouter_instead_of_gExchangeRouter

Router is the one collecting tokens: https://github.com/gmx-io/gmx-synthetics/blob/caf3dd8b51ad9ad27b0a399f668e3016fd2c14df/contracts/router/BaseRouter.sol#L46 https://github.com/gmx-io/gmx-synthetics/blob/caf3dd8b51ad9ad27b0a399f668e3016fd2c14df/contracts/router/Router.sol#L27

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.