Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: high
Invalid

Unrestricted Access to Critical Accounting Function

Summary

A critical vulnerability exists in the FundFlowController.sol contract where the updateOperatorVaultGroupAccounting function lacks proper access control. This oversight allows any external actor to invoke the function, leading to unauthorized manipulation of essential accounting parameters within the OperatorVCS.sol contract. Such unauthorized actions can disrupt the staking process, misallocate funds, and compromise the overall integrity of the stake.link platform.

Vulnerability Details

1. Unrestricted Function Access

// FundFlowController.sol
function updateOperatorVaultGroupAccounting(uint256[] calldata _vaultGroups) external {
// Function body
}

Explanation:
The updateOperatorVaultGroupAccounting function is marked as external without any access control modifiers. This design flaw permits any external entity to call the function, regardless of their authorization status.

2. Interaction with Protected Function in OperatorVCS.sol

// OperatorVCS.sol
function updateVaultGroupAccounting(
uint256[] calldata _vaultGroups,
uint256[] calldata _totalDepositRoom,
uint256 _totalUnbonded,
uint256 _vaultMaxDeposits
) external onlyFundFlowController {
// Function body
}

Explanation:
The updateVaultGroupAccounting function in OperatorVCS.sol is safeguarded by the onlyFundFlowController modifier, ensuring that only the FundFlowController contract can invoke it.

modifier onlyFundFlowController() {
if (msg.sender != address(fundFlowController)) revert SenderNotAuthorized();
_;
}

3. Exploit Flow

// Attacker's Contract
contract Attacker {
FundFlowController public fundFlowController;
constructor(address _fundFlowController) {
fundFlowController = FundFlowController(_fundFlowController);
}
function exploit(uint256[] calldata maliciousVaultGroups) external {
fundFlowController.updateOperatorVaultGroupAccounting(maliciousVaultGroups);
}
}

Explanation:
An attacker deploys a malicious contract that interfaces with the vulnerable FundFlowController. By calling the exploit function and passing in crafted _vaultGroups, the attacker can manipulate the accounting parameters in OperatorVCS.sol. Since FundFlowController has the authority to call OperatorVCS.updateVaultGroupAccounting, the modifier check passes, allowing the unauthorized update.

4. Unauthorized Parameter Manipulation

// OperatorVCS.sol after Exploit
uint256 public totalUnbonded; // Originally set correctly
uint256 public totalDepositRoom; // Originally set correctly
uint256 public vaultMaxDeposits; // Originally set correctly
// After Attack
totalUnbonded = 0;
totalDepositRoom = 0;
vaultMaxDeposits = 0;

Explanation:
Post-exploitation, critical variables such as totalUnbonded, totalDepositRoom, and vaultMaxDeposits can be maliciously set to unintended values like 0. This alteration can lead to severe disruptions in staking operations, fund allocations, and withdrawal processes.

Impact

  • Financial Risk:
    Unauthorized manipulation of staking parameters can result in misallocation of funds, leading to potential financial losses for stakers and the platform.

  • Denial of Service:
    By setting critical parameters to invalid values, legitimate users may be prevented from staking or withdrawing their funds, effectively causing a denial of service.

  • System Integrity:
    The integrity of the staking mechanism is compromised, undermining trust in the platform's security and reliability.

Tools Used

Manual Review

Recommendations

1. Implement Strict Access Control

// FundFlowController.sol
import "@openzeppelin/contracts/access/Ownable.sol";
contract FundFlowController is UUPSUpgradeable, OwnableUpgradeable {
function updateOperatorVaultGroupAccounting(uint256[] calldata _vaultGroups) external onlyOwner {
// Function body remains unchanged
}
}

Explanation:
Restrict the updateOperatorVaultGroupAccounting function to only be callable by the contract owner by integrating the onlyOwner modifier from OpenZeppelin's Ownable contract.

2. Validate Caller Permissions

Ensure that any function interacting with critical components like OperatorVCS.sol strictly verifies the caller's authority, preventing unauthorized entities from making sensitive updates.

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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