Skip to content

Latest commit

 

History

History
97 lines (72 loc) · 3.29 KB

File metadata and controls

97 lines (72 loc) · 3.29 KB

Soaring Orchid Kangaroo

Medium

unvouchUnhealthy method can never succeed in normal circumstances

Summary

The unvouchUnhealthy method is a convenience method that allows you to execute unvouch and markUnhealthy at once.

  function unvouchUnhealthy(uint256 vouchId) external {
    unvouch(vouchId);
    markUnhealthy(vouchId);
  }

https://github.com/sherlock-audit/2024-10-ethos-network/blob/main/ethos/packages/contracts/contracts/EthosVouch.sol#L270

For the unvouchUnhealthy method to execute successfully, both the unvouch and markUnhealthy methods must succeed, but the value of activityCheckpoints.unvouchedAt causes the markUnhealthy method to always fail.

  1. activityCheckpoints.unvouchedAt uses _vouchShouldBePossibleUnhealthy method to check if the vouch could become unhealthy, which checks if the current block.timestamp is greater than activityCheckpoints.unvouchedAt + unhealthyResponsePeriod.
  function unvouch(uint256 vouchId) public {
    uint256 profileId = IEthosProfile(
      contractAddressManager.getContractAddressForName(ETHOS_PROFILE)
    ).verifiedProfileIdForAddress(msg.sender);
    Vouch storage v = vouches[vouchId];
    _vouchShouldExist(vouchId);
    _vouchShouldBelongToAuthor(vouchId, profileId);
    _vouchShouldBePossibleUnvouch(vouchId);

    v.archived = true;
    // solhint-disable-next-line not-rely-on-time
    v.activityCheckpoints.unvouchedAt = block.timestamp;

https://github.com/sherlock-audit/2024-10-ethos-network/blob/main/ethos/packages/contracts/contracts/EthosVouch.sol#L281

  1. The markUnhealthy method requires that the current block.timestamp is greater than activityCheckpoints.unvouchedAt + unhealthyResponsePeriod to succeed.
  function _vouchShouldBePossibleUnhealthy(uint256 vouchId) private view {
    Vouch storage v = vouches[vouchId];
    bool stillHasTime = block.timestamp <=
      v.activityCheckpoints.unvouchedAt + unhealthyResponsePeriod;

https://github.com/sherlock-audit/2024-10-ethos-network/blob/main/ethos/packages/contracts/contracts/EthosVouch.sol#L459

  1. The default value of unhealthyResponsePeriod is set in the initialize method and is 24 hours.
  function initialize(
    address _owner,
    address _admin,
    address _expectedSigner,
    address _signatureVerifier,
    address _contractAddressManagerAddr,
    address _weth
  ) external initializer {
    __accessControl_init(
      _owner,
      _admin,
      _expectedSigner,
      _signatureVerifier,
      _contractAddressManagerAddr
    );

    __UUPSUpgradeable_init();

    configuredMinimumVouchAmount = ABSOLUTE_MINIMUM_VOUCH_AMOUNT;
    unhealthyResponsePeriod = 24 hours;

https://github.com/sherlock-audit/2024-10-ethos-network/blob/main/ethos/packages/contracts/contracts/EthosVouch.sol#L97

Root Cause

In unvouch method, we set activityCheckpoints.unvouchedAt value to block.timestamp, and in markUnhealthy, we check if block.timestamp is greater than activityCheckpoints.unvouchedAt + unhealthyResponsePeriod, so unvouchUnhealthy method always fails if unhealthyResponsePeriod is not 0.

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

No response

Impact

No response

PoC

No response

Mitigation

No response