Skip to content
This repository was archived by the owner on Aug 6, 2025. It is now read-only.

Timepoints, minting freeze, supply exclusion#76

Open
brickpop wants to merge 19 commits intomainfrom
f/supply-exclusion
Open

Timepoints, minting freeze, supply exclusion#76
brickpop wants to merge 19 commits intomainfrom
f/supply-exclusion

Conversation

@brickpop
Copy link

This PR adds support for:

  • Voting tokens indexed by timestamps
  • Permanently disabling the minting function
  • Excluding certain addresses from the voting calculations

@jordaniza jordaniza self-requested a review June 3, 2025 10:20

/// @notice Disables the mint() function permanently.
function freezeMinting() external auth(MINT_PERMISSION_ID) {
if (mintingFrozen) return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might consider reverting here

}
}
for (uint256 i; i < _excludedAccounts.length; ) {
excludedAccounts.push(_excludedAccounts[i]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't check for duplicates here. I do not think this causes issues but it would create redundancy.

}

function delegate(address account) public override {
for (uint256 i; i < excludedAccounts.length; i++) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One could use an EnumerableSet here to have O(1) lookups. This saves SLOADs on common operations like delegate/getPastVotes and transfers that gas cost to the initialization (once).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also do this for account to check one cannot delegate to an excluded account

/// @inheritdoc ERC20VotesUpgradeable
/// @dev This override extends the original implementation, ensuring that excluded addresses cannot use their voting power.
function getPastTotalSupply(uint256 timepoint) public view override returns (uint256) {
uint256 excludedSupply = super.getPastVotes(address(0), timepoint);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth considering if, given that we allow a user to specify an explicit list of excluded accounts, we should always include address(0).

I don't have a problem with this, it follows convention. But worth explaining somewhere at the very least that address 0 is always excluded.

for (uint256 i; i < excludedAccounts.length; ++i) {
/// @dev Using getPastVotes() even though these addresses cannot self delegate.
/// @dev Another account could transfer a delegated balance to them.
excludedSupply += super.getPastVotes(excludedAccounts[i], timepoint);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah so tradeoff here if you use enumerable set would be that 2 x O(1) SLOADs vs. the loop here.

Might have missed this but have you also factored excludedAccounts into totalSupply and not just getPastTotalSupply?

IVotesUpgradeable private votingToken;

/// @notice Wether the token contract indexes past voting power by timestamp.
bool private tokenIndexedByTimestamp;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to have a way to query this information with an external getter

string memory _name,
string memory _symbol,
MintSettings memory _mintSettings
MintSettings memory _mintSettings,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A common use case is fixed-supply-on-mint. You may wish to consider adding freeze to the mint function but not mandatory

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what this PR is aiming to do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would need to call freeze as a separate function after deploy.

Object.values(defaultTokenSettings),
Object.values(defaultMintSettings),
Object.values(defaultTargetConfig),
// // Provide installation inputs

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check: commented code

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants