Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lack of Input Validation for tokenId Allows Setting Invalid or Unauthorized Token IDs #5

Open
CipherHawk0 opened this issue Oct 14, 2024 · 0 comments

Comments

@CipherHawk0
Copy link

Summary

The absence of validation in the setTokenId function will cause a high impact on the staking mechanism for the protocol as an attacker with the SETTER_ROLE can set arbitrary tokenId values, leading to unauthorized staking or misallocation of rewards.

Root Cause

In SolidlyV2AMO.sol, the setTokenId function allows authorized addresses with the SETTER_ROLE to set the tokenId used for staking in the gauge without validating whether the provided tokenId_ is valid or authorized.

Relevant Code Snippet:

function setTokenId(uint256 tokenId_, bool useTokenId_) public override onlyRole(SETTER_ROLE) {
    tokenId = tokenId_;
    useTokenId = useTokenId_;
    emit TokenIdSet(tokenId, useTokenId);
}

Internal pre-conditions

  1. An account with the SETTER_ROLE needs to call setTokenId to set the tokenId.

  2. The tokenId_ being set is arbitrary and not validated against any authorization criteria.

External pre-conditions

  1. The veNFT contract (if applicable) should have mechanisms to verify the validity and ownership of tokenId_.

  2. External contracts (gauge, etc.) should have secure interfaces that handle unexpected tokenId values gracefully.

Attack Path

  1. The attacker, possessing the SETTER_ROLE, calls the setTokenId function.

  2. The attacker sets tokenId_ to an arbitrary or unauthorized value that does not correspond to a legitimate veNFT holder.

  3. The protocol's staking and reward mechanisms interact with the invalid tokenId, causing misallocation of rewards or unauthorized staking.

  4. Rewards intended for legitimate stakers may be redirected or become inaccessible, undermining the protocol's integrity.

Impact

The protocol suffers a high risk of misallocating rewards and disrupting the staking mechanism, leading to financial losses for legitimate users and loss of trust in the protocol's fairness and reliability.

PoC


// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "./SolidlyV2AMO.sol";

contract AttackerContract {
    SolidlyV2AMO amo;

    constructor(address amoAddress) {
        amo = SolidlyV2AMO(amoAddress);
    }

    function exploit() public {
        // Assume the attacker has SETTER_ROLE
        // Set an invalid tokenId that does not belong to a legitimate veNFT holder
        amo.setTokenId(999999, true);
    }
}

Mitigation

  1. Implement tokenId Validation:

Add checks to ensure that the provided tokenId_ is valid and authorized before setting it.

function setTokenId(uint256 tokenId_, bool useTokenId_) public override onlyRole(SETTER_ROLE) {
    require(_isValidTokenId(tokenId_), "Invalid tokenId");
    tokenId = tokenId_;
    useTokenId = useTokenId_;
    emit TokenIdSet(tokenId, useTokenId);
}

function _isValidTokenId(uint256 tokenId_) internal view returns (bool) {
    // Implement logic to verify tokenId validity, e.g., check ownership or existence
    return IVeNFT(veNFT).exists(tokenId_);
}
  1. Restrict SETTER_ROLE Privileges:

Limit the number of addresses with the SETTER_ROLE to reduce the risk of unauthorized parameter manipulation.

  1. Implement Multi-Signature Controls:

Require multiple approvals for setting critical parameters like tokenId, adding an additional layer of security.

  1. Regular Security Audits:

Conduct periodic audits to ensure that all role-based functions have adequate validation and security measures.

  1. Use Immutable Token IDs Where Possible:

If feasible, design the contract to use immutable tokenId values that cannot be changed post-deployment, preventing unauthorized manipulation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant