From 9d818a83eed84b3c070d7ee67beb1334d28b1900 Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Wed, 29 Jan 2025 18:10:46 -0500 Subject: [PATCH 1/6] Compose VaultTokenized and OZ Votes --- src/contracts/vault/VaultVotes.sol | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/contracts/vault/VaultVotes.sol diff --git a/src/contracts/vault/VaultVotes.sol b/src/contracts/vault/VaultVotes.sol new file mode 100644 index 00000000..b4ecb867 --- /dev/null +++ b/src/contracts/vault/VaultVotes.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {VotesUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/VotesUpgradeable.sol"; +import {VaultTokenized} from "./VaultTokenized.sol"; + +contract VaultVotes is VaultTokenized, VotesUpgradeable { + constructor( + address delegatorFactory, + address slasherFactory, + address vaultFactory + ) VaultTokenized(delegatorFactory, slasherFactory, vaultFactory) {} + + function _getVotingUnits( + address account + ) internal view virtual override returns (uint256) { + return balanceOf(account); + } + + error ERC20ExceededSafeSupply(uint256 increasedSupply, uint256 cap); + + function _maxSupply() internal view virtual returns (uint256) { + return type(uint208).max; + } + + function _update( + address from, + address to, + uint256 value + ) internal virtual override(VaultTokenized) { + VaultTokenized._update(from, to, value); + + // copied from ERC20Votes._update + if (from == address(0)) { + uint256 supply = totalSupply(); + uint256 cap = _maxSupply(); + if (supply > cap) { + revert ERC20ExceededSafeSupply(supply, cap); + } + } + _transferVotingUnits(from, to, value); + } +} From acb3b6cec1a3476e4c2872cdb3db3d5d1d053a5c Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Tue, 4 Feb 2025 14:06:29 -0500 Subject: [PATCH 2/6] Make _update virtual --- src/contracts/vault/VaultTokenized.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contracts/vault/VaultTokenized.sol b/src/contracts/vault/VaultTokenized.sol index e37b7539..579038d8 100644 --- a/src/contracts/vault/VaultTokenized.sol +++ b/src/contracts/vault/VaultTokenized.sol @@ -71,7 +71,7 @@ contract VaultTokenized is Vault, ERC20Upgradeable, IVaultTokenized { /** * @inheritdoc ERC20Upgradeable */ - function _update(address from, address to, uint256 value) internal override { + function _update(address from, address to, uint256 value) internal virtual override { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _activeShares.push(Time.timestamp(), totalSupply() + value); From 509dc13924553d4f8e737fa652a3555de013289d Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Tue, 4 Feb 2025 14:11:14 -0500 Subject: [PATCH 3/6] Use timestamp clock mode --- src/contracts/vault/VaultVotes.sol | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/contracts/vault/VaultVotes.sol b/src/contracts/vault/VaultVotes.sol index b4ecb867..fff41f3d 100644 --- a/src/contracts/vault/VaultVotes.sol +++ b/src/contracts/vault/VaultVotes.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.25; import {VotesUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/VotesUpgradeable.sol"; +import {Time} from "@openzeppelin/contracts/utils/types/Time.sol"; import {VaultTokenized} from "./VaultTokenized.sol"; contract VaultVotes is VaultTokenized, VotesUpgradeable { @@ -11,6 +12,14 @@ contract VaultVotes is VaultTokenized, VotesUpgradeable { address vaultFactory ) VaultTokenized(delegatorFactory, slasherFactory, vaultFactory) {} + function clock() public view override returns (uint48) { + return Time.timestamp(); + } + + function CLOCK_MODE() public view override returns (string memory) { + return "mode=timestamp"; + } + function _getVotingUnits( address account ) internal view virtual override returns (uint256) { From cc2645b1c11ac0d2300cf1bf81490ce4a8ed343c Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Tue, 4 Feb 2025 14:12:01 -0500 Subject: [PATCH 4/6] Format --- src/contracts/vault/VaultVotes.sol | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/contracts/vault/VaultVotes.sol b/src/contracts/vault/VaultVotes.sol index fff41f3d..df5b37ce 100644 --- a/src/contracts/vault/VaultVotes.sol +++ b/src/contracts/vault/VaultVotes.sol @@ -32,11 +32,7 @@ contract VaultVotes is VaultTokenized, VotesUpgradeable { return type(uint208).max; } - function _update( - address from, - address to, - uint256 value - ) internal virtual override(VaultTokenized) { + function _update(address from, address to, uint256 value) internal virtual override { VaultTokenized._update(from, to, value); // copied from ERC20Votes._update From e699aa5521b8be99f7f5f78796ca8801c8dd048a Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Tue, 4 Feb 2025 14:20:30 -0500 Subject: [PATCH 5/6] Fix compiler warning --- src/contracts/vault/VaultVotes.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contracts/vault/VaultVotes.sol b/src/contracts/vault/VaultVotes.sol index df5b37ce..7d1a269d 100644 --- a/src/contracts/vault/VaultVotes.sol +++ b/src/contracts/vault/VaultVotes.sol @@ -16,7 +16,7 @@ contract VaultVotes is VaultTokenized, VotesUpgradeable { return Time.timestamp(); } - function CLOCK_MODE() public view override returns (string memory) { + function CLOCK_MODE() public pure override returns (string memory) { return "mode=timestamp"; } From 72efe17e14d18c3b19a856e1817a7968b2f02888 Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Tue, 4 Feb 2025 14:22:23 -0500 Subject: [PATCH 6/6] Rename to VaultTokenizedVotes --- src/contracts/vault/{VaultVotes.sol => VaultTokenizedVotes.sol} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/contracts/vault/{VaultVotes.sol => VaultTokenizedVotes.sol} (95%) diff --git a/src/contracts/vault/VaultVotes.sol b/src/contracts/vault/VaultTokenizedVotes.sol similarity index 95% rename from src/contracts/vault/VaultVotes.sol rename to src/contracts/vault/VaultTokenizedVotes.sol index 7d1a269d..7b17eaba 100644 --- a/src/contracts/vault/VaultVotes.sol +++ b/src/contracts/vault/VaultTokenizedVotes.sol @@ -5,7 +5,7 @@ import {VotesUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts import {Time} from "@openzeppelin/contracts/utils/types/Time.sol"; import {VaultTokenized} from "./VaultTokenized.sol"; -contract VaultVotes is VaultTokenized, VotesUpgradeable { +contract VaultTokenizedVotes is VaultTokenized, VotesUpgradeable { constructor( address delegatorFactory, address slasherFactory,