Skip to content

Latest commit

 

History

History
90 lines (62 loc) · 2.91 KB

File metadata and controls

90 lines (62 loc) · 2.91 KB

Orbiting Steel Tardigrade

Medium

Missing whenNotPaused modifier for the uninviteUser() function

Summary

In the EthosProfile contract, functions like createProfile(), inviteAddress(), and incrementProfileCount() are all protected by the whenNotPaused modifier. However, the uninviteUser() function lacks this protection, allowing users to execute actions even when the contract is in a paused state. This could lead to unintended operations during downtime.

  function uninviteUser(address user) external onlyNonZeroAddress(user) {
    uint256 id = profileIdByAddress[msg.sender];
    Profile storage inviter = profiles[id];

    uint256 index = sentInviteIndexByProfileIdAndAddress[id][user];
    if (index >= inviter.inviteInfo.sent.length || inviter.inviteInfo.sent[index] != user) {
      revert AddressNotInvited();
    }

    // Move the last element to the removed position
    uint256 lastIndex = inviter.inviteInfo.sent.length - 1;
    address lastAddress = inviter.inviteInfo.sent[lastIndex];
    inviter.inviteInfo.sent[index] = lastAddress;
    sentInviteIndexByProfileIdAndAddress[id][lastAddress] = index;

    // Remove the last element
    inviter.inviteInfo.sent.pop();
    delete sentInviteIndexByProfileIdAndAddress[id][user];

    inviter.inviteInfo.available++;
    sentAt[id][user] = 0;
    emit Uninvited(id, msg.sender, inviter.inviteInfo.available, user);
  }

Root Cause

https://github.com/sherlock-audit/2024-10-ethos-network/blob/main/ethos/packages/contracts/contracts/EthosProfile.sol#L258-L280 The uninviteUser() function does not have the whenNotPaused modifier

Internal pre-conditions

The protocol is in a paused state.

External pre-conditions

No response

Attack Path

  1. The protocol is in a paused state.
  2. In this state, users are still able to perform certain operations.

Impact

When the protocol is in a paused state, users can still perform certain operations.

PoC

  function uninviteUser(address user) external onlyNonZeroAddress(user) {
    uint256 id = profileIdByAddress[msg.sender];
    Profile storage inviter = profiles[id];

    uint256 index = sentInviteIndexByProfileIdAndAddress[id][user];
    if (index >= inviter.inviteInfo.sent.length || inviter.inviteInfo.sent[index] != user) {
      revert AddressNotInvited();
    }

    // Move the last element to the removed position
    uint256 lastIndex = inviter.inviteInfo.sent.length - 1;
    address lastAddress = inviter.inviteInfo.sent[lastIndex];
    inviter.inviteInfo.sent[index] = lastAddress;
    sentInviteIndexByProfileIdAndAddress[id][lastAddress] = index;

    // Remove the last element
    inviter.inviteInfo.sent.pop();
    delete sentInviteIndexByProfileIdAndAddress[id][user];

    inviter.inviteInfo.available++;
    sentAt[id][user] = 0;
    emit Uninvited(id, msg.sender, inviter.inviteInfo.available, user);
  }

Mitigation

Add the whenNotPaused modifier.