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

Vesting.sol#vest() Anyone can make other users' vestings revokable #220

Closed
code423n4 opened this issue Nov 10, 2021 · 1 comment
Closed
Labels
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 duplicate This issue or pull request already exists

Comments

@code423n4
Copy link
Contributor

Handle

WatchPug

Vulnerability details

vest() can be called by anyone with an arbitrary _beneficiary address to add a Timelock (vesting) to the _beneficiary.

At L83-88, it changes the global storage of revokable settings for the _beneficiary.

This allows anyone to change the revokable settings for other users. Non-revocable vestings can later be changed into revokable, and then be revoked, causing the user to lose funds.

https://github.com/code-423n4/2021-11-bootfinance/blob/7c457b2b5ba6b2c887dafdf7428fd577e405d652/vesting/contracts/Vesting.sol#L73-L98

function vest(address _beneficiary, uint256 _amount, uint256 _isRevocable) external payable whenNotPaused {
    require(_beneficiary != address(0), "Invalid address");
    require( _amount > 0, "amount must be positive");
    // require(totalVestedAmount.add(_amount) <= maxVestingAmount, 'maxVestingAmount is already vested');
    require(_isRevocable == 0 || _isRevocable == 1, "revocable must be 0 or 1");
    uint256 _unlockTimestamp = block.timestamp.add(unixYear);

    Timelock memory newVesting = Timelock(_amount, _unlockTimestamp);
    timelocks[_beneficiary].push(newVesting);

    if(_isRevocable == 0){
        benRevocable[_beneficiary] = [false,false];
    }
    else if(_isRevocable == 1){
        benRevocable[_beneficiary] = [true,false];
    }

    totalVestedAmount = totalVestedAmount.add(_amount);
    benTotal[_beneficiary] = benTotal[_beneficiary].add(_amount);

    // transfer to SC using delegate transfer
    // NOTE: the tokens has to be approved first by the caller to the SC using `approve()` method.
    vestingToken.transferFrom(msg.sender, address(this), _amount);

    emit TokenVested(_beneficiary, _amount, _unlockTimestamp, block.timestamp);
}

Recommendation

Consider making the revokable settings set per Timelock instead of per address.

@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 Nov 10, 2021
code423n4 added a commit that referenced this issue Nov 10, 2021
@chickenpie347 chickenpie347 added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label Nov 16, 2021
@chickenpie347 chickenpie347 added duplicate This issue or pull request already exists and removed sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") labels Nov 16, 2021
@chickenpie347
Copy link
Collaborator

Addressed in #132.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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 duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

3 participants