-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A malicious user can front-run calcualteFunding to prevent funding payments transfer and funding rate update. #2143
Comments
LQ because of front-running on Arb |
bytes032 marked the issue as low quality report |
More so than a front-run, it seems like the caller would pay a ton of gas to save gas to the "normal user" |
GalloDaSballo marked the issue as unsatisfactory: |
Hello @GalloDaSballo , I would like to clarify a few points for this issue: Based on doc, In addition, if the Dopex admin fails to bring all existing strike prices up to date through // contracts/perp-vault/PerpetualAtlanticVault.sol
/**
* @notice function to transfer funding into the LP in a drip-vested manner
* @dev addProceeds() is invoked to update totalCollateral in LP
**/
function updateFunding() public {
...
uint256 currentFundingRate = fundingRates[latestFundingPaymentPointer];
// @audit when currentFundingRate is reduced , there will be fewer amount of colleteralToken transferred
|> collateralToken.safeTransfer(
addresses.perpetualAtlanticVaultLP,
(currentFundingRate * (block.timestamp - startTime)) / 1e18
);
|> IPerpetualAtlanticVaultLP(addresses.perpetualAtlanticVaultLP)
.addProceeds(
(currentFundingRate * (block.timestamp - startTime)) / 1e18
);
... The attack is basically front-run Dopex admin or any one 's Since the impact is (1) loss/reduction of funding payments to option writers. (2) preventing Dopex admin from bringing funding rates up to date for multiple epochs. I think this should be a medium impact. |
This means that the Dopex Sponsor was supposed to pay 21k + Cost of Operations The attacker pays 21k + Cost of Operation The attacker is paying for processing the strikes to their detriment What am I missing? |
Hey @GalloDaSballo, thanks for the reply! Unless I missed your point, the attacker doesn't necessarily need to pay much gas to create a material impact - a reduction of funding payments to option writers. See my test below. According to sponsor, Because funding payments are sent in a dripped manner in every epoch base on See this gist for my test file: Two tests to compare:
Test results:
Running 2 tests for tests/rdpxV2-core/Unit.t.sol:Unit
[PASS] testCalculate50FrontRun() (gas: 30412123)
[PASS] testCalculate50Reference() (gas: 30301138)
Test result: ok. 2 passed; 0 failed; 0 skipped; finished in 830.13ms
Ran 1 test suites: 2 tests passed, 0 failed, 0 skipped (2 total tests) |
Hey @GalloDaSballo , ...
vm.expectRevert();
vault.calculateFunding(strikes2); //dopex admin gas: 9209
...
vault.calculateFunding(strikes3); //dopex admin gas: 2691810 function testCalculate50FrontRun() public {
...
uint256 fundingSent0To30 = fundingSent0To15 + fundingSent15To30; //2258915767123530 = 0.0023e18
assertEq(fundingSent0To30, 2258915767123530); //<- 15 to 30 mins: funding payment is non-zero due to calculateFundinng success
assert(fundingSent0To30 == fundingSent15To30); //<- funding is only paid for half of the time; function testCalculate50Reference() public {
...
uint256 fundingSent0To30 = fundingSent0To15 + fundingSent15To30;
assertEq(fundingSent0To30, 189433751639555556); //189433751639555556 = 0.189e18
assert(fundingSent0To30 > fundingSent0To15); //<- funding is paid for the full duraton. |
Lines of code
https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVault.sol#L415-L418
Vulnerability details
Impact
(Note: Sponsor confirms that MEV can be considered in scope in discord)
A malicious user can front-run
calculateFunding()
to prevent funding payments transfer and funding rate update. The attack only needs to front-run acalcualteFunding()
transaction submitted by anyone, and callcalculateFunding()
with one strike price that the original transaction contains. This will cause the originalcalcualteFunding()
transaction to revert. By doing so, a malicious user can prevent the majority of strick prices to be updated throughcalculateFunding()
, which delay and prevent funding payments to be transferred from RdpxV2Core to PerpetualAtlanticVault inpayFunding()
in a given epoch.The impact is that either funding payments can be missed for one or more epochs, or funding payments sent in a given epoch are reduced. Both can happen. I think it's medium severity given the impact on the funding flow.
Proof of Concept
(https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVault.sol#L415-L418)
As seen above, the second
_validate()
will revert the transaction if the subsequent transaction contains at least one strike price that has already been processed for a given epoch.As seen above in
payFunding()
, if for a given epoch if not all the active strike prices are updated throughcalculateFunding()
,_validate()
will revert thepayFunding()
transaction, prevent subsequent funding transfer and funding rate update. This means that if a malicious user can prevent mass strike prices update called by others or admin throughcalculateFunding()
,(1) the funding payments for that epoch will not be transferred to the vault (2) Or the actual funding paid throughupdateFunding()
will be greatly reduced since funding rate is not fully up to date.See POC test here that shows user1 front-run user2's
calculateFunding()
and revert user2's transaction:See test result here:
Tools Used
Manual review
Foundry
Recommended Mitigation Steps
In
calculateFunding()
, for each for loop, instead of revert when a strike price has been updated, simply skip one iteration and continue to the next iteration. Consider changing the_validate( latestFundingPerStrike[strikes[i]] != latestFundingPaymentPointer, 5 );
toif...continue
Assessed type
MEV
The text was updated successfully, but these errors were encountered: