Without proper access control, any user can call the liquidate function. This means that malicious actors can force liquidations at their discretion, potentially leading to financial losses for the protocol and its users. For example, an attacker could liquidate positions prematurely or manipulate the system for personal gain. This not only threatens the integrity and security of the platform but also undermines user trust.
Proof of Concept
Example Scenario:
1- An attacker, Bob, identifies that there are no access control checks in the liquidate function.
2- Bob calls the liquidate function on a vault that is not in immediate danger of liquidation.
3- This premature liquidation results in financial losses for the vault owner and potential profits for Bob.
4- Repeated unauthorized liquidations destabilize the protocol, causing distrust among users.
Tools Used
Manual code review
Recommended Mitigation Steps
Implement Access Control: Ensure that only authorized entities, such as protocol administrators or designated liquidators, can call the liquidate function.
// Add a modifier to check for authorized users
modifier onlyAuthorized() {
require(isAuthorized(msg.sender), "Not authorized");
_;
}
// Implement the isAuthorized function to check against a whitelist or roles
function isAuthorized(address user) internal view returns (bool) {
// Example logic, replace with actual access control implementation
return authorizedUsers[user];
}
Use Role-Based Access Control (RBAC): Integrate with role-based access control libraries, such as OpenZeppelin’s AccessControl, to manage permissions more robustly.
Lines of code
https://github.com/code-423n4/2024-05-predy/blob/a9246db5f874a91fb71c296aac6a66902289306a/src/libraries/logic/LiquidationLogic.sol#L39-L119
Vulnerability details
Impact
Without proper access control, any user can call the liquidate function. This means that malicious actors can force liquidations at their discretion, potentially leading to financial losses for the protocol and its users. For example, an attacker could liquidate positions prematurely or manipulate the system for personal gain. This not only threatens the integrity and security of the platform but also undermines user trust.
Proof of Concept
Example Scenario:
1- An attacker, Bob, identifies that there are no access control checks in the liquidate function. 2- Bob calls the liquidate function on a vault that is not in immediate danger of liquidation. 3- This premature liquidation results in financial losses for the vault owner and potential profits for Bob. 4- Repeated unauthorized liquidations destabilize the protocol, causing distrust among users.
Tools Used
Manual code review
Recommended Mitigation Steps
Implement Access Control: Ensure that only authorized entities, such as protocol administrators or designated liquidators, can call the liquidate function.
// Add a modifier to check for authorized users modifier onlyAuthorized() { require(isAuthorized(msg.sender), "Not authorized"); _; }
// Implement the isAuthorized function to check against a whitelist or roles function isAuthorized(address user) internal view returns (bool) { // Example logic, replace with actual access control implementation return authorizedUsers[user]; }
function liquidate( uint256 vaultId, uint256 closeRatio, GlobalDataLibrary.GlobalData storage globalData, bytes memory settlementData ) external onlyAuthorized returns (IPredyPool.TradeResult memory tradeResult) { // existing logic... }
Use Role-Based Access Control (RBAC): Integrate with role-based access control libraries, such as OpenZeppelin’s AccessControl, to manage permissions more robustly.
Assessed type
Access Control