Skip to content

Latest commit

 

History

History
78 lines (55 loc) · 2.35 KB

File metadata and controls

78 lines (55 loc) · 2.35 KB

Colossal Chiffon Urchin

Medium

Users cannot unvouch at any time

Summary

Whenever protocol is paused - users will not be able to withdraw funds

Root Cause

According to docs/whitepaper

You may withdraw your staked funds at any time by unvouching.

Which isn't true:

  function unvouch(uint256 vouchId) public whenNotPaused nonReentrant {
    Vouch storage v = vouches[vouchId];
    _vouchShouldExist(vouchId);
    _vouchShouldBePossibleUnvouch(vouchId);
    // because it's $$$, you can only withdraw/unvouch to the same address you used to vouch
    // however, we don't care about the status of the address's profile; funds are always attached
    // to an address, not a profile
    if (vouches[vouchId].authorAddress != msg.sender) {
      revert AddressNotVouchAuthor(vouchId, msg.sender, vouches[vouchId].authorAddress);
    }

    v.archived = true;
    // solhint-disable-next-line not-rely-on-time
    v.activityCheckpoints.unvouchedAt = block.timestamp;
    // remove the vouch from the tracking arrays and index mappings
    _removeVouchFromArrays(v);

    // apply fees and determine how much is left to send back to the author
    (uint256 toWithdraw, ) = applyFees(v.balance, false, v.subjectProfileId);
    // set the balance to 0 and save back to storage
    v.balance = 0;
    // send the funds to the author
    // note: it sends it to the same address that vouched; not the one that called unvouch
    (bool success, ) = payable(v.authorAddress).call{ value: toWithdraw }("");
    if (!success) {
      revert FeeTransferFailed("Failed to send ETH to author");
    }

    emit Unvouched(v.vouchId, v.authorProfileId, v.subjectProfileId);
  }

contracts/EthosVouch.sol#L452

Internal pre-conditions

protocol paused contract

External pre-conditions

No response

Attack Path

No response

Impact

invariant doesn't hold, users should be able to withdraw funds at any time. User will lose access to funds when protocol paused

PoC

No response

Mitigation

-  function unvouch(uint256 vouchId) public whenNotPaused nonReentrant {
+  function unvouch(uint256 vouchId) public nonReentrant {
    Vouch storage v = vouches[vouchId];