Skip to content

Latest commit

 

History

History
43 lines (38 loc) · 2.59 KB

File metadata and controls

43 lines (38 loc) · 2.59 KB

Overt Alabaster Cottonmouth

Medium

Author can escape slashing by front-running it and unvouching

Description & Impact

As soon as an author sees in the mempool that the slasher has chosen to call slash() on his profileId, they can front-run it and call unvouch() on all their vouches. This immediately returns all the balance to the author. The slash() function anyway doesn't consider archived vouches while slashing since they wouldn't have any balance:

  File: ethos/packages/contracts/contracts/EthosVouch.sol

   520:            function slash(
   521:              uint256 authorProfileId,
   522:              uint256 slashBasisPoints
   523:            ) external onlySlasher whenNotPaused nonReentrant returns (uint256) {
   524:              if (slashBasisPoints > MAX_SLASH_PERCENTAGE) {
   525:                revert InvalidSlashPercentage();
   526:              }
   527:          
   528:              uint256 totalSlashed;
   529:              uint256[] storage vouchIds = vouchIdsByAuthor[authorProfileId];
   530:          
   531:              for (uint256 i = 0; i < vouchIds.length; i++) {
   532:                Vouch storage vouch = vouches[vouchIds[i]];
   533:@--->           // Only slash active vouches
   534:@--->           if (!vouch.archived) {
   535:                  uint256 slashAmount = vouch.balance.mulDiv(
   536:                    slashBasisPoints,
   537:                    BASIS_POINT_SCALE,
   538:                    Math.Rounding.Floor
   539:                  );
   540:                  if (slashAmount > 0) {
   541:                    vouch.balance -= slashAmount;
   542:                    totalSlashed += slashAmount;
   543:                  }
   544:                }
   545:              }

This may effect the author's reputation but the immediate loss of ETH which would probably be of greater value, is avoided.

Mitigation

  • Thr protocol could consider adding a time delay between the call to unvouch() and funds being returned to the author. The author should be required to call a new function to pull these funds into their address once the time period has expired.
  • Then, the slash() logic can be modified to exclude only the vouches which are archived and have zero withdrawable funds in them. We may need to add another element in struct Vouch named uint256 fundsNotYetPulledByAuthor to track this.