From 2562c11f2566d7b027af18ad33d8153da65cbfd0 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Mon, 25 Nov 2024 18:43:21 +0100 Subject: [PATCH] Document VotesExtended assumptions (#5306) Co-authored-by: ernestognw --- contracts/governance/utils/VotesExtended.sol | 22 +++++++++++++++++++ ...ckpoints.test.js => VotesExtended.test.js} | 0 2 files changed, 22 insertions(+) rename test/governance/utils/{VotesAdditionalCheckpoints.test.js => VotesExtended.test.js} (100%) diff --git a/contracts/governance/utils/VotesExtended.sol b/contracts/governance/utils/VotesExtended.sol index 82e4624fb..b68ee2712 100644 --- a/contracts/governance/utils/VotesExtended.sol +++ b/contracts/governance/utils/VotesExtended.sol @@ -7,6 +7,28 @@ import {SafeCast} from "../../utils/math/SafeCast.sol"; /** * @dev Extension of {Votes} that adds checkpoints for delegations and balances. + * + * WARNING: While this contract extends {Votes}, valid uses of {Votes} may not be compatible with + * {VotesExtended} without additional considerations. This implementation of {_transferVotingUnits} must + * run AFTER the voting weight movement is registered, such that it is reflected on {_getVotingUnits}. + * + * Said differently, {VotesExtended} MUST be integrated in a way that calls {_transferVotingUnits} AFTER the + * asset transfer is registered and balances are updated: + * + * ```solidity + * contract VotingToken is Token, VotesExtended { + * function transfer(address from, address to, uint256 tokenId) public override { + * super.transfer(from, to, tokenId); // <- Perform the transfer first ... + * _transferVotingUnits(from, to, 1); // <- ... then call _transferVotingUnits. + * } + * + * function _getVotingUnits(address account) internal view override returns (uint256) { + * return balanceOf(account); + * } + * } + * ``` + * + * {ERC20Votes} and {ERC721Votes} follow this pattern and are thus safe to use with {VotesExtended}. */ abstract contract VotesExtended is Votes { using SafeCast for uint256; diff --git a/test/governance/utils/VotesAdditionalCheckpoints.test.js b/test/governance/utils/VotesExtended.test.js similarity index 100% rename from test/governance/utils/VotesAdditionalCheckpoints.test.js rename to test/governance/utils/VotesExtended.test.js