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

No way to part ways with project contractor #325

Open
code423n4 opened this issue Aug 6, 2022 · 0 comments
Open

No way to part ways with project contractor #325

code423n4 opened this issue Aug 6, 2022 · 0 comments
Labels
bug Something isn't working QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue valid

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-08-rigor/blob/5ab7ea84a1516cb726421ef690af5bc41029f88f/contracts/Project.sol#L123

Vulnerability details

Impact

The function Project.inviteContractor adds a contractor to the project. Once a contractor is set and contractorConfirmed is set to true, the contractor address can not be changed anymore.

If there are any real-world disputes between the project builder and the contractor, there is no way to part ways and define a new contractor. The project could then be stalled due to the contractor not signing multisig messages and griefing the system. Funds in the project contract could be locked as recovering the currency tokens does not work due to tasks being unfinished.

Proof of Concept

Project.sol#L123

function inviteContractor(bytes calldata _data, bytes calldata _signature)
    external
    override
{
    // Revert if contractor has already confirmed his invitation
    require(!contractorConfirmed, "Project::GC accepted"); // @audit-info If a contractor is confirmed, the contractor can not be changed anymore

    // Decode params from _data
    (address _contractor, address _projectAddress) = abi.decode(
        _data,
        (address, address)
    );

    // Revert if decoded project address does not match this contract. Indicating incorrect _data.
    require(_projectAddress == address(this), "Project::!projectAddress");

    // Revert if contractor address is invalid.
    require(_contractor != address(0), "Project::0 address");

    // Store new contractor
    contractor = _contractor;
    contractorConfirmed = true;

    // Check signature for builder and contractor
    checkSignature(_data, _signature);

    emit ContractorInvited(contractor);
}

Project.recoverTokens

function recoverTokens(address _tokenAddress) external override {
    /* If the token address is same as currency of this project,
        then first check if all tasks are complete */
    if (_tokenAddress == address(currency)) {
        // Iterate for each task and check if it is complete.
        uint256 _length = taskCount;
        for (uint256 _taskID = 1; _taskID <= _length; _taskID++) {
            require(tasks[_taskID].getState() == 3, "Project::!Complete");
        }
    }

    // Create token instance.
    IDebtToken _token = IDebtToken(_tokenAddress);

    // Check the balance of _token in this contract.
    uint256 _leftOutTokens = _token.balanceOf(address(this));

    // If balance is present then it to the builder.
    if (_leftOutTokens > 0) {
        _token.safeTransfer(builder, _leftOutTokens);
    }
}

Project.recoverTokens reverts if currency tokens are to be rescued as long as the project has unfinished tasks. As a task can only be set as completed by calling Project.setComplete, which in turn needs the message to be signed by the contractor, the contractor is able to grief the project.

Tools Used

Manual review

Recommended mitigation steps

Consider implementing a function that allows resetting the current contractor and then allows inviting a new contractor.

@code423n4 code423n4 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Aug 6, 2022
code423n4 added a commit that referenced this issue Aug 6, 2022
@parv3213 parv3213 added sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue labels Aug 11, 2022
@jack-the-pug jack-the-pug added QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax valid and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value labels Aug 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue valid
Projects
None yet
Development

No branches or pull requests

3 participants