Calm Fiery Llama
Medium
Currently, a voucher can decide whether to mark a vouch as unhealthy, as long as the unhealthyResponsePeriod
has not expired since they unvouched. However, users may still be able to mark a vouch as unhealthy even after the unhealthyResponsePeriod
has already passed before, if the unhealthyResponsePeriod
is extended.
When it is checked whether the author still has time to mark a vouch as unhealthy, the current unhealthyResponsePeriod
is used instead of the one that was in effect when the user unvouched.
None.
None.
- Alice vouches for ProfileA.
- Alice calls
EthosVouch::unvouch()
to revoke her vouch because she has lost trust in the profile she previously vouched for. She can mark the vouch as unhealthy until theunhealthyResponsePeriod
(currently set to24 hours
) expires. - The
unhealthyResponsePeriod
expires. - Twelve hours later,
updateUnhealthyResponsePeriod()
is called to increase the unhealthy response period to48 hours
. - Now, Alice can call
EthosVouch::markUnhealthy()
, even though theunhealthyResponsePeriod
has already expired once.
Users will still be able to mark a vouch as unhealthy, even if the unhealthyResponsePeriod
at the time of unvouching has already expired. This means that even vouches that have been unvouched for several months could be marked as unhealthy if the unhealthyResponsePeriod
was extended long enough.
As a result, vouchers can mark a vouch as unhealthy, even if they did not distrust the subject when they unvouched it. This increases the risk of manipulation of the protocol's reputation system.
The following test should be added in EthosVouch.test.ts
:
it('should succeed marking vouch unhealthy when unhealthyResponsePeriod extended', async () => {
const {
ethosProfile,
ethosVouch,
ADMIN,
OWNER,
PROFILE_CREATOR_0,
VOUCHER_0,
} = await loadFixture(deployFixture);
await ethosProfile.connect(OWNER).inviteAddress(PROFILE_CREATOR_0.address);
await ethosProfile.connect(PROFILE_CREATOR_0).createProfile(1);
await ethosProfile.connect(OWNER).inviteAddress(VOUCHER_0.address);
await ethosProfile.connect(VOUCHER_0).createProfile(1);
expect(await ethosProfile.profileIdByAddress(PROFILE_CREATOR_0.address)).to.be.equal(
2,
'wrong profile Id',
);
await ethosVouch.connect(VOUCHER_0).vouchByProfileId(2, DEFAULT_COMMENT, DEFAULT_METADATA, {
value: ethers.parseEther('1.1'),
});
expect(await ethosVouch.vouchCount()).to.equal(1, 'Wrong vouchCount');
await ethosVouch.connect(ADMIN).updateUnhealthyResponsePeriod(86400);
expect(await ethosVouch.unhealthyResponsePeriod()).to.equal(
86400,
'Wrong unhealthyResponsePeriod, 0',
);
await ethosVouch.connect(VOUCHER_0).unvouch(0);
await time.increase(100);
await time.increase(await ethosVouch.unhealthyResponsePeriod());
await expect(ethosVouch.connect(VOUCHER_0).markUnhealthy(0))
.to.be.revertedWithCustomError(ethosVouch, 'CannotMarkVouchAsUnhealthy')
.withArgs(0);
await ethosVouch.connect(ADMIN).updateUnhealthyResponsePeriod(172800);
expect(await ethosVouch.unhealthyResponsePeriod()).to.equal(
172800,
'Wrong unhealthyResponsePeriod, 1',
);
await time.increase(43100);
await ethosVouch.connect(VOUCHER_0).markUnhealthy(0)
});
Only the unhealthyResponsePeriod
at the time a user unvouches should be considered when EthosVouch::markUnhealthy()
is called, so that once this period expires, the user will no longer be able to mark a vouch as unhealthy.