Skip to content

Latest commit

 

History

History
76 lines (51 loc) · 2.18 KB

File metadata and controls

76 lines (51 loc) · 2.18 KB

Loud Onyx Perch

Medium

buyVotes doesn't block 0 votes, allowing users to be added as participants without buying any votes

Summary

When buying votes, users get added to the participants list:

// Add buyer to participants if not already a participant
if (!isParticipant[profileId][msg.sender]) {
  participants[profileId].push(msg.sender);
  isParticipant[profileId][msg.sender] = true;
}

This indicates that the user holds some votes for that market. However, buyVotes doesn't block buying 0 votes, i.e. calling buyVotes without paying anything and without receiving anything in return.

This allows users to add themselves as participants for free.

Root Cause

buyVotes doesn't block buying 0 votes, https://github.com/sherlock-audit/2024-12-ethos-update/blob/main/ethos/packages/contracts/contracts/ReputationMarket.sol#L440-L497.

Internal Pre-conditions

No response

External Pre-conditions

No response

Attack Path

No response

Impact

Users can be added to the market's participants without having to buy any votes.

PoC

Add the following test in ethos/packages/contracts/test/reputationMarket/rep.fees.test.ts:

describe('PoC', () => {
    let user1: HardhatEthersSigner, user2: HardhatEthersSigner;

    beforeEach(async () => {
      user1 = ethosUserA.signer;
      user2 = await deployer.createUser().then(async (ethosUser) => {
        await ethosUser.setBalance('2000');

        return ethosUser.signer;
      });

      await reputationMarket.connect(deployer.ADMIN).setExitProtocolFeeBasisPoints(5_00);
      await reputationMarket.connect(deployer.ADMIN).setEntryProtocolFeeBasisPoints(5_00);
      await reputationMarket.connect(deployer.ADMIN).setDonationBasisPoints(5_00);
    });

    it('can be added as participant with 0 votes', async () => {
      // User 1 buys 0 votes
      await reputationMarket.connect(user1).buyVotes(DEFAULT.profileId, true, 0, 0);

      // User 1 is added as a participant
      expect(await reputationMarket.isParticipant(DEFAULT.profileId, user1.address)).to.be.equal(
        true,
      );
    });
});

Mitigation

Don't allow buying 0 votes, i.e. have a 0 validation in buyVotes.