Liquid Staking

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

Insufficient Access Control on Critical Functions

Summary

A critical vulnerability exists in the base/Vault.sol contract of the stake.link platform, specifically pertaining to the lack of robust access control mechanisms on the deposit and withdraw functions. These functions are intended to be exclusively callable by the vaultController. However, if the vaultController can be manipulated or compromised, unauthorized entities may gain the ability to perform deposits and withdrawals, leading to potential financial losses and state manipulation of the vault.

Vulnerability Details

Issue: Insufficient Access Control on deposit and withdraw Functions

The deposit and withdraw functions in the base/Vault.sol contract are protected by the onlyVaultController modifier, which restricts access to the vaultController. However, the current implementation lacks mechanisms to prevent unauthorized changes to the vaultController, making the system susceptible to exploitation if the vaultController is compromised.


1. Modifier Implementation

modifier onlyVaultController() {
require(msg.sender == vaultController, "Sender not authorized");
_;
}

Explanation:
This modifier ensures that only the address designated as vaultController can invoke the deposit and withdraw functions. It checks that the caller (msg.sender) matches the vaultController address.


2. Deposit Function

function deposit(uint256 _amount) external onlyVaultController {
// Deposit logic
}

Explanation:
The deposit function allows the vaultController to deposit funds into the vault. While the function is correctly restricted by the onlyVaultController modifier, the vulnerability arises if the vaultController address can be altered by unauthorized parties.


3. Withdraw Function

function withdraw(uint256 _amount) external onlyVaultController {
// Withdraw logic
}

Explanation:
Similarly, the withdraw function enables the vaultController to withdraw funds from the vault. The security of this function is contingent upon the integrity of the vaultController address.


4. Potential Flaw: Mutable vaultController

function setVaultController(address _newController) external onlyOwner {
vaultController = _newController;
}

Explanation:
If a function like setVaultController exists and is only protected by onlyOwner, it introduces a single point of failure. Should the owner's credentials be compromised, an attacker can reassign the vaultController to a malicious address, thereby bypassing the intended access restrictions on deposit and withdraw.


5. Lack of Multi-Signature or Timelock Mechanisms

Explanation:
The absence of multi-signature requirements or timelock delays for critical functions like changing the vaultController exacerbates the vulnerability. Without these safeguards, even transient compromises can lead to immediate and unauthorized actions affecting the vault's integrity.


Impact

  • Unauthorized Deposits and Withdrawals: Malicious actors can manipulate the vault's funds by depositing or withdrawing without proper authorization.

  • Financial Losses: Users' staked funds may be drained, leading to significant financial repercussions.

  • State Manipulation: Attackers can alter the vault's internal state, affecting staking rewards distribution and overall protocol functionality.

  • Erosion of Trust: Such vulnerabilities can severely damage the platform's reputation, deterring users from participating in staking activities.

Tools Used

  • Manual Review

Recommendations

1. Immutable vaultController

  • Action: Ensure that the vaultController address is set only once during contract initialization and cannot be altered thereafter.

  • Implementation:

    address public immutable vaultController;
    constructor(address _vaultController) {
    require(_vaultController != address(0), "Invalid controller address");
    vaultController = _vaultController;
    }
  • Benefit: Eliminates the risk of unauthorized changes to the vaultController, maintaining consistent access control.

2. Multi-Signature Controls

  • Action: Implement multi-signature (multi-sig) requirements for sensitive functions, especially those that modify critical roles like vaultController.

  • Implementation:

    • Utilize OpenZeppelin’s AccessControl or Ownable with multi-sig wallets.

    function setVaultController(address _newController) external onlyMultiSig {
    require(_newController != address(0), "Invalid address");
    vaultController = _newController;
    }
  • Benefit: Enhances security by requiring multiple approvals for critical changes, mitigating the risk of single-point compromises.

3. Timelock Mechanisms

  • Action: Introduce timelock delays for executing critical functions, allowing ample time for monitoring and response in case of suspicious activities.

  • Implementation:

    • Integrate OpenZeppelin’s TimelockController to manage function execution delays.

    function setVaultController(address _newController) external onlyTimelock {
    vaultController = _newController;
    }
  • Benefit: Provides a buffer period to detect and prevent malicious actions before they are executed, enhancing overall security.

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.