https://github.com/devZygo/zygoAuditHacken
The PerpDex contract has a critical vulnerability that allows an attacker to create zero margin positions, which can subsequently be liquidated. This exploit is targeted to lead to the forced depletion of the fundingFeeGlobalState.bufferBalance, resulting in legitimate users being unable to liquidate their positions if their marginAfterFundingFee is less than or equal to zero until the protocol funds the bufferBalance again and the attacker can carry on with the cycle again, so the protocol keeps pouring in funds that will keep getting drained otherwise legitimate user funds will get stuck, (talk about stuck between a rock and a hard place). This report outlines the details of the vulnerability, its implications, and recommendations for remediation.
Zero/very low Margin Positions: The contract allows users to open positions with zero margin or very low margin. This can be exploited by an attacker to create positions that do not require any initial capital.
Liquidation Mechanism: The liquidation process does not adequately check the margin requirements before allowing a position to be liquidated. Specifically, the following line in the PerpDexLib library is critical:
int256 marginAfterFundingFee = int256(position.margin) - fundingFee;
if (marginAfterFundingFee <= 0) {
// Margin cannot pay for fundingFee
uint256 deficitFundingFee = uint256(-marginAfterFundingFee); // casting negative int256 to uint256
require(
fundingFeeGlobalState.bufferBalance >= deficitFundingFee,
"Funding Fee buffer balance is insufficient"
);
fundingFeeGlobalState.bufferBalance -= deficitFundingFee;
If marginAfterFundingFee is less than or equal to zero, the attacker can continue creating such positions with the aim to liquidate their zero-margin position, draining the bufferBalance.
Impact on Legitimate Users: As the bufferBalance is depleted, legitimate users who have positions with marginAfterFundingFee less than or equal to zero will find themselves unable to liquidate their positions. This creates a scenario where the protocol's integrity is compromised, and users' funds are effectively locked.
bufferBalance is drained by malicious actors and they have to keep adding more to the balance since legitimate users with marginAfterFundingFee <= 0 need it to liquidate their positions otherwise funds will get stuck permanently.** The actor can do this as many times as he sees fit with different addresses and at very minimal cost. This would make it extremely unlikely for the protocol to pinpoint the point of attack. This makes it a Critical severity as the protocol will keep funding and losing the bufferBalance to these malicious positions.
Margin Requirement Enforcement: Implement strict checks to ensure that positions cannot be opened with zero margin. This can be achieved by modifying the openPosition and openLimitOrder functions to require a minimum margin.
Liquidation Logic Review: Revise the liquidation logic to ensure that positions can only be liquidated if the marginAfterFundingFee is greater than zero. This will prevent the exploitation of zero-margin positions.
Buffer Balance Management: Introduce mechanisms to monitor and manage the bufferBalance effectively. This could include limits on how much can be liquidated in a single transaction or requiring additional collateral for positions that are at risk of being liquidated.
Audit and Testing: Conduct a thorough audit of the entire contract and its associated libraries to identify and rectify any other potential vulnerabilities. Additionally, implement comprehensive testing scenarios that simulate various attack vectors.
User Education: Inform users about the risks associated with margin trading and the importance of maintaining sufficient margin in their positions.
The identified vulnerability poses a significant risk to the PerpDex protocol and its users. Immediate action is required to address the issues related to zero margin positions and the liquidation process. By implementing the recommended changes, the protocol can enhance its security and maintain user trust.
To validate the vulnerability regarding zero margin positions and their exploitation in the PerpDex contract, follow these clear and logical steps:
PerpDex contract on a test network (e.g., Rinkeby, Ropsten) using a development environment like Remix or Truffle.Open a Position with Zero Margin:
openPosition function with a margin amount of zero.// Example function call
PerpDexLib.OpenPositionData memory positionData = PerpDexLib.OpenPositionData({
trader: msg.sender,
marginAmount: 0, // Zero margin
// ... other parameters
});
perpDex.openPosition(positionData);
Attempt Liquidation:
liquidatePositions) on the zero-margin position created in Step 2.fundingFeeGlobalState.bufferBalance before and after the liquidation.bufferBalance should decrease.uint256[] memory positionsToLiquidate = new uint256[](1);
positionsToLiquidate[0] = positionId; // ID of the zero-margin position
perpDex.liquidatePositions(positionsToLiquidate, roundIds, priceData);
Check Buffer Balance:
fundingFeeGlobalState.bufferBalance to see how much it has decreased.uint256 bufferBalance = perpDex.fundingFeeGlobalState.bufferBalance;
Create a Legitimate Position:
Attempt Liquidation:
bufferBalance has been depleted, the liquidation should fail or revert, indicating that legitimate users cannot liquidate their positions.