Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

Unverified Contract Interface in setConfig Function

Summary

The setConfig function in the LiquidationKeeper contract allows the owner to update the perpsEngine address without verifying that the new address adheres to the expected IPerpsEngine interface, risking the introduction of incompatible or malicious contracts.

The setConfig function in the LiquidationKeeper contract is responsible for updating the perpsEngine address, a critical component for executing liquidations. However, the function does not verify that the new address implements the IPerpsEngine interface. This oversight allows the owner to set a contract that may not adhere to the expected interface, potentially leading to disruptions in the liquidation process. If a malicious or incompatible contract is set, it could prevent liquidations, execute unauthorized actions, or cause other unexpected behaviors within the LiquidationKeeper contract. This breaks the security guarantee of ensuring that only compatible and trusted contracts are used for critical operations.

Impact

The impact of this Medoium because it can lead to disruptions in the liquidation process, potentially preventing necessary liquidations or allowing unauthorized actions. This can result in financial losses, system instability, and a loss of trust in the protocol's integrity. The chances depend on the actions of the contract owner. If the owner is trusted and careful, the risk is low. But, the potential for human error or malicious intent makes this a valid concern, especially in decentralized environments where ownership may change.

Tools Used

manual review

Proof of Concept

  • The owner sets a contract that does not implement the IPerpsEngine interface.

contract MaliciousEngine {
// Intentionally implement a dummy version of getUnrealizedDebt
// that returns an invalid value or reverts.
function getUnrealizedDebt(uint128 /* marketId */) external pure returns (int256) {
// Return an incorrect value that disrupts liquidation logic.
return -1;
}
}
  • The malicious contract fails to execute liquidations correctly or performs unauthorized actions.

// Owner sets a malicious contract as perpsEngine
liquidationKeeper.setConfig(maliciousContractAddress);

Later, when the liquidation keeper triggers liquidations, it calls functions on the configured perpsEngine (now the malicious contract). For instance, when it calls:

int256 debt = perpsEngine.getUnrealizedDebt(marketId);

The call returns -1 instead of a correct debt value. This erroneous value can cause the liquidation logic to malfunction—preventing liquidations from triggering or leading to incorrect liquidation decisions. The disruption of the liquidation process can result in significant financial losses and destabilize the system.

Recommendations

Add a check so the new perpsEngine address adheres to the expected IPerpsEngine interface before updating it.

function setConfig(address perpsEngine) external onlyOwner {
if (perpsEngine == address(0)) {
revert Errors.ZeroInput("perpsEngine");
}
// Verify that the new address implements the IPerpsEngine interface
require(IPerpsEngine(perpsEngine).supportsInterface(type(IPerpsEngine).interfaceId), "Invalid interface");
LiquidationKeeperStorage storage self = _getLiquidationKeeperStorage();
self.perpsEngine = IPerpsEngine(perpsEngine);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

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