zDAO-Token - Vested tokens revocation depends on claiming state
The owner of the `TokenVesting` contract can revoke the vesting of tokens for any beneficiary by calling `TokenVesting.revoke` only for tokens that have already been claimed using `MerkleTokenVesting.claimAward`. Although anyone can call `MerkleTokenVesting.claimAward` for a given beneficiary, in practice it is mostly the beneficiary's responsibility. This design decision, however, incentivizes the beneficiary to delay the call to `MerkleTokenVesting.claimAward` up to the point when he wishes to cash out, to avoid potential revocation. To revoke vesting tokens the owner will have to claim the award on the beneficiary's behalf first (which might be a gas burden), then call `TokenVesting.revoke`.\\n```\\nfunction revoke(address beneficiary) public onlyOwner {\\n  TokenAward storage award = getTokenAwardStorage(beneficiary);\\n\\n  require(award.revocable, "Cannot be revoked");\\n  require(!award.revoked, "Already revoked");\\n\\n  // Figure out how many tokens were owed up until revocation\\n  uint256 unreleased = getReleasableAmount(beneficiary);\\n  award.released += unreleased;\\n\\n  uint256 refund = award.amount - award.released;\\n\\n  // Mark award as revoked\\n  award.revoked = true;\\n  award.amount = award.released;\\n\\n  // Transfer owed vested tokens to beneficiary\\n  targetToken.safeTransfer(beneficiary, unreleased);\\n  // Transfer unvested tokens to owner (revoked amount)\\n  targetToken.safeTransfer(owner(), refund);\\n\\n  emit Released(beneficiary, unreleased);\\n  emit Revoked(beneficiary, refund);\\n}\\n```\\n
Make sure that the potential owner of a `TokenVesting` contract is aware of this potential issue, and has the required processes in place to handle it.
```\\nfunction revoke(address beneficiary) public onlyOwner {\\n  TokenAward storage award = getTokenAwardStorage(beneficiary);\\n\\n  require(award.revocable, "Cannot be revoked");\\n  require(!award.revoked, "Already revoked");\\n\\n  // Figure out how many tokens were owed up until revocation\\n  uint256 unreleased = getReleasableAmount(beneficiary);\\n  award.released += unreleased;\\n\\n  uint256 refund = award.amount - award.released;\\n\\n  // Mark award as revoked\\n  award.revoked = true;\\n  award.amount = award.released;\\n\\n  // Transfer owed vested tokens to beneficiary\\n  targetToken.safeTransfer(beneficiary, unreleased);\\n  // Transfer unvested tokens to owner (revoked amount)\\n  targetToken.safeTransfer(owner(), refund);\\n\\n  emit Released(beneficiary, unreleased);\\n  emit Revoked(beneficiary, refund);\\n}\\n```\\n