From 6ec6f67686e0dab1ae3ed5181b39ad48625748d2 Mon Sep 17 00:00:00 2001 From: keating Date: Mon, 11 Aug 2025 10:19:46 -0400 Subject: [PATCH 01/19] Initial upgradeable --- .gitmodules | 3 + foundry.lock | 14 +++ lib/openzeppelin-contracts-upgradeable | 1 + src/Staker.sol | 151 ++++++++++++++----------- 4 files changed, 106 insertions(+), 63 deletions(-) create mode 100644 foundry.lock create mode 160000 lib/openzeppelin-contracts-upgradeable diff --git a/.gitmodules b/.gitmodules index 690924b6..9296efd5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/openzeppelin-contracts"] path = lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts +[submodule "lib/openzeppelin-contracts-upgradeable"] + path = lib/openzeppelin-contracts-upgradeable + url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable diff --git a/foundry.lock b/foundry.lock new file mode 100644 index 00000000..faa294c3 --- /dev/null +++ b/foundry.lock @@ -0,0 +1,14 @@ +{ + "lib/openzeppelin-contracts": { + "rev": "dbb6104ce834628e473d2173bbc9d47f81a9eec3" + }, + "lib/openzeppelin-contracts-upgradeable": { + "tag": { + "name": "v5.4.0", + "rev": "e725abddf1e01cf05ace496e950fc8e243cc7cab" + } + }, + "lib/forge-std": { + "rev": "1714bee72e286e73f76e320d110e0eaf5c4e649d" + } +} \ No newline at end of file diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable new file mode 160000 index 00000000..e725abdd --- /dev/null +++ b/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +Subproject commit e725abddf1e01cf05ace496e950fc8e243cc7cab diff --git a/src/Staker.sol b/src/Staker.sol index 8dc36531..a271940e 100644 --- a/src/Staker.sol +++ b/src/Staker.sol @@ -6,8 +6,9 @@ import {INotifiableRewardReceiver} from "./interfaces/INotifiableRewardReceiver. import {IEarningPowerCalculator} from "./interfaces/IEarningPowerCalculator.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {Multicall} from "@openzeppelin/contracts/utils/Multicall.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {MulticallUpgradeable} from + "@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol"; /// @title Staker /// @author [ScopeLift](https://scopelift.co) @@ -34,7 +35,7 @@ import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; /// the Staker contract is a DAO, which is the expected common case, this means the DAO has /// the ability to define and iterate on its own definition of active, aligned participation, /// and to decide how to reward it. -abstract contract Staker is INotifiableRewardReceiver, Multicall { +abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { using SafeCast for uint256; /// @notice A unique identifier assigned to each deposit. @@ -188,11 +189,57 @@ abstract contract Staker is INotifiableRewardReceiver, Multicall { address feeCollector; } - /// @notice ERC20 token in which rewards are denominated and distributed. - IERC20 public immutable REWARD_TOKEN; - - /// @notice Delegable governance token which users stake to earn rewards. - IERC20 public immutable STAKE_TOKEN; + struct StakerStorage { + /// @notice ERC20 token in which rewards are denominated and distributed. + IERC20 _rewardToken; + /// @notice Delegable governance token which users stake to earn rewards. + IERC20 _stakeToken; + /// @notice The maximum value to which the claim fee can be set. + /// @dev For anything other than a zero value, this immutable parameter should be set in the + /// constructor of a concrete implementation inheriting from Staker. + uint256 _maxClaimFee; + /// @dev Unique identifier that will be used for the next deposit. + DepositIdentifier _nextDepositId; + /// @notice Permissioned actor that can enable/disable `rewardNotifier` addresses, set the max + /// bump tip, set the claim fee parameters, and update the earning power calculator. + address _admin; + /// @notice Maximum tip a bumper can request. + uint256 _maxBumpTip; + /// @notice Global amount currently staked across all deposits. + uint256 _totalStaked; + /// @notice Global amount of earning power for all deposits. + uint256 _totalEarningPower; + /// @notice Contract that determines a deposit's earning power based on their delegatee. + /// @dev An earning power calculator should take into account that a deposit's earning power is + /// a + /// uint96. There may be overflow issues within governance staker if this is not taken into + /// account. Also, there should be some mechanism to prevent the deposit from frequently being + /// bumpable: if earning power changes frequently, this will eat into a users unclaimed rewards. + IEarningPowerCalculator _earningPowerCalculator; + /// @notice Tracks the total staked by a depositor across all unique deposits. + mapping(address depositor => uint256 amount) _depositorTotalStaked; + /// @notice Tracks the total earning power by a depositor across all unique deposits. + mapping(address depositor => uint256 earningPower) _depositorTotalEarningPower; + /// @notice Stores the metadata associated with a given deposit. + mapping(DepositIdentifier depositId => Deposit deposit) _deposits; + /// @notice Time at which rewards distribution will complete if there are no new rewards. + uint256 _rewardEndTime; + /// @notice Last time at which the global rewards accumulator was updated. + uint256 _lastCheckpointTime; + /// @notice Global rate at which rewards are currently being distributed to stakers, + /// denominated in scaled reward tokens per second, using the SCALE_FACTOR. + uint256 _scaledRewardRate; + /// @notice Checkpoint value of the global reward per token accumulator. + uint256 _rewardPerTokenAccumulatedCheckpoint; + /// @notice Maps addresses to whether they are authorized to call `notifyRewardAmount`. + mapping(address rewardNotifier => bool) _isRewardNotifier; + /// @notice Current configuration parameters for the fee assessed on claiming. + ClaimFeeParameters _claimFeeParameters; + } + // keccak256(abi.encode(uint256(keccak256("storage.Staker")) - 1)) &~bytes32(uint256(0xff)) + + bytes32 private constant STAKER_STORAGE_LOCATION = + 0x587a86d9af0b7e1804e53a546ebb2307f72c0e29a89678476433276515d51100; /// @notice Length of time over which rewards sent to this contract are distributed to stakers. uint256 public constant REWARD_DURATION = 30 days; @@ -201,62 +248,6 @@ abstract contract Staker is INotifiableRewardReceiver, Multicall { /// truncation during division. uint256 public constant SCALE_FACTOR = 1e36; - /// @notice The maximum value to which the claim fee can be set. - /// @dev For anything other than a zero value, this immutable parameter should be set in the - /// constructor of a concrete implementation inheriting from Staker. - uint256 public immutable MAX_CLAIM_FEE; - - /// @dev Unique identifier that will be used for the next deposit. - DepositIdentifier private nextDepositId; - - /// @notice Permissioned actor that can enable/disable `rewardNotifier` addresses, set the max - /// bump tip, set the claim fee parameters, and update the earning power calculator. - address public admin; - - /// @notice Maximum tip a bumper can request. - uint256 public maxBumpTip; - - /// @notice Global amount currently staked across all deposits. - uint256 public totalStaked; - - /// @notice Global amount of earning power for all deposits. - uint256 public totalEarningPower; - - /// @notice Contract that determines a deposit's earning power based on their delegatee. - /// @dev An earning power calculator should take into account that a deposit's earning power is a - /// uint96. There may be overflow issues within governance staker if this is not taken into - /// account. Also, there should be some mechanism to prevent the deposit from frequently being - /// bumpable: if earning power changes frequently, this will eat into a users unclaimed rewards. - IEarningPowerCalculator public earningPowerCalculator; - - /// @notice Tracks the total staked by a depositor across all unique deposits. - mapping(address depositor => uint256 amount) public depositorTotalStaked; - - /// @notice Tracks the total earning power by a depositor across all unique deposits. - mapping(address depositor => uint256 earningPower) public depositorTotalEarningPower; - - /// @notice Stores the metadata associated with a given deposit. - mapping(DepositIdentifier depositId => Deposit deposit) public deposits; - - /// @notice Time at which rewards distribution will complete if there are no new rewards. - uint256 public rewardEndTime; - - /// @notice Last time at which the global rewards accumulator was updated. - uint256 public lastCheckpointTime; - - /// @notice Global rate at which rewards are currently being distributed to stakers, - /// denominated in scaled reward tokens per second, using the SCALE_FACTOR. - uint256 public scaledRewardRate; - - /// @notice Checkpoint value of the global reward per token accumulator. - uint256 public rewardPerTokenAccumulatedCheckpoint; - - /// @notice Maps addresses to whether they are authorized to call `notifyRewardAmount`. - mapping(address rewardNotifier => bool) public isRewardNotifier; - - /// @notice Current configuration parameters for the fee assessed on claiming. - ClaimFeeParameters public claimFeeParameters; - /// @param _rewardToken ERC20 token in which rewards will be denominated. /// @param _stakeToken Delegable governance token which users will stake to earn rewards. /// @param _earningPowerCalculator The contract that will serve as the initial calculator of @@ -277,6 +268,40 @@ abstract contract Staker is INotifiableRewardReceiver, Multicall { _setEarningPowerCalculator(address(_earningPowerCalculator)); } + function _getStakerStorage() private pure returns (StakerStorage storage $) { + assembly { + $.slot := STAKER_STORAGE_LOCATION + } + } + + function __Staker_init( + IERC20 _rewardToken, + IERC20 _stakeToken, + uint256 _maxClaimFee, + address _admin, + uint256 _maxBumpTip, + IEarningPowerCalculator _earningPowerCalculator + ) internal onlyInitializing { + __Staker_init_unchained(_rewardToken, _stakeToken); + } + + function __Staker_init_unchained( + IERC20 _rewardToken, + IERC20 _stakeToken, + uint256 _maxClaimFee, + address _admin, + uint256 _maxBumpTip, + IEarningPowerCalculator _earningPowerCalculator + ) internal onlyInitializing { + StakerStorage storage $ = _getStakerStorage(); + $._rewardToken = IERC20(address(_rewardToken)); + $._stakeToken = IERC20(address(_stakeToken)); + $._maxClaimFee = _maxClaimFee; + _setAdmin(_admin); + _setMaxBumpTip(_maxBumpTip); + _setEarningPowerCalculator(address(_earningPowerCalculator)); + } + /// @notice Set the admin address. /// @param _newAdmin Address of the new admin. /// @dev Caller must be the current admin. From 327efc850e5691dbf7dbdddbe1e5c24566fd9fd7 Mon Sep 17 00:00:00 2001 From: keating Date: Mon, 11 Aug 2025 11:00:36 -0400 Subject: [PATCH 02/19] Changes --- src/Staker.sol | 322 +++++++++++++----- src/extensions/StakerCapDeposits.sol | 35 +- .../StakerDelegateSurrogateVotes.sol | 51 ++- 3 files changed, 302 insertions(+), 106 deletions(-) diff --git a/src/Staker.sol b/src/Staker.sol index a271940e..edefebcb 100644 --- a/src/Staker.sol +++ b/src/Staker.sol @@ -237,7 +237,6 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { ClaimFeeParameters _claimFeeParameters; } // keccak256(abi.encode(uint256(keccak256("storage.Staker")) - 1)) &~bytes32(uint256(0xff)) - bytes32 private constant STAKER_STORAGE_LOCATION = 0x587a86d9af0b7e1804e53a546ebb2307f72c0e29a89678476433276515d51100; @@ -261,8 +260,9 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { uint256 _maxBumpTip, address _admin ) { - REWARD_TOKEN = _rewardToken; - STAKE_TOKEN = _stakeToken; + StakerStorage storage $ = _getStakerStorage(); + $._rewardToken = _rewardToken; + $._stakeToken = _stakeToken; _setAdmin(_admin); _setMaxBumpTip(_maxBumpTip); _setEarningPowerCalculator(address(_earningPowerCalculator)); @@ -282,7 +282,7 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { uint256 _maxBumpTip, IEarningPowerCalculator _earningPowerCalculator ) internal onlyInitializing { - __Staker_init_unchained(_rewardToken, _stakeToken); + __Staker_init_unchained(_rewardToken, _stakeToken, _maxClaimFee, _admin, _maxBumpTip, _earningPowerCalculator); } function __Staker_init_unchained( @@ -330,7 +330,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @dev Caller must be the current admin. function setRewardNotifier(address _rewardNotifier, bool _isEnabled) external virtual { _revertIfNotAdmin(); - isRewardNotifier[_rewardNotifier] = _isEnabled; + StakerStorage storage $ = _getStakerStorage(); + $._isRewardNotifier[_rewardNotifier] = _isEnabled; emit RewardNotifierSet(_rewardNotifier, _isEnabled); } @@ -355,7 +356,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// at which the reward duration ended (because all rewards to date have already been streamed). /// @return Timestamp representing the last time at which rewards have been distributed. function lastTimeRewardDistributed() public view virtual returns (uint256) { - if (rewardEndTime <= block.timestamp) return rewardEndTime; + StakerStorage storage $ = _getStakerStorage(); + if ($._rewardEndTime <= block.timestamp) return $._rewardEndTime; else return block.timestamp; } @@ -364,10 +366,11 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// This number should monotonically increase over time as more rewards are distributed. /// @return Live value of the global reward per token accumulator. function rewardPerTokenAccumulated() public view virtual returns (uint256) { - if (totalEarningPower == 0) return rewardPerTokenAccumulatedCheckpoint; + StakerStorage storage $ = _getStakerStorage(); + if ($._totalEarningPower == 0) return $._rewardPerTokenAccumulatedCheckpoint; - return rewardPerTokenAccumulatedCheckpoint - + (scaledRewardRate * (lastTimeRewardDistributed() - lastCheckpointTime)) / totalEarningPower; + return $._rewardPerTokenAccumulatedCheckpoint + + ($._scaledRewardRate * (lastTimeRewardDistributed() - $._lastCheckpointTime)) / $._totalEarningPower; } /// @notice Live value of the unclaimed rewards earned by a given deposit. It is the @@ -382,7 +385,118 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @param _depositId Identifier of the deposit in question. /// @return Live value of the unclaimed rewards earned by a given deposit. function unclaimedReward(DepositIdentifier _depositId) external view virtual returns (uint256) { - return _scaledUnclaimedReward(deposits[_depositId]) / SCALE_FACTOR; + StakerStorage storage $ = _getStakerStorage(); + return _scaledUnclaimedReward($._deposits[_depositId]) / SCALE_FACTOR; + } + + // Public getter functions for storage variables + + /// @notice ERC20 token in which rewards are denominated and distributed. + function REWARD_TOKEN() public view virtual returns (IERC20) { + StakerStorage storage $ = _getStakerStorage(); + return $._rewardToken; + } + + /// @notice Delegable governance token which users stake to earn rewards. + function STAKE_TOKEN() public view virtual returns (IERC20) { + StakerStorage storage $ = _getStakerStorage(); + return $._stakeToken; + } + + /// @notice The maximum value to which the claim fee can be set. + function MAX_CLAIM_FEE() public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._maxClaimFee; + } + + /// @notice Permissioned actor that can enable/disable `rewardNotifier` addresses. + function admin() public view virtual returns (address) { + StakerStorage storage $ = _getStakerStorage(); + return $._admin; + } + + /// @notice Maximum tip a bumper can request. + function maxBumpTip() public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._maxBumpTip; + } + + /// @notice Global amount currently staked across all deposits. + function totalStaked() public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._totalStaked; + } + + /// @notice Global amount of earning power for all deposits. + function totalEarningPower() public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._totalEarningPower; + } + + /// @notice Contract that determines a deposit's earning power based on their delegatee. + function earningPowerCalculator() public view virtual returns (IEarningPowerCalculator) { + StakerStorage storage $ = _getStakerStorage(); + return $._earningPowerCalculator; + } + + /// @notice Tracks the total staked by a depositor across all unique deposits. + function depositorTotalStaked(address depositor) public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._depositorTotalStaked[depositor]; + } + + /// @notice Tracks the total earning power by a depositor across all unique deposits. + function depositorTotalEarningPower(address depositor) public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._depositorTotalEarningPower[depositor]; + } + + /// @notice Stores the metadata associated with a given deposit. + function deposits(DepositIdentifier depositId) public view virtual returns (Deposit memory) { + StakerStorage storage $ = _getStakerStorage(); + return $._deposits[depositId]; + } + + /// @notice Time at which rewards distribution will complete if there are no new rewards. + function rewardEndTime() public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._rewardEndTime; + } + + /// @notice Last time at which the global rewards accumulator was updated. + function lastCheckpointTime() public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._lastCheckpointTime; + } + + /// @notice Global rate at which rewards are currently being distributed to stakers. + function scaledRewardRate() public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._scaledRewardRate; + } + + /// @notice Checkpoint value of the global reward per token accumulator. + function rewardPerTokenAccumulatedCheckpoint() public view virtual returns (uint256) { + StakerStorage storage $ = _getStakerStorage(); + return $._rewardPerTokenAccumulatedCheckpoint; + } + + /// @notice Maps addresses to whether they are authorized to call `notifyRewardAmount`. + function isRewardNotifier(address rewardNotifier) public view virtual returns (bool) { + StakerStorage storage $ = _getStakerStorage(); + return $._isRewardNotifier[rewardNotifier]; + } + + /// @notice Current configuration parameters for the fee assessed on claiming. + function claimFeeParameters() public view virtual returns (ClaimFeeParameters memory) { + StakerStorage storage $ = _getStakerStorage(); + return $._claimFeeParameters; + } + + /// @notice Unique identifier that will be used for the next deposit. + function nextDepositId() public view virtual returns (DepositIdentifier) { + StakerStorage storage $ = _getStakerStorage(); + return $._nextDepositId; } /// @notice Stake tokens to a new deposit. The caller must pre-approve the staking contract to @@ -423,7 +537,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @param _amount Quantity of stake to be added. /// @dev The message sender must be the owner of the deposit. function stakeMore(DepositIdentifier _depositId, uint256 _amount) external virtual { - Deposit storage deposit = deposits[_depositId]; + StakerStorage storage $ = _getStakerStorage(); + Deposit storage deposit = $._deposits[_depositId]; _revertIfNotDepositOwner(deposit, msg.sender); _stakeMore(deposit, _depositId, _amount); } @@ -435,7 +550,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @dev The new delegatee may not be the zero address. The message sender must be the owner of /// the deposit. function alterDelegatee(DepositIdentifier _depositId, address _newDelegatee) external virtual { - Deposit storage deposit = deposits[_depositId]; + StakerStorage storage $ = _getStakerStorage(); + Deposit storage deposit = $._deposits[_depositId]; _revertIfNotDepositOwner(deposit, msg.sender); _alterDelegatee(deposit, _depositId, _newDelegatee); } @@ -447,7 +563,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @dev The new claimer may not be the zero address. The message sender must be the owner of /// the deposit. function alterClaimer(DepositIdentifier _depositId, address _newClaimer) external virtual { - Deposit storage deposit = deposits[_depositId]; + StakerStorage storage $ = _getStakerStorage(); + Deposit storage deposit = $._deposits[_depositId]; _revertIfNotDepositOwner(deposit, msg.sender); _alterClaimer(deposit, _depositId, _newClaimer); } @@ -458,7 +575,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @dev The message sender must be the owner of the deposit. Stake is withdrawn to the message /// sender's account. function withdraw(DepositIdentifier _depositId, uint256 _amount) external virtual { - Deposit storage deposit = deposits[_depositId]; + StakerStorage storage $ = _getStakerStorage(); + Deposit storage deposit = $._deposits[_depositId]; _revertIfNotDepositOwner(deposit, msg.sender); _withdraw(deposit, _depositId, _amount); } @@ -468,7 +586,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @param _depositId Identifier of the deposit from which accrued rewards will be claimed. /// @return Amount of reward tokens claimed, after the fee has been assessed. function claimReward(DepositIdentifier _depositId) external virtual returns (uint256) { - Deposit storage deposit = deposits[_depositId]; + StakerStorage storage $ = _getStakerStorage(); + Deposit storage deposit = $._deposits[_depositId]; if (deposit.claimer != msg.sender && deposit.owner != msg.sender) { revert Staker__Unauthorized("not claimer or owner", msg.sender); } @@ -491,23 +610,24 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// required that a notifier contract always transfers the `_amount` to this contract before /// calling this method. function notifyRewardAmount(uint256 _amount) external virtual { - if (!isRewardNotifier[msg.sender]) revert Staker__Unauthorized("not notifier", msg.sender); + StakerStorage storage $ = _getStakerStorage(); + if (!$._isRewardNotifier[msg.sender]) revert Staker__Unauthorized("not notifier", msg.sender); // We checkpoint the accumulator without updating the timestamp at which it was updated, // because that second operation will be done after updating the reward rate. - rewardPerTokenAccumulatedCheckpoint = rewardPerTokenAccumulated(); + $._rewardPerTokenAccumulatedCheckpoint = rewardPerTokenAccumulated(); - if (block.timestamp >= rewardEndTime) { - scaledRewardRate = (_amount * SCALE_FACTOR) / REWARD_DURATION; + if (block.timestamp >= $._rewardEndTime) { + $._scaledRewardRate = (_amount * SCALE_FACTOR) / REWARD_DURATION; } else { - uint256 _remainingReward = scaledRewardRate * (rewardEndTime - block.timestamp); - scaledRewardRate = (_remainingReward + _amount * SCALE_FACTOR) / REWARD_DURATION; + uint256 _remainingReward = $._scaledRewardRate * ($._rewardEndTime - block.timestamp); + $._scaledRewardRate = (_remainingReward + _amount * SCALE_FACTOR) / REWARD_DURATION; } - rewardEndTime = block.timestamp + REWARD_DURATION; - lastCheckpointTime = block.timestamp; + $._rewardEndTime = block.timestamp + REWARD_DURATION; + $._lastCheckpointTime = block.timestamp; - if ((scaledRewardRate / SCALE_FACTOR) == 0) revert Staker__InvalidRewardRate(); + if (($._scaledRewardRate / SCALE_FACTOR) == 0) revert Staker__InvalidRewardRate(); // This check cannot _guarantee_ sufficient rewards have been transferred to the contract, // because it cannot isolate the unclaimed rewards owed to stakers left in the balance. While @@ -515,7 +635,7 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { // critical that only safe reward notifier contracts are approved to call this method by the // admin. if ( - (scaledRewardRate * REWARD_DURATION) > (REWARD_TOKEN.balanceOf(address(this)) * SCALE_FACTOR) + ($._scaledRewardRate * REWARD_DURATION) > ($._rewardToken.balanceOf(address(this)) * SCALE_FACTOR) ) revert Staker__InsufficientRewardBalance(); emit RewardNotified(_amount, msg.sender); @@ -534,16 +654,17 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { address _tipReceiver, uint256 _requestedTip ) external virtual { - if (_requestedTip > maxBumpTip) revert Staker__InvalidTip(); + StakerStorage storage $ = _getStakerStorage(); + if (_requestedTip > $._maxBumpTip) revert Staker__InvalidTip(); - Deposit storage deposit = deposits[_depositId]; + Deposit storage deposit = $._deposits[_depositId]; _checkpointGlobalReward(); _checkpointReward(deposit); uint256 _unclaimedRewards = deposit.scaledUnclaimedRewardCheckpoint / SCALE_FACTOR; - (uint256 _newEarningPower, bool _isQualifiedForBump) = earningPowerCalculator.getNewEarningPower( + (uint256 _newEarningPower, bool _isQualifiedForBump) = $._earningPowerCalculator.getNewEarningPower( deposit.balance, deposit.owner, deposit.delegatee, deposit.earningPower ); if (!_isQualifiedForBump || _newEarningPower == deposit.earningPower) { @@ -555,7 +676,7 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { } // Note: underflow causes a revert if the requested tip is more than unclaimed rewards - if (_newEarningPower < deposit.earningPower && (_unclaimedRewards - _requestedTip) < maxBumpTip) + if (_newEarningPower < deposit.earningPower && (_unclaimedRewards - _requestedTip) < $._maxBumpTip) { revert Staker__InsufficientUnclaimedRewards(); } @@ -565,15 +686,15 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { ); // Update global earning power & deposit earning power based on this bump - totalEarningPower = - _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, totalEarningPower); - depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( - deposit.earningPower, _newEarningPower, depositorTotalEarningPower[deposit.owner] + $._totalEarningPower = + _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, $._totalEarningPower); + $._depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( + deposit.earningPower, _newEarningPower, $._depositorTotalEarningPower[deposit.owner] ); deposit.earningPower = _newEarningPower.toUint96(); // Send tip to the receiver - SafeERC20.safeTransfer(REWARD_TOKEN, _tipReceiver, _requestedTip); + SafeERC20.safeTransfer($._rewardToken, _tipReceiver, _requestedTip); deposit.scaledUnclaimedRewardCheckpoint = deposit.scaledUnclaimedRewardCheckpoint - (_requestedTip * SCALE_FACTOR); } @@ -606,15 +727,17 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @param _to Destination account of the stake token which is to be transferred. /// @param _value Quantity of stake token which is to be transferred. function _stakeTokenSafeTransferFrom(address _from, address _to, uint256 _value) internal virtual { - SafeERC20.safeTransferFrom(STAKE_TOKEN, _from, _to, _value); + StakerStorage storage $ = _getStakerStorage(); + SafeERC20.safeTransferFrom($._stakeToken, _from, _to, _value); } /// @notice Internal method which generates and returns a unique, previously unused deposit /// identifier. /// @return _depositId Previously unused deposit identifier. function _useDepositId() internal virtual returns (DepositIdentifier _depositId) { - _depositId = nextDepositId; - nextDepositId = DepositIdentifier.wrap(DepositIdentifier.unwrap(_depositId) + 1); + StakerStorage storage $ = _getStakerStorage(); + _depositId = $._nextDepositId; + $._nextDepositId = DepositIdentifier.wrap(DepositIdentifier.unwrap(_depositId) + 1); } /// @notice Internal convenience methods which performs the staking operations. @@ -633,19 +756,20 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { DelegationSurrogate _surrogate = _fetchOrDeploySurrogate(_delegatee); _depositId = _useDepositId(); - uint256 _earningPower = earningPowerCalculator.getEarningPower(_amount, _depositor, _delegatee); + StakerStorage storage $ = _getStakerStorage(); + uint256 _earningPower = $._earningPowerCalculator.getEarningPower(_amount, _depositor, _delegatee); - totalStaked += _amount; - totalEarningPower += _earningPower; - depositorTotalStaked[_depositor] += _amount; - depositorTotalEarningPower[_depositor] += _earningPower; - deposits[_depositId] = Deposit({ + $._totalStaked += _amount; + $._totalEarningPower += _earningPower; + $._depositorTotalStaked[_depositor] += _amount; + $._depositorTotalEarningPower[_depositor] += _earningPower; + $._deposits[_depositId] = Deposit({ balance: _amount.toUint96(), owner: _depositor, delegatee: _delegatee, claimer: _claimer, earningPower: _earningPower.toUint96(), - rewardPerTokenCheckpoint: rewardPerTokenAccumulatedCheckpoint, + rewardPerTokenCheckpoint: $._rewardPerTokenAccumulatedCheckpoint, scaledUnclaimedRewardCheckpoint: 0 }); _stakeTokenSafeTransferFrom(_depositor, address(_surrogate), _amount); @@ -666,16 +790,17 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { DelegationSurrogate _surrogate = surrogates(deposit.delegatee); + StakerStorage storage $ = _getStakerStorage(); uint256 _newBalance = deposit.balance + _amount; uint256 _newEarningPower = - earningPowerCalculator.getEarningPower(_newBalance, deposit.owner, deposit.delegatee); - - totalEarningPower = - _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, totalEarningPower); - totalStaked += _amount; - depositorTotalStaked[deposit.owner] += _amount; - depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( - deposit.earningPower, _newEarningPower, depositorTotalEarningPower[deposit.owner] + $._earningPowerCalculator.getEarningPower(_newBalance, deposit.owner, deposit.delegatee); + + $._totalEarningPower = + _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, $._totalEarningPower); + $._totalStaked += _amount; + $._depositorTotalStaked[deposit.owner] += _amount; + $._depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( + deposit.earningPower, _newEarningPower, $._depositorTotalEarningPower[deposit.owner] ); deposit.earningPower = _newEarningPower.toUint96(); deposit.balance = _newBalance.toUint96(); @@ -695,14 +820,15 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { _checkpointGlobalReward(); _checkpointReward(deposit); + StakerStorage storage $ = _getStakerStorage(); DelegationSurrogate _oldSurrogate = surrogates(deposit.delegatee); uint256 _newEarningPower = - earningPowerCalculator.getEarningPower(deposit.balance, deposit.owner, _newDelegatee); + $._earningPowerCalculator.getEarningPower(deposit.balance, deposit.owner, _newDelegatee); - totalEarningPower = - _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, totalEarningPower); - depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( - deposit.earningPower, _newEarningPower, depositorTotalEarningPower[deposit.owner] + $._totalEarningPower = + _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, $._totalEarningPower); + $._depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( + deposit.earningPower, _newEarningPower, $._depositorTotalEarningPower[deposit.owner] ); emit DelegateeAltered(_depositId, deposit.delegatee, _newDelegatee, _newEarningPower); @@ -723,14 +849,15 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { _checkpointGlobalReward(); _checkpointReward(deposit); + StakerStorage storage $ = _getStakerStorage(); // Updating the earning power here is not strictly necessary, but if the user is touching their // deposit anyway, it seems reasonable to make sure their earning power is up to date. uint256 _newEarningPower = - earningPowerCalculator.getEarningPower(deposit.balance, deposit.owner, deposit.delegatee); - totalEarningPower = - _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, totalEarningPower); - depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( - deposit.earningPower, _newEarningPower, depositorTotalEarningPower[deposit.owner] + $._earningPowerCalculator.getEarningPower(deposit.balance, deposit.owner, deposit.delegatee); + $._totalEarningPower = + _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, $._totalEarningPower); + $._depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( + deposit.earningPower, _newEarningPower, $._depositorTotalEarningPower[deposit.owner] ); deposit.earningPower = _newEarningPower.toUint96(); @@ -749,17 +876,18 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { _checkpointGlobalReward(); _checkpointReward(deposit); + StakerStorage storage $ = _getStakerStorage(); // overflow prevents withdrawing more than balance uint256 _newBalance = deposit.balance - _amount; uint256 _newEarningPower = - earningPowerCalculator.getEarningPower(_newBalance, deposit.owner, deposit.delegatee); - - totalStaked -= _amount; - totalEarningPower = - _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, totalEarningPower); - depositorTotalStaked[deposit.owner] -= _amount; - depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( - deposit.earningPower, _newEarningPower, depositorTotalEarningPower[deposit.owner] + $._earningPowerCalculator.getEarningPower(_newBalance, deposit.owner, deposit.delegatee); + + $._totalStaked -= _amount; + $._totalEarningPower = + _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, $._totalEarningPower); + $._depositorTotalStaked[deposit.owner] -= _amount; + $._depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( + deposit.earningPower, _newEarningPower, $._depositorTotalEarningPower[deposit.owner] ); deposit.balance = _newBalance.toUint96(); @@ -780,9 +908,10 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { _checkpointGlobalReward(); _checkpointReward(deposit); + StakerStorage storage $ = _getStakerStorage(); uint256 _reward = deposit.scaledUnclaimedRewardCheckpoint / SCALE_FACTOR; // Intentionally reverts due to overflow if unclaimed rewards are less than fee. - uint256 _payout = _reward - claimFeeParameters.feeAmount; + uint256 _payout = _reward - $._claimFeeParameters.feeAmount; if (_payout == 0) return 0; // retain sub-wei dust that would be left due to the precision loss @@ -790,21 +919,21 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { deposit.scaledUnclaimedRewardCheckpoint - (_reward * SCALE_FACTOR); uint256 _newEarningPower = - earningPowerCalculator.getEarningPower(deposit.balance, deposit.owner, deposit.delegatee); + $._earningPowerCalculator.getEarningPower(deposit.balance, deposit.owner, deposit.delegatee); emit RewardClaimed(_depositId, _claimer, _payout, _newEarningPower); - totalEarningPower = - _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, totalEarningPower); - depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( - deposit.earningPower, _newEarningPower, depositorTotalEarningPower[deposit.owner] + $._totalEarningPower = + _calculateTotalEarningPower(deposit.earningPower, _newEarningPower, $._totalEarningPower); + $._depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower( + deposit.earningPower, _newEarningPower, $._depositorTotalEarningPower[deposit.owner] ); deposit.earningPower = _newEarningPower.toUint96(); - SafeERC20.safeTransfer(REWARD_TOKEN, _claimer, _payout); - if (claimFeeParameters.feeAmount > 0) { + SafeERC20.safeTransfer($._rewardToken, _claimer, _payout); + if ($._claimFeeParameters.feeAmount > 0) { SafeERC20.safeTransfer( - REWARD_TOKEN, claimFeeParameters.feeCollector, claimFeeParameters.feeAmount + $._rewardToken, $._claimFeeParameters.feeCollector, $._claimFeeParameters.feeAmount ); } return _payout; @@ -812,8 +941,9 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @notice Checkpoints the global reward per token accumulator. function _checkpointGlobalReward() internal virtual { - rewardPerTokenAccumulatedCheckpoint = rewardPerTokenAccumulated(); - lastCheckpointTime = lastTimeRewardDistributed(); + StakerStorage storage $ = _getStakerStorage(); + $._rewardPerTokenAccumulatedCheckpoint = rewardPerTokenAccumulated(); + $._lastCheckpointTime = lastTimeRewardDistributed(); } /// @notice Checkpoints the unclaimed rewards and reward per token accumulator of a given @@ -823,8 +953,9 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// accumulator has been checkpointed. It assumes the global `rewardPerTokenCheckpoint` is up to /// date. function _checkpointReward(Deposit storage deposit) internal virtual { + StakerStorage storage $ = _getStakerStorage(); deposit.scaledUnclaimedRewardCheckpoint = _scaledUnclaimedReward(deposit); - deposit.rewardPerTokenCheckpoint = rewardPerTokenAccumulatedCheckpoint; + deposit.rewardPerTokenCheckpoint = $._rewardPerTokenAccumulatedCheckpoint; } /// @notice Internal helper method which calculates and returns an updated value for total @@ -843,47 +974,52 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @notice Internal helper method which sets the admin address. /// @param _newAdmin Address of the new admin. function _setAdmin(address _newAdmin) internal virtual { + StakerStorage storage $ = _getStakerStorage(); _revertIfAddressZero(_newAdmin); - emit AdminSet(admin, _newAdmin); - admin = _newAdmin; + emit AdminSet($._admin, _newAdmin); + $._admin = _newAdmin; } /// @notice Internal helper method which sets the earning power calculator address. function _setEarningPowerCalculator(address _newEarningPowerCalculator) internal virtual { + StakerStorage storage $ = _getStakerStorage(); _revertIfAddressZero(_newEarningPowerCalculator); - emit EarningPowerCalculatorSet(address(earningPowerCalculator), _newEarningPowerCalculator); - earningPowerCalculator = IEarningPowerCalculator(_newEarningPowerCalculator); + emit EarningPowerCalculatorSet(address($._earningPowerCalculator), _newEarningPowerCalculator); + $._earningPowerCalculator = IEarningPowerCalculator(_newEarningPowerCalculator); } /// @notice Internal helper method which sets the max bump tip. /// @param _newMaxTip Value of the new max bump tip. function _setMaxBumpTip(uint256 _newMaxTip) internal virtual { - emit MaxBumpTipSet(maxBumpTip, _newMaxTip); - maxBumpTip = _newMaxTip; + StakerStorage storage $ = _getStakerStorage(); + emit MaxBumpTipSet($._maxBumpTip, _newMaxTip); + $._maxBumpTip = _newMaxTip; } /// @notice Internal helper method which sets the claim fee parameters. /// @param _params The new fee parameters. function _setClaimFeeParameters(ClaimFeeParameters memory _params) internal virtual { + StakerStorage storage $ = _getStakerStorage(); if ( - _params.feeAmount > MAX_CLAIM_FEE + _params.feeAmount > $._maxClaimFee || (_params.feeCollector == address(0) && _params.feeAmount > 0) ) revert Staker__InvalidClaimFeeParameters(); emit ClaimFeeParametersSet( - claimFeeParameters.feeAmount, + $._claimFeeParameters.feeAmount, _params.feeAmount, - claimFeeParameters.feeCollector, + $._claimFeeParameters.feeCollector, _params.feeCollector ); - claimFeeParameters = _params; + $._claimFeeParameters = _params; } /// @notice Internal helper method which reverts Staker__Unauthorized if the message /// sender is not the admin. function _revertIfNotAdmin() internal view virtual { - if (msg.sender != admin) revert Staker__Unauthorized("not admin", msg.sender); + StakerStorage storage $ = _getStakerStorage(); + if (msg.sender != $._admin) revert Staker__Unauthorized("not admin", msg.sender); } /// @notice Internal helper method which reverts Staker__Unauthorized if the alleged diff --git a/src/extensions/StakerCapDeposits.sol b/src/extensions/StakerCapDeposits.sol index c213d0cd..005224ea 100644 --- a/src/extensions/StakerCapDeposits.sol +++ b/src/extensions/StakerCapDeposits.sol @@ -21,14 +21,33 @@ abstract contract StakerCapDeposits is Staker { /// cap. error StakerCapDeposits__CapExceeded(); + struct StakerCapDepositsStorage { /// @notice The maximum total amount of tokens that can be staked across all deposits. - uint256 public totalStakeCap; + uint256 _totalStakeCap; + } + + // keccak256(abi.encode(uint256(keccak256("storage.StakerCapDeposits")) - 1)) &~bytes32(uint256(0xff)) + bytes32 private constant STAKER_CAP_DEPOSITS_STORAGE_LOCATION = 0x46a81a56bebd29f7ac25bcccfeb503450824f0cb51e1dc37a6009eb410111900; /// @param _initialTotalStakeCap The initial maximum total stake allowed. constructor(uint256 _initialTotalStakeCap) { _setTotalStakeCap(_initialTotalStakeCap); } + function _getStakerCapDepositsStorage() private pure returns (StakerCapDepositsStorage storage $) { + assembly { + $.slot := STAKER_CAP_DEPOSITS_STORAGE_LOCATION + } + } + + function __StakerCapDeposits_init(uint256 _initialTotalStakeCap) internal onlyInitializing { + __StakerCapDeposits_init_unchained(_initialTotalStakeCap); + } + + function __StakerCapDeposits_init_unchained(uint256 _initialTotalStakeCap) internal onlyInitializing { + _setTotalStakeCap(_initialTotalStakeCap); + } + /// @notice Sets a new maximum total stake cap. /// @param _newTotalStakeCap The new maximum total stake allowed. /// @dev Caller must be the current admin. @@ -37,11 +56,18 @@ abstract contract StakerCapDeposits is Staker { _setTotalStakeCap(_newTotalStakeCap); } + /// @notice The maximum total amount of tokens that can be staked across all deposits. + function totalStakeCap() public view returns (uint256) { + StakerCapDepositsStorage storage $ = _getStakerCapDepositsStorage(); + return $._totalStakeCap; + } + /// @notice Internal helper method which sets a new total stake cap. /// @param _newTotalStakeCap The new maximum total stake allowed. function _setTotalStakeCap(uint256 _newTotalStakeCap) internal { - emit TotalStakeCapSet(totalStakeCap, _newTotalStakeCap); - totalStakeCap = _newTotalStakeCap; + StakerCapDepositsStorage storage $ = _getStakerCapDepositsStorage(); + emit TotalStakeCapSet($._totalStakeCap, _newTotalStakeCap); + $._totalStakeCap = _newTotalStakeCap; } /// @inheritdoc Staker @@ -73,6 +99,7 @@ abstract contract StakerCapDeposits is Staker { /// @dev Reverts with StakerCapDeposits__CapExceeded if the amount would cause total stake to /// exceed the cap. function _revertIfCapExceeded(uint256 _amount) internal view virtual { - if ((totalStaked + _amount) > totalStakeCap) revert StakerCapDeposits__CapExceeded(); + StakerCapDepositsStorage storage $ = _getStakerCapDepositsStorage(); + if ((totalStaked() + _amount) > $._totalStakeCap) revert StakerCapDeposits__CapExceeded(); } } diff --git a/src/extensions/StakerDelegateSurrogateVotes.sol b/src/extensions/StakerDelegateSurrogateVotes.sol index 7db98aa1..b405b4a0 100644 --- a/src/extensions/StakerDelegateSurrogateVotes.sol +++ b/src/extensions/StakerDelegateSurrogateVotes.sol @@ -14,24 +14,56 @@ abstract contract StakerDelegateSurrogateVotes is Staker { /// @notice Emitted when a surrogate contract is deployed. event SurrogateDeployed(address indexed delegatee, address indexed surrogate); - /// @notice Maps the account of each governance delegate with the surrogate contract which holds - /// the staked tokens from deposits which assign voting weight to said delegate. - mapping(address delegatee => DelegationSurrogate surrogate) private storedSurrogates; - /// @notice Thrown if an inheritor misconfigures the staking token on deployment. error StakerDelegateSurrogateVotes__UnauthorizedToken(); + struct StakerDelegateSurrogateVotesStorage { + /// @notice Maps the account of each governance delegate with the surrogate contract which holds + /// the staked tokens from deposits which assign voting weight to said delegate. + mapping(address delegatee => DelegationSurrogate surrogate) _storedSurrogates; + } + + // keccak256(abi.encode(uint256(keccak256("storage.StakerDelegateSurrogateVotes")) - 1)) &~bytes32(uint256(0xff)) + bytes32 private constant STAKER_DELEGATE_SURROGATE_STORAGE_LOCATION = 0x2186d4a7f8e27d9f3f491b144161a10376bddb43a9c124160e3a246528969400; + /// @param _votingToken The token that is used for voting, which must be the same as the parent /// Staker's STAKE_TOKEN. constructor(IERC20Delegates _votingToken) { - if (address(STAKE_TOKEN) != address(_votingToken)) { + if (address(STAKE_TOKEN()) != address(_votingToken)) { + revert StakerDelegateSurrogateVotes__UnauthorizedToken(); + } + } + + function _getStakerDelegateSurrogateStorage() private pure returns (StakerDelegateSurrogateVotesStorage storage $) { + assembly { + $.slot := STAKER_DELEGATE_SURROGATE_STORAGE_LOCATION + } + } + + function __StakerDelegateSurrogateVotes_init( IERC20Delegates _votingToken + ) internal onlyInitializing { + __StakerDelegateSurrogateVotes_init_unchained(_votingToken); + } + + function __StakerDelegateSurrogateVotes_init_unchained(IERC20Delegates _votingToken) internal onlyInitializing { + if (address(STAKE_TOKEN()) != address(_votingToken)) { revert StakerDelegateSurrogateVotes__UnauthorizedToken(); } } + /// @inheritdoc Staker function surrogates(address _delegatee) public view override returns (DelegationSurrogate) { - return storedSurrogates[_delegatee]; + StakerStorage storage $ = _getStakerDelegateSurrogateStorage(); + return $._storedSurrogates[_delegatee]; + } + + /// @notice Maps the account of each governance delegate with the surrogate contract. + /// @param _delegatee The address of the delegatee. + /// @return The surrogate contract address for the given delegatee. + function storedSurrogates(address _delegatee) public view returns (DelegationSurrogate) { + StakerStorage storage $ = _getStakerDelegateSurrogateStorage(); + return $._storedSurrogates[_delegatee]; } /// @inheritdoc Staker @@ -41,11 +73,12 @@ abstract contract StakerDelegateSurrogateVotes is Staker { override returns (DelegationSurrogate _surrogate) { - _surrogate = storedSurrogates[_delegatee]; + StakerStorage storage $ = _getStakerDelegateSurrogateStorage(); + _surrogate = $._storedSurrogates[_delegatee]; if (address(_surrogate) == address(0)) { - _surrogate = new DelegationSurrogateVotes(IERC20Delegates(address(STAKE_TOKEN)), _delegatee); - storedSurrogates[_delegatee] = _surrogate; + _surrogate = new DelegationSurrogateVotes(IERC20Delegates(address(STAKE_TOKEN())), _delegatee); + $._storedSurrogates[_delegatee] = _surrogate; emit SurrogateDeployed(_delegatee, address(_surrogate)); } } From f172dee707526b2d928867f23e0b595dfac24628 Mon Sep 17 00:00:00 2001 From: keating Date: Tue, 12 Aug 2025 07:14:18 -0400 Subject: [PATCH 03/19] Fix compilation --- src/Staker.sol | 8 ++++++++ src/extensions/StakerDelegateSurrogateVotes.sol | 6 +++--- src/extensions/StakerOnBehalf.sol | 10 +++++----- src/extensions/StakerPermitAndStake.sol | 8 ++++---- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/Staker.sol b/src/Staker.sol index edefebcb..1609a0a9 100644 --- a/src/Staker.sol +++ b/src/Staker.sol @@ -499,6 +499,14 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { return $._nextDepositId; } + /// @notice Internal helper to get a deposit in storage. + /// @param _depositId The identifier of the deposit. + /// @return The deposit in storage. + function _getDeposit(DepositIdentifier _depositId) internal view virtual returns (Deposit storage) { + StakerStorage storage $ = _getStakerStorage(); + return $._deposits[_depositId]; + } + /// @notice Stake tokens to a new deposit. The caller must pre-approve the staking contract to /// spend at least the would-be staked amount of the token. /// @param _amount The amount of the staking token to stake. diff --git a/src/extensions/StakerDelegateSurrogateVotes.sol b/src/extensions/StakerDelegateSurrogateVotes.sol index b405b4a0..e3228826 100644 --- a/src/extensions/StakerDelegateSurrogateVotes.sol +++ b/src/extensions/StakerDelegateSurrogateVotes.sol @@ -54,7 +54,7 @@ abstract contract StakerDelegateSurrogateVotes is Staker { /// @inheritdoc Staker function surrogates(address _delegatee) public view override returns (DelegationSurrogate) { - StakerStorage storage $ = _getStakerDelegateSurrogateStorage(); + StakerDelegateSurrogateVotesStorage storage $ = _getStakerDelegateSurrogateStorage(); return $._storedSurrogates[_delegatee]; } @@ -62,7 +62,7 @@ abstract contract StakerDelegateSurrogateVotes is Staker { /// @param _delegatee The address of the delegatee. /// @return The surrogate contract address for the given delegatee. function storedSurrogates(address _delegatee) public view returns (DelegationSurrogate) { - StakerStorage storage $ = _getStakerDelegateSurrogateStorage(); + StakerDelegateSurrogateVotesStorage storage $ = _getStakerDelegateSurrogateStorage(); return $._storedSurrogates[_delegatee]; } @@ -73,7 +73,7 @@ abstract contract StakerDelegateSurrogateVotes is Staker { override returns (DelegationSurrogate _surrogate) { - StakerStorage storage $ = _getStakerDelegateSurrogateStorage(); + StakerDelegateSurrogateVotesStorage storage $ = _getStakerDelegateSurrogateStorage(); _surrogate = $._storedSurrogates[_delegatee]; if (address(_surrogate) == address(0)) { diff --git a/src/extensions/StakerOnBehalf.sol b/src/extensions/StakerOnBehalf.sol index 7b1ec61d..0e2f41d2 100644 --- a/src/extensions/StakerOnBehalf.sol +++ b/src/extensions/StakerOnBehalf.sol @@ -114,7 +114,7 @@ abstract contract StakerOnBehalf is Staker, EIP712, Nonces { uint256 _deadline, bytes memory _signature ) external virtual { - Deposit storage deposit = deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _revertIfNotDepositOwner(deposit, _depositor); _revertIfPastDeadline(_deadline); _revertIfSignatureIsNotValidNow( @@ -147,7 +147,7 @@ abstract contract StakerOnBehalf is Staker, EIP712, Nonces { uint256 _deadline, bytes memory _signature ) external virtual { - Deposit storage deposit = deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _revertIfNotDepositOwner(deposit, _depositor); _revertIfPastDeadline(_deadline); _revertIfSignatureIsNotValidNow( @@ -186,7 +186,7 @@ abstract contract StakerOnBehalf is Staker, EIP712, Nonces { uint256 _deadline, bytes memory _signature ) external virtual { - Deposit storage deposit = deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _revertIfNotDepositOwner(deposit, _depositor); _revertIfPastDeadline(_deadline); _revertIfSignatureIsNotValidNow( @@ -224,7 +224,7 @@ abstract contract StakerOnBehalf is Staker, EIP712, Nonces { uint256 _deadline, bytes memory _signature ) external virtual { - Deposit storage deposit = deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _revertIfNotDepositOwner(deposit, _depositor); _revertIfPastDeadline(_deadline); _revertIfSignatureIsNotValidNow( @@ -255,7 +255,7 @@ abstract contract StakerOnBehalf is Staker, EIP712, Nonces { bytes memory _signature ) external virtual returns (uint256) { _revertIfPastDeadline(_deadline); - Deposit storage deposit = deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); bytes32 _claimerHash = _hashTypedDataV4( keccak256(abi.encode(CLAIM_REWARD_TYPEHASH, _depositId, nonces(deposit.claimer), _deadline)) ); diff --git a/src/extensions/StakerPermitAndStake.sol b/src/extensions/StakerPermitAndStake.sol index 06702f8f..d53867e8 100644 --- a/src/extensions/StakerPermitAndStake.sol +++ b/src/extensions/StakerPermitAndStake.sol @@ -18,7 +18,7 @@ abstract contract StakerPermitAndStake is Staker { /// @param _permitToken The token that is used for staking, which must support EIP-2612. It also /// must be the same as the parent Staker's STAKE_TOKEN. constructor(IERC20Permit _permitToken) { - if (address(STAKE_TOKEN) != address(_permitToken)) { + if (address(STAKE_TOKEN()) != address(_permitToken)) { revert StakerPermitAndStake__UnauthorizedToken(); } } @@ -45,7 +45,7 @@ abstract contract StakerPermitAndStake is Staker { bytes32 _r, bytes32 _s ) external virtual returns (DepositIdentifier _depositId) { - try IERC20Permit(address(STAKE_TOKEN)).permit( + try IERC20Permit(address(STAKE_TOKEN())).permit( msg.sender, address(this), _amount, _deadline, _v, _r, _s ) {} catch {} _depositId = _stake(msg.sender, _amount, _delegatee, _claimer); @@ -70,10 +70,10 @@ abstract contract StakerPermitAndStake is Staker { bytes32 _r, bytes32 _s ) external virtual { - Deposit storage deposit = deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _revertIfNotDepositOwner(deposit, msg.sender); - try IERC20Permit(address(STAKE_TOKEN)).permit( + try IERC20Permit(address(STAKE_TOKEN())).permit( msg.sender, address(this), _amount, _deadline, _v, _r, _s ) {} catch {} _stakeMore(deposit, _depositId, _amount); From 20cf97552bac2498bc2515687594534ab31e59cf Mon Sep 17 00:00:00 2001 From: keating Date: Tue, 12 Aug 2025 07:23:44 -0400 Subject: [PATCH 04/19] Fix tuple destructuring issues --- src/Staker.sol | 8 ++++++++ test/Staker.t.sol | 31 +++++++++++++++++-------------- test/StakerTestBase.sol | 17 ++++++++--------- test/harnesses/StakerHarness.sol | 2 +- test/helpers/Staker.handler.sol | 6 ++++-- test/mocks/MockStakerHarness.sol | 2 +- 6 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/Staker.sol b/src/Staker.sol index 1609a0a9..c9f2a818 100644 --- a/src/Staker.sol +++ b/src/Staker.sol @@ -1023,6 +1023,14 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { $._claimFeeParameters = _params; } + /// @notice Internal helper method to set the max claim fee. + /// @param _maxClaimFee The maximum claim fee value. + /// @dev This should only be called in constructors of concrete implementations. + function _setMaxClaimFee(uint256 _maxClaimFee) internal virtual { + StakerStorage storage $ = _getStakerStorage(); + $._maxClaimFee = _maxClaimFee; + } + /// @notice Internal helper method which reverts Staker__Unauthorized if the message /// sender is not the admin. function _revertIfNotAdmin() internal view virtual { diff --git a/test/Staker.t.sol b/test/Staker.t.sol index 8d1a2095..56b15f9a 100644 --- a/test/Staker.t.sol +++ b/test/Staker.t.sol @@ -676,7 +676,7 @@ contract Stake is StakerTest { (, Staker.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _depositor); - (,, uint96 _actualEarningPower,,,,) = govStaker.deposits(_depositId); + uint96 _actualEarningPower = govStaker.deposits(_depositId).earningPower; uint256 _expectedEarningPower = (_stakeAmount * _multiplierBips) / 10_000; assertEq(_actualEarningPower, _expectedEarningPower); } @@ -694,7 +694,7 @@ contract Stake is StakerTest { (, Staker.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _depositor); - (,, uint96 _actualEarningPower,,,,) = govStaker.deposits(_depositId); + uint96 _actualEarningPower = govStaker.deposits(_depositId).earningPower; assertEq(_actualEarningPower, _fixedEarningPower); } } @@ -1191,7 +1191,7 @@ contract StakeMore is StakerTest { govStaker.stakeMore(_depositId, _addAmount); vm.stopPrank(); - (,, uint96 _actualEarningPower,,,,) = govStaker.deposits(_depositId); + uint96 _actualEarningPower = govStaker.deposits(_depositId).earningPower; uint256 _expectedEarningPower = ((_depositAmount + _addAmount) * _multiplierBips) / 10_000; assertEq(_actualEarningPower, _expectedEarningPower); } @@ -1216,7 +1216,7 @@ contract StakeMore is StakerTest { govStaker.stakeMore(_depositId, _addAmount); vm.stopPrank(); - (,, uint96 _actualEarningPower,,,,) = govStaker.deposits(_depositId); + uint96 _actualEarningPower = govStaker.deposits(_depositId).earningPower; assertEq(_actualEarningPower, _fixedEarningPower); } @@ -2464,7 +2464,9 @@ contract SetClaimFeeParameters is StakerTest { vm.prank(admin); govStaker.setClaimFeeParameters(_newParams); - (uint96 _feeAmount, address _feeCollector) = govStaker.claimFeeParameters(); + Staker.ClaimFeeParameters memory _feeParams = govStaker.claimFeeParameters(); + uint96 _feeAmount = _feeParams.feeAmount; + address _feeCollector = _feeParams.feeCollector; assertEq(_feeAmount, _newParams.feeAmount); assertEq(_feeCollector, _newParams.feeCollector); } @@ -2486,7 +2488,9 @@ contract SetClaimFeeParameters is StakerTest { vm.prank(admin); govStaker.setClaimFeeParameters(_zeroParams); - (uint96 _feeAmount, address _feeCollector) = govStaker.claimFeeParameters(); + Staker.ClaimFeeParameters memory _feeParams = govStaker.claimFeeParameters(); + uint96 _feeAmount = _feeParams.feeAmount; + address _feeCollector = _feeParams.feeCollector; assertEq(_feeAmount, 0); assertEq(_feeCollector, address(0)); } @@ -2891,7 +2895,7 @@ contract BumpEarningPower is StakerRewardsTest { vm.prank(_bumpCaller); govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip); - (,, uint96 _newEarningPower,,,,) = govStaker.deposits(_depositId); + uint96 _newEarningPower = govStaker.deposits(_depositId).earningPower; assertEq(_newEarningPower, _stakeAmount + _earningPowerIncrease); } @@ -3120,7 +3124,7 @@ contract BumpEarningPower is StakerRewardsTest { vm.prank(_bumpCaller); govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip); - (,, uint96 _newEarningPower,,,,) = govStaker.deposits(_depositId); + uint96 _newEarningPower = govStaker.deposits(_depositId).earningPower; assertEq(_newEarningPower, _stakeAmount - _earningPowerDecrease); } @@ -3545,7 +3549,7 @@ contract BumpEarningPower is StakerRewardsTest { govStaker.bumpEarningPower(depositId, _depositor, 0); // Verify the earning power update - (,, uint96 actualEarningPower,,,,) = govStaker.deposits(depositId); + uint96 actualEarningPower = govStaker.deposits(depositId).earningPower; uint256 expectedEarningPower = (_stakeAmount * _multiplierBips) / 10_000; assertEq(actualEarningPower, expectedEarningPower, "Earning power should be updated"); } @@ -5447,12 +5451,11 @@ contract Multicall is StakerRewardsTest { govStaker.multicall(_calls); vm.stopPrank(); - (uint96 _amountResult,,, address _delegateeResult, address _claimerResult,,) = - govStaker.deposits(_depositId); + Staker.Deposit memory _depositResult = govStaker.deposits(_depositId); assertEq(govStaker.depositorTotalStaked(_depositor), _stakeAmount0 + _stakeAmount1); assertEq(govStaker.depositorTotalEarningPower(_depositor), _stakeAmount0 + _stakeAmount1); - assertEq(_amountResult, _stakeAmount0 + _stakeAmount1); - assertEq(_delegateeResult, _delegatee1); - assertEq(_claimerResult, _claimer1); + assertEq(_depositResult.balance, _stakeAmount0 + _stakeAmount1); + assertEq(_depositResult.delegatee, _delegatee1); + assertEq(_depositResult.claimer, _claimer1); } } diff --git a/test/StakerTestBase.sol b/test/StakerTestBase.sol index ff2c5ac6..773fd302 100644 --- a/test/StakerTestBase.sol +++ b/test/StakerTestBase.sol @@ -143,15 +143,14 @@ abstract contract StakerTestBase is Test, PercentAssertions { view returns (Staker.Deposit memory) { - ( - uint96 _balance, - address _owner, - uint96 _earningPower, - address _delegatee, - address _claimer, - uint256 _rewardPerTokenCheckpoint, - uint256 _scaledUnclaimedRewardCheckpoint - ) = baseStaker.deposits(_depositId); + Staker.Deposit memory _deposit = baseStaker.deposits(_depositId); + uint96 _balance = _deposit.balance; + address _owner = _deposit.owner; + uint96 _earningPower = _deposit.earningPower; + address _delegatee = _deposit.delegatee; + address _claimer = _deposit.claimer; + uint256 _rewardPerTokenCheckpoint = _deposit.rewardPerTokenCheckpoint; + uint256 _scaledUnclaimedRewardCheckpoint = _deposit.scaledUnclaimedRewardCheckpoint; return Staker.Deposit({ balance: _balance, owner: _owner, diff --git a/test/harnesses/StakerHarness.sol b/test/harnesses/StakerHarness.sol index 76340fd3..703dc364 100644 --- a/test/harnesses/StakerHarness.sol +++ b/test/harnesses/StakerHarness.sol @@ -31,7 +31,7 @@ contract StakerHarness is StakerDelegateSurrogateVotes(_stakeToken) EIP712(_name, "1") { - MAX_CLAIM_FEE = 1e18; + _setMaxClaimFee(1e18); _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); } diff --git a/test/helpers/Staker.handler.sol b/test/helpers/Staker.handler.sol index 054ec297..e16fa19f 100644 --- a/test/helpers/Staker.handler.sol +++ b/test/helpers/Staker.handler.sol @@ -132,7 +132,8 @@ contract StakerHandler is CommonBase, StdCheats, StdUtils { vm.assume(_depositIds[_currentActor].length > 0); Staker.DepositIdentifier _depositId = Staker.DepositIdentifier.wrap(_getActorRandDepositId(_actorDepositSeed)); - (uint256 _balance,,,,,,) = govStaker.deposits(_depositId); + Staker.Deposit memory _deposit = govStaker.deposits(_depositId); + uint256 _balance = _deposit.balance; _amount = uint256(_bound(_amount, 0, _balance)); vm.startPrank(_currentActor); stakeToken.approve(address(govStaker), _amount); @@ -151,7 +152,8 @@ contract StakerHandler is CommonBase, StdCheats, StdUtils { vm.assume(_depositIds[_currentActor].length > 0); Staker.DepositIdentifier _depositId = Staker.DepositIdentifier.wrap(_getActorRandDepositId(_actorDepositSeed)); - (uint256 _balance,,,,,,) = govStaker.deposits(_depositId); + Staker.Deposit memory _deposit = govStaker.deposits(_depositId); + uint256 _balance = _deposit.balance; _amount = uint256(_bound(_amount, 0, _balance)); vm.startPrank(_currentActor); govStaker.withdraw(_depositId, _amount); diff --git a/test/mocks/MockStakerHarness.sol b/test/mocks/MockStakerHarness.sol index 8538218a..a2ffcecb 100644 --- a/test/mocks/MockStakerHarness.sol +++ b/test/mocks/MockStakerHarness.sol @@ -27,7 +27,7 @@ contract MockStakerHarness is Staker, StakerPermitAndStake, StakerDelegateSurrog StakerPermitAndStake(_permitAndStakeStakeToken) StakerDelegateSurrogateVotes(_delegateSurrogateVotesStakeToken) { - MAX_CLAIM_FEE = 1e18; + _setMaxClaimFee(1e18); _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); } From 579d557957cbc58303b2c65c769ee5db1c80eac7 Mon Sep 17 00:00:00 2001 From: keating Date: Tue, 12 Aug 2025 08:33:10 -0400 Subject: [PATCH 05/19] Test gas --- test/gas-reports/gov-staker-gas-report.json | 34 ++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/test/gas-reports/gov-staker-gas-report.json b/test/gas-reports/gov-staker-gas-report.json index 0f1e3c64..178fc75a 100644 --- a/test/gas-reports/gov-staker-gas-report.json +++ b/test/gas-reports/gov-staker-gas-report.json @@ -1,70 +1,70 @@ { - "generatedAt": 1738772511, + "generatedAt": 1755001934, "reportName:": "gov-stakerGasReport", "results": [ { "scenarioName": "First stake to a new delegatee", - "gasUsed": 331255 + "gasUsed": 333651 }, { "scenarioName": "Second stake to a existing delegatee", - "gasUsed": 164973 + "gasUsed": 167260 }, { "scenarioName": "Second stake to a new delegatee", - "gasUsed": 297055 + "gasUsed": 299451 }, { "scenarioName": "Stake more after initial stake", - "gasUsed": 101818 + "gasUsed": 104135 }, { "scenarioName": "Alter delegatee with new delegatee", - "gasUsed": 218712 + "gasUsed": 221137 }, { "scenarioName": "Alter delegatee with existing delegatee", - "gasUsed": 86606 + "gasUsed": 88922 }, { "scenarioName": "Alter claimer to a new address", - "gasUsed": 69683 + "gasUsed": 69870 }, { "scenarioName": "Withdraw full stake", - "gasUsed": 110825 + "gasUsed": 113139 }, { "scenarioName": "Withdraw partial stake", - "gasUsed": 125225 + "gasUsed": 127539 }, { "scenarioName": "Claim reward when no reward", - "gasUsed": 46021 + "gasUsed": 46188 }, { "scenarioName": "Claim reward when reward", - "gasUsed": 165132 + "gasUsed": 167444 }, { "scenarioName": "Notify reward", - "gasUsed": 45750 + "gasUsed": 47950 }, { "scenarioName": "Second notify reward", - "gasUsed": 46099 + "gasUsed": 48310 }, { "scenarioName": "Bump earning power up no reward", - "gasUsed": 82880 + "gasUsed": 85461 }, { "scenarioName": "Bump earning power down with reward", - "gasUsed": 111652 + "gasUsed": 114242 }, { "scenarioName": "Bump earning power up with reward", - "gasUsed": 111652 + "gasUsed": 114242 } ] } \ No newline at end of file From 259848a71366251079ca7b9a57188a4e2ce69e11 Mon Sep 17 00:00:00 2001 From: keating Date: Wed, 13 Aug 2025 10:58:48 -0400 Subject: [PATCH 06/19] Constructors removed tests failing --- src/Staker.sol | 67 ++++++++++--------- src/extensions/StakerCapDeposits.sol | 23 ++++--- .../StakerDelegateSurrogateVotes.sol | 32 ++++----- src/extensions/StakerOnBehalf.sol | 10 ++- src/extensions/StakerPermitAndStake.sol | 10 ++- test/Staker.invariants.t.sol | 5 +- test/Staker.t.sol | 18 ++--- test/StakerCapDeposits.t.sol | 25 ++++--- test/StakerOnBehalf.t.sol | 8 ++- test/fakes/DeployBaseFake.sol | 8 ++- .../DeployBaseInvalidStakerAdminFake.sol | 8 ++- ...bilityOracleEarningPowerCalculatorFake.sol | 8 ++- .../DeployMultipleRewardNotifiersFake.sol | 9 ++- .../DeployTransferFromRewardNotifierFake.sol | 9 ++- .../DeployTransferRewardNotifierFake.sol | 9 ++- test/harnesses/StakerHarness.sol | 39 +++++++---- test/harnesses/StakerHarnessCapDeposits.sol | 43 +++++++++--- test/mocks/MockStakerHarness.sol | 6 +- 18 files changed, 211 insertions(+), 126 deletions(-) diff --git a/src/Staker.sol b/src/Staker.sol index c9f2a818..f254ee9a 100644 --- a/src/Staker.sol +++ b/src/Staker.sol @@ -237,6 +237,7 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { ClaimFeeParameters _claimFeeParameters; } // keccak256(abi.encode(uint256(keccak256("storage.Staker")) - 1)) &~bytes32(uint256(0xff)) + bytes32 private constant STAKER_STORAGE_LOCATION = 0x587a86d9af0b7e1804e53a546ebb2307f72c0e29a89678476433276515d51100; @@ -247,26 +248,21 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// truncation during division. uint256 public constant SCALE_FACTOR = 1e36; - /// @param _rewardToken ERC20 token in which rewards will be denominated. - /// @param _stakeToken Delegable governance token which users will stake to earn rewards. - /// @param _earningPowerCalculator The contract that will serve as the initial calculator of - /// earning power for the staker system. - /// @param _admin Address which will have permission to manage reward notifiers, claim fee /// parameters, the max bump tip, and the reward calculator. - constructor( - IERC20 _rewardToken, - IERC20 _stakeToken, - IEarningPowerCalculator _earningPowerCalculator, - uint256 _maxBumpTip, - address _admin - ) { - StakerStorage storage $ = _getStakerStorage(); - $._rewardToken = _rewardToken; - $._stakeToken = _stakeToken; - _setAdmin(_admin); - _setMaxBumpTip(_maxBumpTip); - _setEarningPowerCalculator(address(_earningPowerCalculator)); - } + // constructor( + // IERC20 _rewardToken, + // IERC20 _stakeToken, + // IEarningPowerCalculator _earningPowerCalculator, + // uint256 _maxBumpTip, + // address _admin + // ) { + // StakerStorage storage $ = _getStakerStorage(); + // $._rewardToken = _rewardToken; + // $._stakeToken = _stakeToken; + // _setAdmin(_admin); + // _setMaxBumpTip(_maxBumpTip); + // _setEarningPowerCalculator(address(_earningPowerCalculator)); + // } function _getStakerStorage() private pure returns (StakerStorage storage $) { assembly { @@ -282,7 +278,9 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { uint256 _maxBumpTip, IEarningPowerCalculator _earningPowerCalculator ) internal onlyInitializing { - __Staker_init_unchained(_rewardToken, _stakeToken, _maxClaimFee, _admin, _maxBumpTip, _earningPowerCalculator); + __Staker_init_unchained( + _rewardToken, _stakeToken, _maxClaimFee, _admin, _maxBumpTip, _earningPowerCalculator + ); } function __Staker_init_unchained( @@ -370,7 +368,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { if ($._totalEarningPower == 0) return $._rewardPerTokenAccumulatedCheckpoint; return $._rewardPerTokenAccumulatedCheckpoint - + ($._scaledRewardRate * (lastTimeRewardDistributed() - $._lastCheckpointTime)) / $._totalEarningPower; + + ($._scaledRewardRate * (lastTimeRewardDistributed() - $._lastCheckpointTime)) + / $._totalEarningPower; } /// @notice Live value of the unclaimed rewards earned by a given deposit. It is the @@ -502,7 +501,12 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { /// @notice Internal helper to get a deposit in storage. /// @param _depositId The identifier of the deposit. /// @return The deposit in storage. - function _getDeposit(DepositIdentifier _depositId) internal view virtual returns (Deposit storage) { + function _getDeposit(DepositIdentifier _depositId) + internal + view + virtual + returns (Deposit storage) + { StakerStorage storage $ = _getStakerStorage(); return $._deposits[_depositId]; } @@ -643,7 +647,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { // critical that only safe reward notifier contracts are approved to call this method by the // admin. if ( - ($._scaledRewardRate * REWARD_DURATION) > ($._rewardToken.balanceOf(address(this)) * SCALE_FACTOR) + ($._scaledRewardRate * REWARD_DURATION) + > ($._rewardToken.balanceOf(address(this)) * SCALE_FACTOR) ) revert Staker__InsufficientRewardBalance(); emit RewardNotified(_amount, msg.sender); @@ -672,9 +677,9 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { uint256 _unclaimedRewards = deposit.scaledUnclaimedRewardCheckpoint / SCALE_FACTOR; - (uint256 _newEarningPower, bool _isQualifiedForBump) = $._earningPowerCalculator.getNewEarningPower( - deposit.balance, deposit.owner, deposit.delegatee, deposit.earningPower - ); + (uint256 _newEarningPower, bool _isQualifiedForBump) = $ + ._earningPowerCalculator + .getNewEarningPower(deposit.balance, deposit.owner, deposit.delegatee, deposit.earningPower); if (!_isQualifiedForBump || _newEarningPower == deposit.earningPower) { revert Staker__Unqualified(_newEarningPower); } @@ -684,10 +689,9 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { } // Note: underflow causes a revert if the requested tip is more than unclaimed rewards - if (_newEarningPower < deposit.earningPower && (_unclaimedRewards - _requestedTip) < $._maxBumpTip) - { - revert Staker__InsufficientUnclaimedRewards(); - } + if ( + _newEarningPower < deposit.earningPower && (_unclaimedRewards - _requestedTip) < $._maxBumpTip + ) revert Staker__InsufficientUnclaimedRewards(); emit EarningPowerBumped( _depositId, deposit.earningPower, _newEarningPower, msg.sender, _tipReceiver, _requestedTip @@ -765,7 +769,8 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { _depositId = _useDepositId(); StakerStorage storage $ = _getStakerStorage(); - uint256 _earningPower = $._earningPowerCalculator.getEarningPower(_amount, _depositor, _delegatee); + uint256 _earningPower = + $._earningPowerCalculator.getEarningPower(_amount, _depositor, _delegatee); $._totalStaked += _amount; $._totalEarningPower += _earningPower; diff --git a/src/extensions/StakerCapDeposits.sol b/src/extensions/StakerCapDeposits.sol index 005224ea..3354f9c2 100644 --- a/src/extensions/StakerCapDeposits.sol +++ b/src/extensions/StakerCapDeposits.sol @@ -22,17 +22,18 @@ abstract contract StakerCapDeposits is Staker { error StakerCapDeposits__CapExceeded(); struct StakerCapDepositsStorage { - /// @notice The maximum total amount of tokens that can be staked across all deposits. - uint256 _totalStakeCap; + /// @notice The maximum total amount of tokens that can be staked across all deposits. + uint256 _totalStakeCap; } - // keccak256(abi.encode(uint256(keccak256("storage.StakerCapDeposits")) - 1)) &~bytes32(uint256(0xff)) - bytes32 private constant STAKER_CAP_DEPOSITS_STORAGE_LOCATION = 0x46a81a56bebd29f7ac25bcccfeb503450824f0cb51e1dc37a6009eb410111900; + // keccak256(abi.encode(uint256(keccak256("storage.StakerCapDeposits")) - 1)) + // &~bytes32(uint256(0xff)) + bytes32 private constant STAKER_CAP_DEPOSITS_STORAGE_LOCATION = + 0x46a81a56bebd29f7ac25bcccfeb503450824f0cb51e1dc37a6009eb410111900; - /// @param _initialTotalStakeCap The initial maximum total stake allowed. - constructor(uint256 _initialTotalStakeCap) { - _setTotalStakeCap(_initialTotalStakeCap); - } + // constructor(uint256 _initialTotalStakeCap) { + // _setTotalStakeCap(_initialTotalStakeCap); + // } function _getStakerCapDepositsStorage() private pure returns (StakerCapDepositsStorage storage $) { assembly { @@ -40,11 +41,15 @@ abstract contract StakerCapDeposits is Staker { } } + /// @param _initialTotalStakeCap The initial maximum total stake allowed. function __StakerCapDeposits_init(uint256 _initialTotalStakeCap) internal onlyInitializing { __StakerCapDeposits_init_unchained(_initialTotalStakeCap); } - function __StakerCapDeposits_init_unchained(uint256 _initialTotalStakeCap) internal onlyInitializing { + function __StakerCapDeposits_init_unchained(uint256 _initialTotalStakeCap) + internal + onlyInitializing + { _setTotalStakeCap(_initialTotalStakeCap); } diff --git a/src/extensions/StakerDelegateSurrogateVotes.sol b/src/extensions/StakerDelegateSurrogateVotes.sol index e3228826..ef64a4cc 100644 --- a/src/extensions/StakerDelegateSurrogateVotes.sol +++ b/src/extensions/StakerDelegateSurrogateVotes.sol @@ -23,35 +23,37 @@ abstract contract StakerDelegateSurrogateVotes is Staker { mapping(address delegatee => DelegationSurrogate surrogate) _storedSurrogates; } - // keccak256(abi.encode(uint256(keccak256("storage.StakerDelegateSurrogateVotes")) - 1)) &~bytes32(uint256(0xff)) - bytes32 private constant STAKER_DELEGATE_SURROGATE_STORAGE_LOCATION = 0x2186d4a7f8e27d9f3f491b144161a10376bddb43a9c124160e3a246528969400; + // keccak256(abi.encode(uint256(keccak256("storage.StakerDelegateSurrogateVotes")) - 1)) + // &~bytes32(uint256(0xff)) + bytes32 private constant STAKER_DELEGATE_SURROGATE_STORAGE_LOCATION = + 0x2186d4a7f8e27d9f3f491b144161a10376bddb43a9c124160e3a246528969400; - /// @param _votingToken The token that is used for voting, which must be the same as the parent - /// Staker's STAKE_TOKEN. - constructor(IERC20Delegates _votingToken) { - if (address(STAKE_TOKEN()) != address(_votingToken)) { - revert StakerDelegateSurrogateVotes__UnauthorizedToken(); - } - } - - function _getStakerDelegateSurrogateStorage() private pure returns (StakerDelegateSurrogateVotesStorage storage $) { + function _getStakerDelegateSurrogateStorage() + private + pure + returns (StakerDelegateSurrogateVotesStorage storage $) + { assembly { $.slot := STAKER_DELEGATE_SURROGATE_STORAGE_LOCATION } } - function __StakerDelegateSurrogateVotes_init( IERC20Delegates _votingToken - ) internal onlyInitializing { + function __StakerDelegateSurrogateVotes_init(IERC20Delegates _votingToken) + internal + onlyInitializing + { __StakerDelegateSurrogateVotes_init_unchained(_votingToken); } - function __StakerDelegateSurrogateVotes_init_unchained(IERC20Delegates _votingToken) internal onlyInitializing { + function __StakerDelegateSurrogateVotes_init_unchained(IERC20Delegates _votingToken) + internal + onlyInitializing + { if (address(STAKE_TOKEN()) != address(_votingToken)) { revert StakerDelegateSurrogateVotes__UnauthorizedToken(); } } - /// @inheritdoc Staker function surrogates(address _delegatee) public view override returns (DelegationSurrogate) { StakerDelegateSurrogateVotesStorage storage $ = _getStakerDelegateSurrogateStorage(); diff --git a/src/extensions/StakerOnBehalf.sol b/src/extensions/StakerOnBehalf.sol index 0e2f41d2..10476e09 100644 --- a/src/extensions/StakerOnBehalf.sol +++ b/src/extensions/StakerOnBehalf.sol @@ -4,7 +4,9 @@ pragma solidity ^0.8.23; import {Staker} from "../Staker.sol"; import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; import {Nonces} from "@openzeppelin/contracts/utils/Nonces.sol"; -import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; +import {EIP712Upgradeable} from + "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol"; +import {NoncesUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/NoncesUpgradeable.sol"; /// @title StakerOnBehalf /// @author [ScopeLift](https://scopelift.co) @@ -14,7 +16,7 @@ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; /// altering delegatees and claimers, and claiming rewards. Each operation requires a unique /// signature that is validated against the appropriate signer (owner or claimer) before /// execution. -abstract contract StakerOnBehalf is Staker, EIP712, Nonces { +abstract contract StakerOnBehalf is Staker, EIP712Upgradeable, NoncesUpgradeable { /// @notice Thrown when an onBehalf method is called with a deadline that has expired. error StakerOnBehalf__ExpiredDeadline(); @@ -51,6 +53,10 @@ abstract contract StakerOnBehalf is Staker, EIP712, Nonces { return _domainSeparatorV4(); } + function __StakerOnBehalf_init() internal onlyInitializing {} + + function __StakerOnBehalf_init_unchained() internal onlyInitializing {} + /// @notice Allows an address to increment their nonce and therefore invalidate any pending signed /// actions. function invalidateNonce() external virtual { diff --git a/src/extensions/StakerPermitAndStake.sol b/src/extensions/StakerPermitAndStake.sol index d53867e8..0bafc0c4 100644 --- a/src/extensions/StakerPermitAndStake.sol +++ b/src/extensions/StakerPermitAndStake.sol @@ -16,8 +16,14 @@ abstract contract StakerPermitAndStake is Staker { error StakerPermitAndStake__UnauthorizedToken(); /// @param _permitToken The token that is used for staking, which must support EIP-2612. It also - /// must be the same as the parent Staker's STAKE_TOKEN. - constructor(IERC20Permit _permitToken) { + function __StakerPermitAndStake_init(IERC20Permit _permitToken) internal onlyInitializing { + __StakerPermitAndStake_init_unchained(_permitToken); + } + + function __StakerPermitAndStake_init_unchained(IERC20Permit _permitToken) + internal + onlyInitializing + { if (address(STAKE_TOKEN()) != address(_permitToken)) { revert StakerPermitAndStake__UnauthorizedToken(); } diff --git a/test/Staker.invariants.t.sol b/test/Staker.invariants.t.sol index 4826a86b..077b0f46 100644 --- a/test/Staker.invariants.t.sol +++ b/test/Staker.invariants.t.sol @@ -34,8 +34,9 @@ contract StakerInvariants is Test { earningPowerCalculator = new MockFullEarningPowerCalculator(); vm.label(address(earningPowerCalculator), "Full Earning Power Calculator"); - govStaker = new StakerHarness( - rewardToken, govToken, earningPowerCalculator, maxBumpTip, rewardsNotifier, STAKER_NAME + govStaker = new StakerHarness(); + govStaker.initialize( + rewardToken, govToken, 1e18, rewardsNotifier, maxBumpTip, earningPowerCalculator, STAKER_NAME ); handler = new StakerHandler(govStaker); diff --git a/test/Staker.t.sol b/test/Staker.t.sol index 56b15f9a..c98eea27 100644 --- a/test/Staker.t.sol +++ b/test/Staker.t.sol @@ -31,8 +31,11 @@ contract StakerTest is StakerTestBase { } function _deployStaker() public virtual override(StakerTestBase) returns (Staker _staker) { - return - new StakerHarness(rewardToken, govToken, earningPowerCalculator, maxBumpTip, admin, "Staker"); + StakerHarness _govStaker = new StakerHarness(); + _govStaker.initialize( + rewardToken, govToken, 1e18, admin, maxBumpTip, earningPowerCalculator, "Staker" + ); + return _govStaker; } function _sign(uint256 _privateKey, bytes32 _messageHash) internal pure returns (bytes memory) { @@ -79,14 +82,11 @@ contract Constructor is StakerTest { string memory _name ) public { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); - StakerHarness _govStaker = new StakerHarness( - IERC20(_rewardToken), - IERC20Staking(_stakeToken), - IEarningPowerCalculator(_earningPowerCalculator), - _maxBumpTip, - _admin, - _name + StakerHarness _govStaker = new StakerHarness(); + _govStaker.initialize( + rewardToken, govToken, 1e18, admin, maxBumpTip, earningPowerCalculator, _name ); + assertEq(address(_govStaker.REWARD_TOKEN()), address(_rewardToken)); assertEq(address(_govStaker.STAKE_TOKEN()), address(_stakeToken)); assertEq(address(_govStaker.earningPowerCalculator()), address(_earningPowerCalculator)); diff --git a/test/StakerCapDeposits.t.sol b/test/StakerCapDeposits.t.sol index c6bf5aa3..91bee8ca 100644 --- a/test/StakerCapDeposits.t.sol +++ b/test/StakerCapDeposits.t.sol @@ -13,15 +13,18 @@ contract StakerCapDepositsTest is StakerTestBase { uint256 initialTotalStakeCap = 1_000_000e18; function _deployStaker() public virtual override(StakerTestBase) returns (Staker _staker) { - return new StakerHarnessCapDeposits( + StakerHarnessCapDeposits _govStaker = new StakerHarnessCapDeposits(); + _govStaker.initialize( rewardToken, govToken, - earningPowerCalculator, - maxBumpTip, + 1e18, admin, + maxBumpTip, + earningPowerCalculator, "Staker", initialTotalStakeCap ); + return _govStaker; } function setUp() public virtual override(StakerTestBase) { @@ -39,12 +42,14 @@ contract Constructor is StakerCapDepositsTest { function testFuzz_SetsTheInitialTotalStakeCapToArbitraryValues(uint256 _initialTotalStakeCap) public { - StakerHarnessCapDeposits _govStaker = new StakerHarnessCapDeposits( + StakerHarnessCapDeposits _govStaker = new StakerHarnessCapDeposits(); + _govStaker.initialize( rewardToken, govToken, - earningPowerCalculator, - maxBumpTip, + 1e18, admin, + maxBumpTip, + earningPowerCalculator, "Staker", _initialTotalStakeCap ); @@ -54,12 +59,14 @@ contract Constructor is StakerCapDepositsTest { function testFuzz_EmitsATotalStakeCapSetEvent(uint256 _initialTotalStakeCap) public { vm.expectEmit(); emit StakerCapDeposits.TotalStakeCapSet(0, _initialTotalStakeCap); - new StakerHarnessCapDeposits( + StakerHarnessCapDeposits _govStaker = new StakerHarnessCapDeposits(); + _govStaker.initialize( rewardToken, govToken, - earningPowerCalculator, - maxBumpTip, + 1e18, admin, + maxBumpTip, + earningPowerCalculator, "Staker", _initialTotalStakeCap ); diff --git a/test/StakerOnBehalf.t.sol b/test/StakerOnBehalf.t.sol index 780c8416..50126db9 100644 --- a/test/StakerOnBehalf.t.sol +++ b/test/StakerOnBehalf.t.sol @@ -33,12 +33,14 @@ contract Domain_Separator is StakerTest { string memory _name ) public { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); - StakerHarness _govStaker = new StakerHarness( + StakerHarness _govStaker = new StakerHarness(); + _govStaker.initialize( IERC20(_rewardToken), IERC20Staking(_stakeToken), - IEarningPowerCalculator(_earningPowerCalculator), - _maxBumpTip, + 1e18, _admin, + _maxBumpTip, + IEarningPowerCalculator(_earningPowerCalculator), _name ); diff --git a/test/fakes/DeployBaseFake.sol b/test/fakes/DeployBaseFake.sol index 8a10187f..3e5f73cb 100644 --- a/test/fakes/DeployBaseFake.sol +++ b/test/fakes/DeployBaseFake.sol @@ -75,12 +75,14 @@ contract DeployBaseFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - return new StakerHarness( + StakerHarness _staker = new StakerHarness(); + _staker.initialize( _config.rewardToken, IERC20Staking(address(_config.stakeToken)), - _config.earningPowerCalculator, - _config.maxBumpTip, + 1e18, deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, name ); } diff --git a/test/fakes/DeployBaseInvalidStakerAdminFake.sol b/test/fakes/DeployBaseInvalidStakerAdminFake.sol index 7a9d37ff..0a0a4b70 100644 --- a/test/fakes/DeployBaseInvalidStakerAdminFake.sol +++ b/test/fakes/DeployBaseInvalidStakerAdminFake.sol @@ -75,12 +75,14 @@ contract DeployBaseInvalidStakerAdminFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - return new StakerHarness( + StakerHarness _staker = new StakerHarness(); + _staker.initialize( _config.rewardToken, IERC20Staking(address(_config.stakeToken)), - _config.earningPowerCalculator, + 1e18, + deployer, _config.maxBumpTip, - makeAddr("Anyone but the deployer"), + _config.earningPowerCalculator, name ); } diff --git a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol index cd55cfaa..f9423541 100644 --- a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol +++ b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol @@ -96,12 +96,14 @@ contract DeployBinaryEligibilityOracleEarningPowerCalculatorFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - return new StakerHarness( + StakerHarness _staker = new StakerHarness(); + _staker.initialize( _config.rewardToken, IERC20Staking(address(_config.stakeToken)), - _config.earningPowerCalculator, - _config.maxBumpTip, + 1e18, deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, name ); } diff --git a/test/fakes/DeployMultipleRewardNotifiersFake.sol b/test/fakes/DeployMultipleRewardNotifiersFake.sol index da941e02..55427b97 100644 --- a/test/fakes/DeployMultipleRewardNotifiersFake.sol +++ b/test/fakes/DeployMultipleRewardNotifiersFake.sol @@ -100,13 +100,16 @@ contract DeployMultipleRewardNotifiersFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - return new StakerHarness( + StakerHarness _staker = new StakerHarness(); + _staker.initialize( _config.rewardToken, IERC20Staking(address(_config.stakeToken)), - _config.earningPowerCalculator, - _config.maxBumpTip, + 1e18, deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, name ); + return _staker; } } diff --git a/test/fakes/DeployTransferFromRewardNotifierFake.sol b/test/fakes/DeployTransferFromRewardNotifierFake.sol index c3bce458..5e450f36 100644 --- a/test/fakes/DeployTransferFromRewardNotifierFake.sol +++ b/test/fakes/DeployTransferFromRewardNotifierFake.sol @@ -74,13 +74,16 @@ contract DeployTransferFromRewardNotifierFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - return new StakerHarness( + StakerHarness _staker = new StakerHarness(); + _staker.initialize( _config.rewardToken, IERC20Staking(address(_config.stakeToken)), - _config.earningPowerCalculator, - _config.maxBumpTip, + 1e18, deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, name ); + return _staker; } } diff --git a/test/fakes/DeployTransferRewardNotifierFake.sol b/test/fakes/DeployTransferRewardNotifierFake.sol index 837d91fc..642b651b 100644 --- a/test/fakes/DeployTransferRewardNotifierFake.sol +++ b/test/fakes/DeployTransferRewardNotifierFake.sol @@ -73,13 +73,16 @@ contract DeployTransferRewardNotifierFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - return new StakerHarness( + StakerHarness _staker = new StakerHarness(); + _staker.initialize( _config.rewardToken, IERC20Staking(address(_config.stakeToken)), - _config.earningPowerCalculator, - _config.maxBumpTip, + 1e18, deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, name ); + return _staker; } } diff --git a/test/harnesses/StakerHarness.sol b/test/harnesses/StakerHarness.sol index 703dc364..4e15a14e 100644 --- a/test/harnesses/StakerHarness.sol +++ b/test/harnesses/StakerHarness.sol @@ -9,6 +9,8 @@ import {StakerDelegateSurrogateVotes} from "../../src/extensions/StakerDelegateS import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; +import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; +import {IERC20Delegates} from "../../src/interfaces/IERC20Delegates.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; import {DelegationSurrogate} from "../../src/DelegationSurrogate.sol"; @@ -18,20 +20,33 @@ contract StakerHarness is StakerOnBehalf, StakerDelegateSurrogateVotes { - constructor( - IERC20 _rewardsToken, - IERC20Staking _stakeToken, - IEarningPowerCalculator _earningPowerCalculator, - uint256 _maxBumpTip, + // constructor( + // IERC20 _rewardsToken, + // IERC20Staking _stakeToken, + // IEarningPowerCalculator _earningPowerCalculator, + // uint256 _maxBumpTip, + // address _admin, + // string memory _name + // ) + // {} + + function initialize( + IERC20 _rewardToken, + IERC20 _stakeToken, + uint256 _maxClaimFee, address _admin, + uint256 _maxBumpTip, + IEarningPowerCalculator _earningPowerCalculator, string memory _name - ) - Staker(_rewardsToken, _stakeToken, _earningPowerCalculator, _maxBumpTip, _admin) - StakerPermitAndStake(_stakeToken) - StakerDelegateSurrogateVotes(_stakeToken) - EIP712(_name, "1") - { - _setMaxClaimFee(1e18); + ) public initializer { + __Staker_init( + _rewardToken, _stakeToken, _maxClaimFee, _admin, _maxBumpTip, _earningPowerCalculator + ); + __StakerPermitAndStake_init(IERC20Permit(address(_stakeToken))); + __StakerDelegateSurrogateVotes_init(IERC20Delegates(address(_stakeToken))); + __EIP712_init(_name, "1"); + __Nonces_init(); + _setMaxClaimFee(_maxClaimFee); _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); } diff --git a/test/harnesses/StakerHarnessCapDeposits.sol b/test/harnesses/StakerHarnessCapDeposits.sol index 8531ee30..f9b19da7 100644 --- a/test/harnesses/StakerHarnessCapDeposits.sol +++ b/test/harnesses/StakerHarnessCapDeposits.sol @@ -7,21 +7,46 @@ import {StakerHarness} from "../../test/harnesses/StakerHarness.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; +import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; +import {IERC20Delegates} from "../../src/interfaces/IERC20Delegates.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; contract StakerHarnessCapDeposits is StakerHarness, StakerCapDeposits { - constructor( - IERC20 _rewardsToken, - IERC20Staking _stakeToken, - IEarningPowerCalculator _earningPowerCalculator, - uint256 _maxBumpTip, + // constructor( + // IERC20 _rewardsToken, + // IERC20Staking _stakeToken, + // IEarningPowerCalculator _earningPowerCalculator, + // uint256 _maxBumpTip, + // address _admin, + // string memory _name, + // uint256 _initialStakeCap + // ) + // StakerHarness(_rewardsToken, _stakeToken, _earningPowerCalculator, _maxBumpTip, _admin, + // _name) + // StakerCapDeposits(_initialStakeCap) + // {} + + function initialize( + IERC20 _rewardToken, + IERC20 _stakeToken, + uint256 _maxClaimFee, address _admin, + uint256 _maxBumpTip, + IEarningPowerCalculator _earningPowerCalculator, string memory _name, uint256 _initialStakeCap - ) - StakerHarness(_rewardsToken, _stakeToken, _earningPowerCalculator, _maxBumpTip, _admin, _name) - StakerCapDeposits(_initialStakeCap) - {} + ) public initializer { + __Staker_init( + _rewardToken, _stakeToken, _maxClaimFee, _admin, _maxBumpTip, _earningPowerCalculator + ); + __StakerPermitAndStake_init(IERC20Permit(address(_stakeToken))); + __StakerDelegateSurrogateVotes_init(IERC20Delegates(address(_stakeToken))); + __EIP712_init(_name, "1"); + __StakerCapDeposits_init(_initialStakeCap); + __Nonces_init(); + _setMaxClaimFee(_maxClaimFee); + _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); + } function _stake(address _depositor, uint256 _amount, address _delegatee, address _claimer) internal diff --git a/test/mocks/MockStakerHarness.sol b/test/mocks/MockStakerHarness.sol index a2ffcecb..760cc459 100644 --- a/test/mocks/MockStakerHarness.sol +++ b/test/mocks/MockStakerHarness.sol @@ -22,11 +22,7 @@ contract MockStakerHarness is Staker, StakerPermitAndStake, StakerDelegateSurrog IEarningPowerCalculator _earningPowerCalculator, uint256 _maxBumpTip, address _admin - ) - Staker(_rewardsToken, _stakerStakeToken, _earningPowerCalculator, _maxBumpTip, _admin) - StakerPermitAndStake(_permitAndStakeStakeToken) - StakerDelegateSurrogateVotes(_delegateSurrogateVotesStakeToken) - { + ) { _setMaxClaimFee(1e18); _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); } From c5787f6243946190c69bf0efb52fcc63575d3c01 Mon Sep 17 00:00:00 2001 From: keating Date: Wed, 13 Aug 2025 15:58:12 -0400 Subject: [PATCH 07/19] Passing tests except for bytecode comparison --- test/Staker.t.sol | 22 +++++++---- test/fakes/DeployBaseFake.sol | 1 + .../DeployBaseInvalidStakerAdminFake.sol | 3 +- ...bilityOracleEarningPowerCalculatorFake.sol | 1 + test/mocks/MockStakerHarness.sol | 39 ++++++++++++++++--- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/test/Staker.t.sol b/test/Staker.t.sol index c98eea27..3e0427f9 100644 --- a/test/Staker.t.sol +++ b/test/Staker.t.sol @@ -84,7 +84,13 @@ contract Constructor is StakerTest { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); StakerHarness _govStaker = new StakerHarness(); _govStaker.initialize( - rewardToken, govToken, 1e18, admin, maxBumpTip, earningPowerCalculator, _name + IERC20(_rewardToken), + IERC20(_stakeToken), + 1e18, + _admin, + _maxBumpTip, + IEarningPowerCalculator(_earningPowerCalculator), + _name ); assertEq(address(_govStaker.REWARD_TOKEN()), address(_rewardToken)); @@ -104,17 +110,18 @@ contract Constructor is StakerTest { ) public { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); vm.assume(address(_stakerStateToken) != address(_delegateSurrogateStakeToken)); + MockStakerHarness _staker = new MockStakerHarness(); vm.expectRevert( StakerDelegateSurrogateVotes.StakerDelegateSurrogateVotes__UnauthorizedToken.selector ); - new MockStakerHarness( + _staker.initialize( IERC20(_rewardToken), IERC20Staking(_stakerStateToken), IERC20Staking(_stakerStateToken), IERC20Staking(_delegateSurrogateStakeToken), IEarningPowerCalculator(_earningPowerCalculator), - _maxBumpTip, - _admin + _admin, + _maxBumpTip ); } @@ -128,15 +135,16 @@ contract Constructor is StakerTest { ) public { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); vm.assume(address(_stakerStateToken) != address(_permitAndStakeStakeToken)); + MockStakerHarness _staker = new MockStakerHarness(); vm.expectRevert(StakerPermitAndStake.StakerPermitAndStake__UnauthorizedToken.selector); - new MockStakerHarness( + _staker.initialize( IERC20(_rewardToken), IERC20Staking(_stakerStateToken), IERC20Staking(_permitAndStakeStakeToken), IERC20Staking(_stakerStateToken), IEarningPowerCalculator(_earningPowerCalculator), - _maxBumpTip, - _admin + _admin, + _maxBumpTip ); } } diff --git a/test/fakes/DeployBaseFake.sol b/test/fakes/DeployBaseFake.sol index 3e5f73cb..003b217a 100644 --- a/test/fakes/DeployBaseFake.sol +++ b/test/fakes/DeployBaseFake.sol @@ -85,5 +85,6 @@ contract DeployBaseFake is _config.earningPowerCalculator, name ); + return _staker; } } diff --git a/test/fakes/DeployBaseInvalidStakerAdminFake.sol b/test/fakes/DeployBaseInvalidStakerAdminFake.sol index 0a0a4b70..07180c25 100644 --- a/test/fakes/DeployBaseInvalidStakerAdminFake.sol +++ b/test/fakes/DeployBaseInvalidStakerAdminFake.sol @@ -80,10 +80,11 @@ contract DeployBaseInvalidStakerAdminFake is _config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, - deployer, + makeAddr("Anyone but the deployer"), _config.maxBumpTip, _config.earningPowerCalculator, name ); + return _staker; } } diff --git a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol index f9423541..dedb3c4d 100644 --- a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol +++ b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol @@ -106,5 +106,6 @@ contract DeployBinaryEligibilityOracleEarningPowerCalculatorFake is _config.earningPowerCalculator, name ); + return _staker; } } diff --git a/test/mocks/MockStakerHarness.sol b/test/mocks/MockStakerHarness.sol index 760cc459..565576d8 100644 --- a/test/mocks/MockStakerHarness.sol +++ b/test/mocks/MockStakerHarness.sol @@ -14,15 +14,44 @@ import {DelegationSurrogate} from "../../src/DelegationSurrogate.sol"; /// contract, unlike StakerHarness which uses the same token. This contract is used to test reverts /// when stake tokens mismatch. contract MockStakerHarness is Staker, StakerPermitAndStake, StakerDelegateSurrogateVotes { - constructor( + // constructor( + // IERC20 _rewardsToken, + // IERC20Staking _stakerStakeToken, + // IERC20Staking _permitAndStakeStakeToken, + // IERC20Staking _delegateSurrogateVotesStakeToken, + // IEarningPowerCalculator _earningPowerCalculator, + // uint256 _maxBumpTip, + // address _admin + // ) { + // _setMaxClaimFee(1e18); + // _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); + // } + // IERC20 _rewardsToken, + // IERC20Staking _stakerStakeToken, + // IERC20Staking _permitAndStakeStakeToken, + // IERC20Staking _delegateSurrogateVotesStakeToken, + // IEarningPowerCalculator _earningPowerCalculator, + // uint256 _maxBumpTip, + // address _admin + // + // Staker(_rewardsToken, _stakerStakeToken, _earningPowerCalculator, _maxBumpTip, _admin) + // StakerPermitAndStake(_permitAndStakeStakeToken) + // StakerDelegateSurrogateVotes(_delegateSurrogateVotesStakeToken) + // { + function initialize( IERC20 _rewardsToken, - IERC20Staking _stakerStakeToken, + IERC20Staking _stakeToken, IERC20Staking _permitAndStakeStakeToken, IERC20Staking _delegateSurrogateVotesStakeToken, IEarningPowerCalculator _earningPowerCalculator, - uint256 _maxBumpTip, - address _admin - ) { + address _admin, + uint256 _maxBumpTip + ) public initializer { + __Staker_init(_rewardsToken, _stakeToken, 1e18, _admin, _maxBumpTip, _earningPowerCalculator); + __StakerPermitAndStake_init(_permitAndStakeStakeToken); + __StakerDelegateSurrogateVotes_init(_delegateSurrogateVotesStakeToken); + // __EIP712_init("Staker", "1"); + // __Nonces_init(); _setMaxClaimFee(1e18); _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); } From e940b6a8b50a79dca8baef0f0fecac3f3437f3eb Mon Sep 17 00:00:00 2001 From: keating Date: Wed, 13 Aug 2025 20:33:53 -0400 Subject: [PATCH 08/19] Proxy changes --- test/Staker.invariants.t.sol | 12 +++- test/Staker.t.sol | 62 +++++++++---------- test/StakerOnBehalf.t.sol | 18 +++--- test/fakes/DeployBaseFake.sol | 19 +++--- .../DeployBaseInvalidStakerAdminFake.sol | 19 +++--- ...bilityOracleEarningPowerCalculatorFake.sol | 19 +++--- .../DeployMultipleRewardNotifiersFake.sol | 19 +++--- .../DeployTransferFromRewardNotifierFake.sol | 19 +++--- .../DeployTransferRewardNotifierFake.sol | 19 +++--- test/harnesses/StakerHarness.sol | 12 +--- test/mocks/MockStakerHarness.sol | 15 +---- 11 files changed, 109 insertions(+), 124 deletions(-) diff --git a/test/Staker.invariants.t.sol b/test/Staker.invariants.t.sol index 077b0f46..c3664577 100644 --- a/test/Staker.invariants.t.sol +++ b/test/Staker.invariants.t.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.23; import {Test} from "forge-std/Test.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import {IEarningPowerCalculator} from "../src/Staker.sol"; import {StakerHandler} from "./helpers/Staker.handler.sol"; @@ -34,10 +35,15 @@ contract StakerInvariants is Test { earningPowerCalculator = new MockFullEarningPowerCalculator(); vm.label(address(earningPowerCalculator), "Full Earning Power Calculator"); - govStaker = new StakerHarness(); - govStaker.initialize( - rewardToken, govToken, 1e18, rewardsNotifier, maxBumpTip, earningPowerCalculator, STAKER_NAME + StakerHarness implementation = new StakerHarness(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarness.initialize, + (rewardToken, govToken, 1e18, rewardsNotifier, maxBumpTip, earningPowerCalculator, STAKER_NAME) + ) ); + govStaker = StakerHarness(address(proxy)); handler = new StakerHandler(govStaker); bytes4[] memory selectors = new bytes4[](7); diff --git a/test/Staker.t.sol b/test/Staker.t.sol index 3e0427f9..376dafb7 100644 --- a/test/Staker.t.sol +++ b/test/Staker.t.sol @@ -13,6 +13,7 @@ import { StakerPermitAndStake } from "./mocks/MockStakerHarness.sol"; import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract StakerTest is StakerTestBase { StakerHarness govStaker; @@ -32,10 +33,14 @@ contract StakerTest is StakerTestBase { function _deployStaker() public virtual override(StakerTestBase) returns (Staker _staker) { StakerHarness _govStaker = new StakerHarness(); - _govStaker.initialize( - rewardToken, govToken, 1e18, admin, maxBumpTip, earningPowerCalculator, "Staker" - ); - return _govStaker; + ERC1967Proxy proxy = new ERC1967Proxy( + address(_govStaker), + abi.encodeCall( + StakerHarness.initialize, + (rewardToken, govToken, 1e18, admin, maxBumpTip, earningPowerCalculator, "Staker") + ) + ); + return StakerHarness(address(proxy)); } function _sign(uint256 _privateKey, bytes32 _messageHash) internal pure returns (bytes memory) { @@ -82,16 +87,15 @@ contract Constructor is StakerTest { string memory _name ) public { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); - StakerHarness _govStaker = new StakerHarness(); - _govStaker.initialize( - IERC20(_rewardToken), - IERC20(_stakeToken), - 1e18, - _admin, - _maxBumpTip, - IEarningPowerCalculator(_earningPowerCalculator), - _name + StakerHarness implementation = new StakerHarness(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarness.initialize, + (IERC20(_rewardToken), IERC20(_stakeToken), 1e18, _admin, _maxBumpTip, IEarningPowerCalculator(_earningPowerCalculator), _name) + ) ); + StakerHarness _govStaker = StakerHarness(address(proxy)); assertEq(address(_govStaker.REWARD_TOKEN()), address(_rewardToken)); assertEq(address(_govStaker.STAKE_TOKEN()), address(_stakeToken)); @@ -110,18 +114,16 @@ contract Constructor is StakerTest { ) public { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); vm.assume(address(_stakerStateToken) != address(_delegateSurrogateStakeToken)); - MockStakerHarness _staker = new MockStakerHarness(); + MockStakerHarness implementation = new MockStakerHarness(); vm.expectRevert( StakerDelegateSurrogateVotes.StakerDelegateSurrogateVotes__UnauthorizedToken.selector ); - _staker.initialize( - IERC20(_rewardToken), - IERC20Staking(_stakerStateToken), - IERC20Staking(_stakerStateToken), - IERC20Staking(_delegateSurrogateStakeToken), - IEarningPowerCalculator(_earningPowerCalculator), - _admin, - _maxBumpTip + new ERC1967Proxy( + address(implementation), + abi.encodeCall( + MockStakerHarness.initialize, + (IERC20(_rewardToken), IERC20Staking(_stakerStateToken), IERC20Staking(_stakerStateToken), IERC20Staking(_delegateSurrogateStakeToken), IEarningPowerCalculator(_earningPowerCalculator), _admin, _maxBumpTip) + ) ); } @@ -135,16 +137,14 @@ contract Constructor is StakerTest { ) public { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); vm.assume(address(_stakerStateToken) != address(_permitAndStakeStakeToken)); - MockStakerHarness _staker = new MockStakerHarness(); + MockStakerHarness implementation = new MockStakerHarness(); vm.expectRevert(StakerPermitAndStake.StakerPermitAndStake__UnauthorizedToken.selector); - _staker.initialize( - IERC20(_rewardToken), - IERC20Staking(_stakerStateToken), - IERC20Staking(_permitAndStakeStakeToken), - IERC20Staking(_stakerStateToken), - IEarningPowerCalculator(_earningPowerCalculator), - _admin, - _maxBumpTip + new ERC1967Proxy( + address(implementation), + abi.encodeCall( + MockStakerHarness.initialize, + (IERC20(_rewardToken), IERC20Staking(_stakerStateToken), IERC20Staking(_permitAndStakeStakeToken), IERC20Staking(_stakerStateToken), IEarningPowerCalculator(_earningPowerCalculator), _admin, _maxBumpTip) + ) ); } } diff --git a/test/StakerOnBehalf.t.sol b/test/StakerOnBehalf.t.sol index 50126db9..3d5cf8b9 100644 --- a/test/StakerOnBehalf.t.sol +++ b/test/StakerOnBehalf.t.sol @@ -7,6 +7,7 @@ import {StakerTest, StakerRewardsTest} from "./Staker.t.sol"; import {StakerHarness} from "./harnesses/StakerHarness.sol"; import {Staker, IERC20, IEarningPowerCalculator} from "../src/Staker.sol"; import {IERC20Staking} from "../src/interfaces/IERC20Staking.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract Domain_Separator is StakerTest { function _buildDomainSeparator(string memory _name, string memory _version, address _contract) @@ -33,16 +34,15 @@ contract Domain_Separator is StakerTest { string memory _name ) public { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); - StakerHarness _govStaker = new StakerHarness(); - _govStaker.initialize( - IERC20(_rewardToken), - IERC20Staking(_stakeToken), - 1e18, - _admin, - _maxBumpTip, - IEarningPowerCalculator(_earningPowerCalculator), - _name + StakerHarness implementation = new StakerHarness(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarness.initialize, + (IERC20(_rewardToken), IERC20Staking(_stakeToken), 1e18, _admin, _maxBumpTip, IEarningPowerCalculator(_earningPowerCalculator), _name) + ) ); + StakerHarness _govStaker = StakerHarness(address(proxy)); bytes32 _separator = _govStaker.DOMAIN_SEPARATOR(); bytes32 _expectedSeparator = _buildDomainSeparator(_name, "1", address(_govStaker)); diff --git a/test/fakes/DeployBaseFake.sol b/test/fakes/DeployBaseFake.sol index 003b217a..f273aff9 100644 --- a/test/fakes/DeployBaseFake.sol +++ b/test/fakes/DeployBaseFake.sol @@ -13,6 +13,7 @@ import {Staker} from "../../src/Staker.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract DeployBaseFake is DeployBase, @@ -75,16 +76,14 @@ contract DeployBaseFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - StakerHarness _staker = new StakerHarness(); - _staker.initialize( - _config.rewardToken, - IERC20Staking(address(_config.stakeToken)), - 1e18, - deployer, - _config.maxBumpTip, - _config.earningPowerCalculator, - name + StakerHarness implementation = new StakerHarness(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarness.initialize, + (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ) ); - return _staker; + return StakerHarness(address(proxy)); } } diff --git a/test/fakes/DeployBaseInvalidStakerAdminFake.sol b/test/fakes/DeployBaseInvalidStakerAdminFake.sol index 07180c25..d4b5a4e2 100644 --- a/test/fakes/DeployBaseInvalidStakerAdminFake.sol +++ b/test/fakes/DeployBaseInvalidStakerAdminFake.sol @@ -13,6 +13,7 @@ import {Staker} from "../../src/Staker.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract DeployBaseInvalidStakerAdminFake is DeployBase, @@ -75,16 +76,14 @@ contract DeployBaseInvalidStakerAdminFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - StakerHarness _staker = new StakerHarness(); - _staker.initialize( - _config.rewardToken, - IERC20Staking(address(_config.stakeToken)), - 1e18, - makeAddr("Anyone but the deployer"), - _config.maxBumpTip, - _config.earningPowerCalculator, - name + StakerHarness implementation = new StakerHarness(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarness.initialize, + (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, makeAddr("Anyone but the deployer"), _config.maxBumpTip, _config.earningPowerCalculator, name) + ) ); - return _staker; + return StakerHarness(address(proxy)); } } diff --git a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol index dedb3c4d..e9a05230 100644 --- a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol +++ b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol @@ -12,6 +12,7 @@ import {Staker} from "../../src/Staker.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract DeployBinaryEligibilityOracleEarningPowerCalculatorFake is DeployBase, @@ -96,16 +97,14 @@ contract DeployBinaryEligibilityOracleEarningPowerCalculatorFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - StakerHarness _staker = new StakerHarness(); - _staker.initialize( - _config.rewardToken, - IERC20Staking(address(_config.stakeToken)), - 1e18, - deployer, - _config.maxBumpTip, - _config.earningPowerCalculator, - name + StakerHarness implementation = new StakerHarness(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarness.initialize, + (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ) ); - return _staker; + return StakerHarness(address(proxy)); } } diff --git a/test/fakes/DeployMultipleRewardNotifiersFake.sol b/test/fakes/DeployMultipleRewardNotifiersFake.sol index 55427b97..398f7671 100644 --- a/test/fakes/DeployMultipleRewardNotifiersFake.sol +++ b/test/fakes/DeployMultipleRewardNotifiersFake.sol @@ -14,6 +14,7 @@ import {Staker} from "../../src/Staker.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract DeployMultipleRewardNotifiersFake is DeployBase, @@ -100,16 +101,14 @@ contract DeployMultipleRewardNotifiersFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - StakerHarness _staker = new StakerHarness(); - _staker.initialize( - _config.rewardToken, - IERC20Staking(address(_config.stakeToken)), - 1e18, - deployer, - _config.maxBumpTip, - _config.earningPowerCalculator, - name + StakerHarness implementation = new StakerHarness(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarness.initialize, + (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ) ); - return _staker; + return StakerHarness(address(proxy)); } } diff --git a/test/fakes/DeployTransferFromRewardNotifierFake.sol b/test/fakes/DeployTransferFromRewardNotifierFake.sol index 5e450f36..0983d455 100644 --- a/test/fakes/DeployTransferFromRewardNotifierFake.sol +++ b/test/fakes/DeployTransferFromRewardNotifierFake.sol @@ -12,6 +12,7 @@ import {Staker} from "../../src/Staker.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract DeployTransferFromRewardNotifierFake is DeployBase, @@ -74,16 +75,14 @@ contract DeployTransferFromRewardNotifierFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - StakerHarness _staker = new StakerHarness(); - _staker.initialize( - _config.rewardToken, - IERC20Staking(address(_config.stakeToken)), - 1e18, - deployer, - _config.maxBumpTip, - _config.earningPowerCalculator, - name + StakerHarness implementation = new StakerHarness(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarness.initialize, + (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ) ); - return _staker; + return StakerHarness(address(proxy)); } } diff --git a/test/fakes/DeployTransferRewardNotifierFake.sol b/test/fakes/DeployTransferRewardNotifierFake.sol index 642b651b..c63d9012 100644 --- a/test/fakes/DeployTransferRewardNotifierFake.sol +++ b/test/fakes/DeployTransferRewardNotifierFake.sol @@ -12,6 +12,7 @@ import {Staker} from "../../src/Staker.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract DeployTransferRewardNotifierFake is DeployBase, @@ -73,16 +74,14 @@ contract DeployTransferRewardNotifierFake is returns (Staker) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); - StakerHarness _staker = new StakerHarness(); - _staker.initialize( - _config.rewardToken, - IERC20Staking(address(_config.stakeToken)), - 1e18, - deployer, - _config.maxBumpTip, - _config.earningPowerCalculator, - name + StakerHarness implementation = new StakerHarness(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarness.initialize, + (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ) ); - return _staker; + return StakerHarness(address(proxy)); } } diff --git a/test/harnesses/StakerHarness.sol b/test/harnesses/StakerHarness.sol index 4e15a14e..e12a21fd 100644 --- a/test/harnesses/StakerHarness.sol +++ b/test/harnesses/StakerHarness.sol @@ -20,15 +20,9 @@ contract StakerHarness is StakerOnBehalf, StakerDelegateSurrogateVotes { - // constructor( - // IERC20 _rewardsToken, - // IERC20Staking _stakeToken, - // IEarningPowerCalculator _earningPowerCalculator, - // uint256 _maxBumpTip, - // address _admin, - // string memory _name - // ) - // {} + constructor() { + _disableInitializers(); + } function initialize( IERC20 _rewardToken, diff --git a/test/mocks/MockStakerHarness.sol b/test/mocks/MockStakerHarness.sol index 565576d8..8c4b2b35 100644 --- a/test/mocks/MockStakerHarness.sol +++ b/test/mocks/MockStakerHarness.sol @@ -14,18 +14,9 @@ import {DelegationSurrogate} from "../../src/DelegationSurrogate.sol"; /// contract, unlike StakerHarness which uses the same token. This contract is used to test reverts /// when stake tokens mismatch. contract MockStakerHarness is Staker, StakerPermitAndStake, StakerDelegateSurrogateVotes { - // constructor( - // IERC20 _rewardsToken, - // IERC20Staking _stakerStakeToken, - // IERC20Staking _permitAndStakeStakeToken, - // IERC20Staking _delegateSurrogateVotesStakeToken, - // IEarningPowerCalculator _earningPowerCalculator, - // uint256 _maxBumpTip, - // address _admin - // ) { - // _setMaxClaimFee(1e18); - // _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); - // } + constructor() { + _disableInitializers(); + } // IERC20 _rewardsToken, // IERC20Staking _stakerStakeToken, // IERC20Staking _permitAndStakeStakeToken, From e7488acffc563ede83d2d41ae9aeb0330befff6c Mon Sep 17 00:00:00 2001 From: keating Date: Wed, 13 Aug 2025 20:34:06 -0400 Subject: [PATCH 09/19] Proxy changes --- test/Staker.invariants.t.sol | 10 +++++- test/Staker.t.sol | 34 ++++++++++++++++--- test/StakerOnBehalf.t.sol | 10 +++++- test/fakes/DeployBaseFake.sol | 10 +++++- .../DeployBaseInvalidStakerAdminFake.sol | 10 +++++- ...bilityOracleEarningPowerCalculatorFake.sol | 10 +++++- .../DeployMultipleRewardNotifiersFake.sol | 10 +++++- .../DeployTransferFromRewardNotifierFake.sol | 10 +++++- .../DeployTransferRewardNotifierFake.sol | 10 +++++- test/mocks/MockStakerHarness.sol | 1 + 10 files changed, 102 insertions(+), 13 deletions(-) diff --git a/test/Staker.invariants.t.sol b/test/Staker.invariants.t.sol index c3664577..892ecf03 100644 --- a/test/Staker.invariants.t.sol +++ b/test/Staker.invariants.t.sol @@ -40,7 +40,15 @@ contract StakerInvariants is Test { address(implementation), abi.encodeCall( StakerHarness.initialize, - (rewardToken, govToken, 1e18, rewardsNotifier, maxBumpTip, earningPowerCalculator, STAKER_NAME) + ( + rewardToken, + govToken, + 1e18, + rewardsNotifier, + maxBumpTip, + earningPowerCalculator, + STAKER_NAME + ) ) ); govStaker = StakerHarness(address(proxy)); diff --git a/test/Staker.t.sol b/test/Staker.t.sol index 376dafb7..96046cdf 100644 --- a/test/Staker.t.sol +++ b/test/Staker.t.sol @@ -33,13 +33,13 @@ contract StakerTest is StakerTestBase { function _deployStaker() public virtual override(StakerTestBase) returns (Staker _staker) { StakerHarness _govStaker = new StakerHarness(); - ERC1967Proxy proxy = new ERC1967Proxy( + ERC1967Proxy proxy = new ERC1967Proxy( address(_govStaker), abi.encodeCall( StakerHarness.initialize, (rewardToken, govToken, 1e18, admin, maxBumpTip, earningPowerCalculator, "Staker") ) - ); + ); return StakerHarness(address(proxy)); } @@ -92,7 +92,15 @@ contract Constructor is StakerTest { address(implementation), abi.encodeCall( StakerHarness.initialize, - (IERC20(_rewardToken), IERC20(_stakeToken), 1e18, _admin, _maxBumpTip, IEarningPowerCalculator(_earningPowerCalculator), _name) + ( + IERC20(_rewardToken), + IERC20(_stakeToken), + 1e18, + _admin, + _maxBumpTip, + IEarningPowerCalculator(_earningPowerCalculator), + _name + ) ) ); StakerHarness _govStaker = StakerHarness(address(proxy)); @@ -122,7 +130,15 @@ contract Constructor is StakerTest { address(implementation), abi.encodeCall( MockStakerHarness.initialize, - (IERC20(_rewardToken), IERC20Staking(_stakerStateToken), IERC20Staking(_stakerStateToken), IERC20Staking(_delegateSurrogateStakeToken), IEarningPowerCalculator(_earningPowerCalculator), _admin, _maxBumpTip) + ( + IERC20(_rewardToken), + IERC20Staking(_stakerStateToken), + IERC20Staking(_stakerStateToken), + IERC20Staking(_delegateSurrogateStakeToken), + IEarningPowerCalculator(_earningPowerCalculator), + _admin, + _maxBumpTip + ) ) ); } @@ -143,7 +159,15 @@ contract Constructor is StakerTest { address(implementation), abi.encodeCall( MockStakerHarness.initialize, - (IERC20(_rewardToken), IERC20Staking(_stakerStateToken), IERC20Staking(_permitAndStakeStakeToken), IERC20Staking(_stakerStateToken), IEarningPowerCalculator(_earningPowerCalculator), _admin, _maxBumpTip) + ( + IERC20(_rewardToken), + IERC20Staking(_stakerStateToken), + IERC20Staking(_permitAndStakeStakeToken), + IERC20Staking(_stakerStateToken), + IEarningPowerCalculator(_earningPowerCalculator), + _admin, + _maxBumpTip + ) ) ); } diff --git a/test/StakerOnBehalf.t.sol b/test/StakerOnBehalf.t.sol index 3d5cf8b9..f92a6926 100644 --- a/test/StakerOnBehalf.t.sol +++ b/test/StakerOnBehalf.t.sol @@ -39,7 +39,15 @@ contract Domain_Separator is StakerTest { address(implementation), abi.encodeCall( StakerHarness.initialize, - (IERC20(_rewardToken), IERC20Staking(_stakeToken), 1e18, _admin, _maxBumpTip, IEarningPowerCalculator(_earningPowerCalculator), _name) + ( + IERC20(_rewardToken), + IERC20Staking(_stakeToken), + 1e18, + _admin, + _maxBumpTip, + IEarningPowerCalculator(_earningPowerCalculator), + _name + ) ) ); StakerHarness _govStaker = StakerHarness(address(proxy)); diff --git a/test/fakes/DeployBaseFake.sol b/test/fakes/DeployBaseFake.sol index f273aff9..8b033d5f 100644 --- a/test/fakes/DeployBaseFake.sol +++ b/test/fakes/DeployBaseFake.sol @@ -81,7 +81,15 @@ contract DeployBaseFake is address(implementation), abi.encodeCall( StakerHarness.initialize, - (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ( + _config.rewardToken, + IERC20Staking(address(_config.stakeToken)), + 1e18, + deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, + name + ) ) ); return StakerHarness(address(proxy)); diff --git a/test/fakes/DeployBaseInvalidStakerAdminFake.sol b/test/fakes/DeployBaseInvalidStakerAdminFake.sol index d4b5a4e2..3bcd549f 100644 --- a/test/fakes/DeployBaseInvalidStakerAdminFake.sol +++ b/test/fakes/DeployBaseInvalidStakerAdminFake.sol @@ -81,7 +81,15 @@ contract DeployBaseInvalidStakerAdminFake is address(implementation), abi.encodeCall( StakerHarness.initialize, - (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, makeAddr("Anyone but the deployer"), _config.maxBumpTip, _config.earningPowerCalculator, name) + ( + _config.rewardToken, + IERC20Staking(address(_config.stakeToken)), + 1e18, + makeAddr("Anyone but the deployer"), + _config.maxBumpTip, + _config.earningPowerCalculator, + name + ) ) ); return StakerHarness(address(proxy)); diff --git a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol index e9a05230..4a131788 100644 --- a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol +++ b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol @@ -102,7 +102,15 @@ contract DeployBinaryEligibilityOracleEarningPowerCalculatorFake is address(implementation), abi.encodeCall( StakerHarness.initialize, - (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ( + _config.rewardToken, + IERC20Staking(address(_config.stakeToken)), + 1e18, + deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, + name + ) ) ); return StakerHarness(address(proxy)); diff --git a/test/fakes/DeployMultipleRewardNotifiersFake.sol b/test/fakes/DeployMultipleRewardNotifiersFake.sol index 398f7671..09585f5c 100644 --- a/test/fakes/DeployMultipleRewardNotifiersFake.sol +++ b/test/fakes/DeployMultipleRewardNotifiersFake.sol @@ -106,7 +106,15 @@ contract DeployMultipleRewardNotifiersFake is address(implementation), abi.encodeCall( StakerHarness.initialize, - (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ( + _config.rewardToken, + IERC20Staking(address(_config.stakeToken)), + 1e18, + deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, + name + ) ) ); return StakerHarness(address(proxy)); diff --git a/test/fakes/DeployTransferFromRewardNotifierFake.sol b/test/fakes/DeployTransferFromRewardNotifierFake.sol index 0983d455..634f3322 100644 --- a/test/fakes/DeployTransferFromRewardNotifierFake.sol +++ b/test/fakes/DeployTransferFromRewardNotifierFake.sol @@ -80,7 +80,15 @@ contract DeployTransferFromRewardNotifierFake is address(implementation), abi.encodeCall( StakerHarness.initialize, - (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ( + _config.rewardToken, + IERC20Staking(address(_config.stakeToken)), + 1e18, + deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, + name + ) ) ); return StakerHarness(address(proxy)); diff --git a/test/fakes/DeployTransferRewardNotifierFake.sol b/test/fakes/DeployTransferRewardNotifierFake.sol index c63d9012..ebd8d0df 100644 --- a/test/fakes/DeployTransferRewardNotifierFake.sol +++ b/test/fakes/DeployTransferRewardNotifierFake.sol @@ -79,7 +79,15 @@ contract DeployTransferRewardNotifierFake is address(implementation), abi.encodeCall( StakerHarness.initialize, - (_config.rewardToken, IERC20Staking(address(_config.stakeToken)), 1e18, deployer, _config.maxBumpTip, _config.earningPowerCalculator, name) + ( + _config.rewardToken, + IERC20Staking(address(_config.stakeToken)), + 1e18, + deployer, + _config.maxBumpTip, + _config.earningPowerCalculator, + name + ) ) ); return StakerHarness(address(proxy)); diff --git a/test/mocks/MockStakerHarness.sol b/test/mocks/MockStakerHarness.sol index 8c4b2b35..312f39c0 100644 --- a/test/mocks/MockStakerHarness.sol +++ b/test/mocks/MockStakerHarness.sol @@ -29,6 +29,7 @@ contract MockStakerHarness is Staker, StakerPermitAndStake, StakerDelegateSurrog // StakerPermitAndStake(_permitAndStakeStakeToken) // StakerDelegateSurrogateVotes(_delegateSurrogateVotesStakeToken) // { + function initialize( IERC20 _rewardsToken, IERC20Staking _stakeToken, From 0ee5b71cfc4225010d83c9ec46f4ce91a48749bd Mon Sep 17 00:00:00 2001 From: keating Date: Wed, 13 Aug 2025 20:39:38 -0400 Subject: [PATCH 10/19] Final proxy changes --- test/StakerCapDeposits.t.sol | 82 ++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/test/StakerCapDeposits.t.sol b/test/StakerCapDeposits.t.sol index 91bee8ca..17bd532e 100644 --- a/test/StakerCapDeposits.t.sol +++ b/test/StakerCapDeposits.t.sol @@ -7,24 +7,31 @@ import {StakerHarnessCapDeposits} from "./harnesses/StakerHarnessCapDeposits.sol import {Staker} from "../src/Staker.sol"; import {StakerCapDeposits} from "../src/extensions/StakerCapDeposits.sol"; import {DelegationSurrogate} from "../src/DelegationSurrogate.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract StakerCapDepositsTest is StakerTestBase { StakerHarnessCapDeposits govStaker; uint256 initialTotalStakeCap = 1_000_000e18; function _deployStaker() public virtual override(StakerTestBase) returns (Staker _staker) { - StakerHarnessCapDeposits _govStaker = new StakerHarnessCapDeposits(); - _govStaker.initialize( - rewardToken, - govToken, - 1e18, - admin, - maxBumpTip, - earningPowerCalculator, - "Staker", - initialTotalStakeCap + StakerHarnessCapDeposits implementation = new StakerHarnessCapDeposits(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarnessCapDeposits.initialize, + ( + rewardToken, + govToken, + 1e18, + admin, + maxBumpTip, + earningPowerCalculator, + "Staker", + initialTotalStakeCap + ) + ) ); - return _govStaker; + return StakerHarnessCapDeposits(address(proxy)); } function setUp() public virtual override(StakerTestBase) { @@ -42,33 +49,46 @@ contract Constructor is StakerCapDepositsTest { function testFuzz_SetsTheInitialTotalStakeCapToArbitraryValues(uint256 _initialTotalStakeCap) public { - StakerHarnessCapDeposits _govStaker = new StakerHarnessCapDeposits(); - _govStaker.initialize( - rewardToken, - govToken, - 1e18, - admin, - maxBumpTip, - earningPowerCalculator, - "Staker", - _initialTotalStakeCap + StakerHarnessCapDeposits implementation = new StakerHarnessCapDeposits(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarnessCapDeposits.initialize, + ( + rewardToken, + govToken, + 1e18, + admin, + maxBumpTip, + earningPowerCalculator, + "Staker", + _initialTotalStakeCap + ) + ) ); + StakerHarnessCapDeposits _govStaker = StakerHarnessCapDeposits(address(proxy)); assertEq(_govStaker.totalStakeCap(), _initialTotalStakeCap); } function testFuzz_EmitsATotalStakeCapSetEvent(uint256 _initialTotalStakeCap) public { vm.expectEmit(); emit StakerCapDeposits.TotalStakeCapSet(0, _initialTotalStakeCap); - StakerHarnessCapDeposits _govStaker = new StakerHarnessCapDeposits(); - _govStaker.initialize( - rewardToken, - govToken, - 1e18, - admin, - maxBumpTip, - earningPowerCalculator, - "Staker", - _initialTotalStakeCap + StakerHarnessCapDeposits implementation = new StakerHarnessCapDeposits(); + ERC1967Proxy proxy = new ERC1967Proxy( + address(implementation), + abi.encodeCall( + StakerHarnessCapDeposits.initialize, + ( + rewardToken, + govToken, + 1e18, + admin, + maxBumpTip, + earningPowerCalculator, + "Staker", + _initialTotalStakeCap + ) + ) ); } } From a4623792a2f40fb1dbe5a82049047f81a0dad753 Mon Sep 17 00:00:00 2001 From: keating Date: Wed, 13 Aug 2025 21:59:22 -0400 Subject: [PATCH 11/19] Add Upgradeable suffix --- src/{Staker.sol => StakerUpgradeable.sol} | 8 +- ...s.sol => StakerCapDepositsUpgradeable.sol} | 31 +- ...akerDelegateSurrogateVotesUpgradeable.sol} | 18 +- ...half.sol => StakerOnBehalfUpgradeable.sol} | 23 +- ...ol => StakerPermitAndStakeUpgradeable.sol} | 17 +- src/script/DeployBase.sol | 12 +- src/script/DeployStaker.sol | 1 - .../notifiers/DeployMintRewardNotifier.sol | 4 +- .../DeployTransferFromRewardNotifier.sol | 4 +- .../DeployTransferRewardNotifier.sol | 4 +- test/Staker.invariants.t.sol | 2 +- test/Staker.t.sol | 583 ++++++++++-------- test/StakerCapDeposits.t.sol | 59 +- test/StakerOnBehalf.t.sol | 116 ++-- test/StakerTestBase.sol | 26 +- test/fakes/DeployBaseFake.sol | 4 +- .../DeployBaseInvalidStakerAdminFake.sol | 4 +- ...bilityOracleEarningPowerCalculatorFake.sol | 4 +- .../DeployMultipleRewardNotifiersFake.sol | 6 +- .../DeployTransferFromRewardNotifierFake.sol | 4 +- .../DeployTransferRewardNotifierFake.sol | 4 +- test/gas-reports/Staker.g.sol | 4 +- test/harnesses/StakerHarness.sol | 24 +- test/harnesses/StakerHarnessCapDeposits.sol | 22 +- test/helpers/DepositIdSet.sol | 10 +- test/helpers/Staker.handler.sol | 26 +- test/mocks/MockStakerHarness.sol | 22 +- test/script/DeployBase.t.sol | 6 +- ...gibilityOracleEarningPowerCalculator.t.sol | 4 +- test/script/DeployMintRewardNotifier.sol | 6 +- .../DeployTransferFromRewardNotifier.t.sol | 6 +- .../script/DeployTransferRewardNotifier.t.sol | 6 +- 32 files changed, 574 insertions(+), 496 deletions(-) rename src/{Staker.sol => StakerUpgradeable.sol} (99%) rename src/extensions/{StakerCapDeposits.sol => StakerCapDepositsUpgradeable.sol} (80%) rename src/extensions/{StakerDelegateSurrogateVotes.sol => StakerDelegateSurrogateVotesUpgradeable.sol} (82%) rename src/extensions/{StakerOnBehalf.sol => StakerOnBehalfUpgradeable.sol} (94%) rename src/extensions/{StakerPermitAndStake.sol => StakerPermitAndStakeUpgradeable.sol} (87%) diff --git a/src/Staker.sol b/src/StakerUpgradeable.sol similarity index 99% rename from src/Staker.sol rename to src/StakerUpgradeable.sol index f254ee9a..7f4a1738 100644 --- a/src/Staker.sol +++ b/src/StakerUpgradeable.sol @@ -35,7 +35,7 @@ import {MulticallUpgradeable} from /// the Staker contract is a DAO, which is the expected common case, this means the DAO has /// the ability to define and iterate on its own definition of active, aligned participation, /// and to decide how to reward it. -abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { +abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgradeable { using SafeCast for uint256; /// @notice A unique identifier assigned to each deposit. @@ -270,7 +270,7 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { } } - function __Staker_init( + function __StakerUpgradeable_init( IERC20 _rewardToken, IERC20 _stakeToken, uint256 _maxClaimFee, @@ -278,12 +278,12 @@ abstract contract Staker is INotifiableRewardReceiver, MulticallUpgradeable { uint256 _maxBumpTip, IEarningPowerCalculator _earningPowerCalculator ) internal onlyInitializing { - __Staker_init_unchained( + __StakerUpgradeable_init_unchained( _rewardToken, _stakeToken, _maxClaimFee, _admin, _maxBumpTip, _earningPowerCalculator ); } - function __Staker_init_unchained( + function __StakerUpgradeable_init_unchained( IERC20 _rewardToken, IERC20 _stakeToken, uint256 _maxClaimFee, diff --git a/src/extensions/StakerCapDeposits.sol b/src/extensions/StakerCapDepositsUpgradeable.sol similarity index 80% rename from src/extensions/StakerCapDeposits.sol rename to src/extensions/StakerCapDepositsUpgradeable.sol index 3354f9c2..16c12833 100644 --- a/src/extensions/StakerCapDeposits.sol +++ b/src/extensions/StakerCapDepositsUpgradeable.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.23; -import {Staker} from "../Staker.sol"; +import {StakerUpgradeable} from "../StakerUpgradeable.sol"; /// @title StakerCapDeposits /// @author [ScopeLift](https://scopelift.co) @@ -11,7 +11,7 @@ import {Staker} from "../Staker.sol"; /// The contract allows the admin to configure a total stake cap that applies across all deposits. /// Any attempt to stake tokens that would cause the total staked amount to exceed this cap will /// revert. -abstract contract StakerCapDeposits is Staker { +abstract contract StakerCapDepositsUpgradeable is StakerUpgradeable { /// @notice Emitted when the total stake cap is changed. /// @param oldTotalStakeCap The previous maximum total stake allowed. /// @param newTotalStakeCap The new maximum total stake allowed. @@ -19,7 +19,7 @@ abstract contract StakerCapDeposits is Staker { /// @notice Thrown when a staking operation would cause the total staked amount to exceed the /// cap. - error StakerCapDeposits__CapExceeded(); + error StakerCapDepositsUpgradeable__CapExceeded(); struct StakerCapDepositsStorage { /// @notice The maximum total amount of tokens that can be staked across all deposits. @@ -42,11 +42,14 @@ abstract contract StakerCapDeposits is Staker { } /// @param _initialTotalStakeCap The initial maximum total stake allowed. - function __StakerCapDeposits_init(uint256 _initialTotalStakeCap) internal onlyInitializing { - __StakerCapDeposits_init_unchained(_initialTotalStakeCap); + function __StakerCapDepositsUpgradeable_init(uint256 _initialTotalStakeCap) + internal + onlyInitializing + { + __StakerCapDepositsUpgradeable_init_unchained(_initialTotalStakeCap); } - function __StakerCapDeposits_init_unchained(uint256 _initialTotalStakeCap) + function __StakerCapDepositsUpgradeable_init_unchained(uint256 _initialTotalStakeCap) internal onlyInitializing { @@ -75,27 +78,27 @@ abstract contract StakerCapDeposits is Staker { $._totalStakeCap = _newTotalStakeCap; } - /// @inheritdoc Staker + /// @inheritdoc StakerUpgradeable /// @dev Checks if the stake would exceed the total stake cap before proceeding. function _stake(address _depositor, uint256 _amount, address _delegatee, address _claimer) internal virtual - override(Staker) + override(StakerUpgradeable) returns (DepositIdentifier _depositId) { _revertIfCapExceeded(_amount); - return Staker._stake(_depositor, _amount, _delegatee, _claimer); + return StakerUpgradeable._stake(_depositor, _amount, _delegatee, _claimer); } - /// @inheritdoc Staker + /// @inheritdoc StakerUpgradeable /// @dev Checks if the additional stake would exceed the total stake cap before proceeding. function _stakeMore(Deposit storage deposit, DepositIdentifier _depositId, uint256 _amount) internal virtual - override(Staker) + override(StakerUpgradeable) { _revertIfCapExceeded(_amount); - Staker._stakeMore(deposit, _depositId, _amount); + StakerUpgradeable._stakeMore(deposit, _depositId, _amount); } /// @notice Internal helper method which reverts if adding a given stake amount would exceed the @@ -105,6 +108,8 @@ abstract contract StakerCapDeposits is Staker { /// exceed the cap. function _revertIfCapExceeded(uint256 _amount) internal view virtual { StakerCapDepositsStorage storage $ = _getStakerCapDepositsStorage(); - if ((totalStaked() + _amount) > $._totalStakeCap) revert StakerCapDeposits__CapExceeded(); + if ((totalStaked() + _amount) > $._totalStakeCap) { + revert StakerCapDepositsUpgradeable__CapExceeded(); + } } } diff --git a/src/extensions/StakerDelegateSurrogateVotes.sol b/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol similarity index 82% rename from src/extensions/StakerDelegateSurrogateVotes.sol rename to src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol index ef64a4cc..42e8a0e5 100644 --- a/src/extensions/StakerDelegateSurrogateVotes.sol +++ b/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol @@ -3,19 +3,19 @@ pragma solidity ^0.8.23; import {DelegationSurrogate} from "../DelegationSurrogate.sol"; import {DelegationSurrogateVotes} from "../DelegationSurrogateVotes.sol"; -import {Staker} from "../Staker.sol"; +import {StakerUpgradeable} from "../StakerUpgradeable.sol"; import {IERC20Delegates} from "../interfaces/IERC20Delegates.sol"; /// @title StakerDelegateSurrogateVotes /// @author [ScopeLift](https://scopelift.co) /// @notice This contract extension adds delegation surrogates to the Staker base /// contract, allowing staked tokens to be delegated to a specific delegate. -abstract contract StakerDelegateSurrogateVotes is Staker { +abstract contract StakerDelegateSurrogateVotesUpgradeable is StakerUpgradeable { /// @notice Emitted when a surrogate contract is deployed. event SurrogateDeployed(address indexed delegatee, address indexed surrogate); /// @notice Thrown if an inheritor misconfigures the staking token on deployment. - error StakerDelegateSurrogateVotes__UnauthorizedToken(); + error StakerDelegateSurrogateVotesUpgradeable__UnauthorizedToken(); struct StakerDelegateSurrogateVotesStorage { /// @notice Maps the account of each governance delegate with the surrogate contract which holds @@ -38,23 +38,23 @@ abstract contract StakerDelegateSurrogateVotes is Staker { } } - function __StakerDelegateSurrogateVotes_init(IERC20Delegates _votingToken) + function __StakerDelegateSurrogateVotesUpgradeable_init(IERC20Delegates _votingToken) internal onlyInitializing { - __StakerDelegateSurrogateVotes_init_unchained(_votingToken); + __StakerDelegateSurrogateVotesUpgradeable_init_unchained(_votingToken); } - function __StakerDelegateSurrogateVotes_init_unchained(IERC20Delegates _votingToken) + function __StakerDelegateSurrogateVotesUpgradeable_init_unchained(IERC20Delegates _votingToken) internal onlyInitializing { if (address(STAKE_TOKEN()) != address(_votingToken)) { - revert StakerDelegateSurrogateVotes__UnauthorizedToken(); + revert StakerDelegateSurrogateVotesUpgradeable__UnauthorizedToken(); } } - /// @inheritdoc Staker + /// @inheritdoc StakerUpgradeable function surrogates(address _delegatee) public view override returns (DelegationSurrogate) { StakerDelegateSurrogateVotesStorage storage $ = _getStakerDelegateSurrogateStorage(); return $._storedSurrogates[_delegatee]; @@ -68,7 +68,7 @@ abstract contract StakerDelegateSurrogateVotes is Staker { return $._storedSurrogates[_delegatee]; } - /// @inheritdoc Staker + /// @inheritdoc StakerUpgradeable function _fetchOrDeploySurrogate(address _delegatee) internal virtual diff --git a/src/extensions/StakerOnBehalf.sol b/src/extensions/StakerOnBehalfUpgradeable.sol similarity index 94% rename from src/extensions/StakerOnBehalf.sol rename to src/extensions/StakerOnBehalfUpgradeable.sol index 10476e09..ea4e7778 100644 --- a/src/extensions/StakerOnBehalf.sol +++ b/src/extensions/StakerOnBehalfUpgradeable.sol @@ -1,9 +1,8 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.23; -import {Staker} from "../Staker.sol"; +import {StakerUpgradeable} from "../StakerUpgradeable.sol"; import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; -import {Nonces} from "@openzeppelin/contracts/utils/Nonces.sol"; import {EIP712Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol"; import {NoncesUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/NoncesUpgradeable.sol"; @@ -16,12 +15,16 @@ import {NoncesUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/Nonce /// altering delegatees and claimers, and claiming rewards. Each operation requires a unique /// signature that is validated against the appropriate signer (owner or claimer) before /// execution. -abstract contract StakerOnBehalf is Staker, EIP712Upgradeable, NoncesUpgradeable { +abstract contract StakerOnBehalfUpgradeable is + StakerUpgradeable, + EIP712Upgradeable, + NoncesUpgradeable +{ /// @notice Thrown when an onBehalf method is called with a deadline that has expired. - error StakerOnBehalf__ExpiredDeadline(); + error StakerOnBehalfUpgradeable__ExpiredDeadline(); /// @notice Thrown if a caller supplies an invalid signature to a method that requires one. - error StakerOnBehalf__InvalidSignature(); + error StakerOnBehalfUpgradeable__InvalidSignature(); /// @notice Type hash used when encoding data for `stakeOnBehalf` calls. bytes32 public constant STAKE_TYPEHASH = keccak256( @@ -53,9 +56,9 @@ abstract contract StakerOnBehalf is Staker, EIP712Upgradeable, NoncesUpgradeable return _domainSeparatorV4(); } - function __StakerOnBehalf_init() internal onlyInitializing {} + function __StakerOnBehalfUpgradeable_init() internal onlyInitializing {} - function __StakerOnBehalf_init_unchained() internal onlyInitializing {} + function __StakerOnBehalfUpgradeable_init_unchained() internal onlyInitializing {} /// @notice Allows an address to increment their nonce and therefore invalidate any pending signed /// actions. @@ -277,7 +280,7 @@ abstract contract StakerOnBehalf is Staker, EIP712Upgradeable, NoncesUpgradeable ); bool _isValidOwnerClaim = SignatureChecker.isValidSignatureNow(deposit.owner, _ownerHash, _signature); - if (!_isValidOwnerClaim) revert StakerOnBehalf__InvalidSignature(); + if (!_isValidOwnerClaim) revert StakerOnBehalfUpgradeable__InvalidSignature(); return _claimReward(_depositId, deposit, deposit.owner); } @@ -285,7 +288,7 @@ abstract contract StakerOnBehalf is Staker, EIP712Upgradeable, NoncesUpgradeable /// provided deadline has passed. /// @param _deadline The timestamp that represents when the operation should no longer be valid. function _revertIfPastDeadline(uint256 _deadline) internal view virtual { - if (block.timestamp > _deadline) revert StakerOnBehalf__ExpiredDeadline(); + if (block.timestamp > _deadline) revert StakerOnBehalfUpgradeable__ExpiredDeadline(); } /// @notice Internal helper method which reverts with Staker__InvalidSignature if the @@ -299,6 +302,6 @@ abstract contract StakerOnBehalf is Staker, EIP712Upgradeable, NoncesUpgradeable virtual { bool _isValid = SignatureChecker.isValidSignatureNow(_signer, _hash, _signature); - if (!_isValid) revert StakerOnBehalf__InvalidSignature(); + if (!_isValid) revert StakerOnBehalfUpgradeable__InvalidSignature(); } } diff --git a/src/extensions/StakerPermitAndStake.sol b/src/extensions/StakerPermitAndStakeUpgradeable.sol similarity index 87% rename from src/extensions/StakerPermitAndStake.sol rename to src/extensions/StakerPermitAndStakeUpgradeable.sol index 0bafc0c4..f478fba7 100644 --- a/src/extensions/StakerPermitAndStake.sol +++ b/src/extensions/StakerPermitAndStakeUpgradeable.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.23; -import {Staker} from "../Staker.sol"; +import {StakerUpgradeable} from "../StakerUpgradeable.sol"; import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; /// @title StakerPermitAndStake @@ -11,21 +11,24 @@ import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC2 /// The permit functionality is used in conjunction with staking operations, improving UX by /// enabling users to approve and stake tokens in a single transaction. Note that this extension /// requires the stake token to support EIP-2612 permit functionality. -abstract contract StakerPermitAndStake is Staker { +abstract contract StakerPermitAndStakeUpgradeable is StakerUpgradeable { /// @notice Thrown if an inheritor misconfigures the staking token on deployment. - error StakerPermitAndStake__UnauthorizedToken(); + error StakerPermitAndStakeUpgradeable__UnauthorizedToken(); /// @param _permitToken The token that is used for staking, which must support EIP-2612. It also - function __StakerPermitAndStake_init(IERC20Permit _permitToken) internal onlyInitializing { - __StakerPermitAndStake_init_unchained(_permitToken); + function __StakerPermitAndStakeUpgradeable_init(IERC20Permit _permitToken) + internal + onlyInitializing + { + __StakerPermitAndStakeUpgradeable_init_unchained(_permitToken); } - function __StakerPermitAndStake_init_unchained(IERC20Permit _permitToken) + function __StakerPermitAndStakeUpgradeable_init_unchained(IERC20Permit _permitToken) internal onlyInitializing { if (address(STAKE_TOKEN()) != address(_permitToken)) { - revert StakerPermitAndStake__UnauthorizedToken(); + revert StakerPermitAndStakeUpgradeable__UnauthorizedToken(); } } diff --git a/src/script/DeployBase.sol b/src/script/DeployBase.sol index 7aabee66..ca18d146 100644 --- a/src/script/DeployBase.sol +++ b/src/script/DeployBase.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.23; import {Script} from "forge-std/Script.sol"; import {IEarningPowerCalculator} from "../interfaces/IEarningPowerCalculator.sol"; -import {Staker} from "../Staker.sol"; +import {StakerUpgradeable} from "../StakerUpgradeable.sol"; /// @title DeployBase /// @author [ScopeLift](https://scopelift.co) @@ -43,22 +43,22 @@ abstract contract DeployBase is Script { function _deployStaker(IEarningPowerCalculator _earningPowerCalculator) internal virtual - returns (Staker); + returns (StakerUpgradeable); /// @notice An interface method that deploys the earning power contract for the staking system. /// @return The earning power calculator contract. function _deployEarningPowerCalculator() internal virtual returns (IEarningPowerCalculator); /// @notice An interface method that deploys the reward notifiers. - /// @param _staker The Staker for the staking system. + /// @param _staker The StakerUpgradeable for the staking system. /// @dev When this method is overridden make sure to add the reward notifier to the /// `rewardNotifiers` array. - function _deployRewardNotifiers(Staker _staker) internal virtual; + function _deployRewardNotifiers(StakerUpgradeable _staker) internal virtual; /// @notice The method that is executed when the script runs which deploys the entire staking /// system. /// @return The Staker contract, earning power calculator, and array of reward notifiers. - function run() public returns (IEarningPowerCalculator, Staker, address[] memory) { + function run() public returns (IEarningPowerCalculator, StakerUpgradeable, address[] memory) { uint256 deployerPrivateKey = vm.envOr( "DEPLOYER_PRIVATE_KEY", uint256(0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80) @@ -67,7 +67,7 @@ abstract contract DeployBase is Script { deployer = vm.rememberKey(deployerPrivateKey); vm.startBroadcast(deployer); IEarningPowerCalculator _earningPowerCalculator = _deployEarningPowerCalculator(); - Staker _staker = _deployStaker(_earningPowerCalculator); + StakerUpgradeable _staker = _deployStaker(_earningPowerCalculator); if (_staker.admin() != deployer) revert DeployBase__InvalidInitialStakerAdmin(); _deployRewardNotifiers(_staker); diff --git a/src/script/DeployStaker.sol b/src/script/DeployStaker.sol index 46530626..2ed78f7c 100644 --- a/src/script/DeployStaker.sol +++ b/src/script/DeployStaker.sol @@ -5,7 +5,6 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {DeployBase} from "./DeployBase.sol"; import {IEarningPowerCalculator} from "../interfaces/IEarningPowerCalculator.sol"; -import {Staker} from "../Staker.sol"; /// @title DeployStaker /// @author [ScopeLift](https://scopelift.co) diff --git a/src/script/notifiers/DeployMintRewardNotifier.sol b/src/script/notifiers/DeployMintRewardNotifier.sol index c0b0024e..cd391f85 100644 --- a/src/script/notifiers/DeployMintRewardNotifier.sol +++ b/src/script/notifiers/DeployMintRewardNotifier.sol @@ -5,7 +5,7 @@ import {INotifiableRewardReceiver} from "../../interfaces/INotifiableRewardRecei import {IMintable} from "../../interfaces/IMintable.sol"; import {DeployBase} from "../DeployBase.sol"; import {MintRewardNotifier} from "../../notifiers/MintRewardNotifier.sol"; -import {Staker} from "../../Staker.sol"; +import {StakerUpgradeable} from "../../StakerUpgradeable.sol"; /// @title DeployMintRewardNotifer /// @author [ScopeLift](https://scopelift.co) @@ -40,7 +40,7 @@ abstract contract DeployMintRewardNotifier is DeployBase { /// @inheritdoc DeployBase /// @dev When this method is overridden make sure to call super so it is added to the reward /// notifiers array. - function _deployRewardNotifiers(Staker _staker) internal virtual override { + function _deployRewardNotifiers(StakerUpgradeable _staker) internal virtual override { MintRewardNotifierConfiguration memory _config = _mintRewardNotifierConfiguration(); MintRewardNotifier _notifier = new MintRewardNotifier( INotifiableRewardReceiver(address(_staker)), diff --git a/src/script/notifiers/DeployTransferFromRewardNotifier.sol b/src/script/notifiers/DeployTransferFromRewardNotifier.sol index f9a6ff6f..bafed3f1 100644 --- a/src/script/notifiers/DeployTransferFromRewardNotifier.sol +++ b/src/script/notifiers/DeployTransferFromRewardNotifier.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.23; import {INotifiableRewardReceiver} from "../../interfaces/INotifiableRewardReceiver.sol"; import {TransferFromRewardNotifier} from "../../notifiers/TransferFromRewardNotifier.sol"; import {DeployBase} from "../DeployBase.sol"; -import {Staker} from "../../Staker.sol"; +import {StakerUpgradeable} from "../../StakerUpgradeable.sol"; /// @title DeployTransferFromRewardNotifier /// @author [ScopeLift](https://scopelift.co) @@ -38,7 +38,7 @@ abstract contract DeployTransferFromRewardNotifier is DeployBase { /// @inheritdoc DeployBase /// @dev When this method is overridden make sure to call super so it is added to the reward /// notifiers array. - function _deployRewardNotifiers(Staker _staker) internal virtual override { + function _deployRewardNotifiers(StakerUpgradeable _staker) internal virtual override { TransferFromRewardNotifierConfiguration memory _config = _transferFromRewardNotifierConfiguration(); TransferFromRewardNotifier _notifier = new TransferFromRewardNotifier( diff --git a/src/script/notifiers/DeployTransferRewardNotifier.sol b/src/script/notifiers/DeployTransferRewardNotifier.sol index bdf301ed..b60d98d3 100644 --- a/src/script/notifiers/DeployTransferRewardNotifier.sol +++ b/src/script/notifiers/DeployTransferRewardNotifier.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.23; import {INotifiableRewardReceiver} from "../../interfaces/INotifiableRewardReceiver.sol"; import {TransferRewardNotifier} from "../../notifiers/TransferRewardNotifier.sol"; import {DeployBase} from "../DeployBase.sol"; -import {Staker} from "../../Staker.sol"; +import {StakerUpgradeable} from "../../StakerUpgradeable.sol"; /// @title DeployTransferRewardNotifier /// @author [ScopeLift](https://scopelift.co) @@ -36,7 +36,7 @@ abstract contract DeployTransferRewardNotifier is DeployBase { /// @inheritdoc DeployBase /// @dev When this method is overridden make sure to call super so it is added to the reward /// notifiers array. - function _deployRewardNotifiers(Staker _staker) internal virtual override { + function _deployRewardNotifiers(StakerUpgradeable _staker) internal virtual override { TransferRewardNotifierConfiguration memory _config = _transferRewardNotifierConfiguration(); TransferRewardNotifier _notifier = new TransferRewardNotifier( INotifiableRewardReceiver(address(_staker)), diff --git a/test/Staker.invariants.t.sol b/test/Staker.invariants.t.sol index 892ecf03..ab8ab7e7 100644 --- a/test/Staker.invariants.t.sol +++ b/test/Staker.invariants.t.sol @@ -5,7 +5,7 @@ import {Test} from "forge-std/Test.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {IEarningPowerCalculator} from "../src/Staker.sol"; +import {IEarningPowerCalculator} from "../src/StakerUpgradeable.sol"; import {StakerHandler} from "./helpers/Staker.handler.sol"; import {StakerHarness} from "./harnesses/StakerHarness.sol"; import {ERC20VotesMock} from "./mocks/MockERC20Votes.sol"; diff --git a/test/Staker.t.sol b/test/Staker.t.sol index 96046cdf..2b68c1ee 100644 --- a/test/Staker.t.sol +++ b/test/Staker.t.sol @@ -3,14 +3,14 @@ pragma solidity ^0.8.23; import {Vm, Test, stdStorage, StdStorage, console2, stdError} from "forge-std/Test.sol"; import {StakerTestBase} from "./StakerTestBase.sol"; -import {Staker, IERC20, IEarningPowerCalculator} from "../src/Staker.sol"; +import {StakerUpgradeable, IERC20, IEarningPowerCalculator} from "../src/StakerUpgradeable.sol"; import {IERC20Staking} from "../src/interfaces/IERC20Staking.sol"; import {DelegationSurrogate} from "../src/DelegationSurrogate.sol"; import {StakerHarness} from "./harnesses/StakerHarness.sol"; import { MockStakerHarness, - StakerDelegateSurrogateVotes, - StakerPermitAndStake + StakerDelegateSurrogateVotesUpgradeable, + StakerPermitAndStakeUpgradeable } from "./mocks/MockStakerHarness.sol"; import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; @@ -31,7 +31,12 @@ contract StakerTest is StakerTestBase { EIP712_DOMAIN_SEPARATOR = govStaker.DOMAIN_SEPARATOR(); } - function _deployStaker() public virtual override(StakerTestBase) returns (Staker _staker) { + function _deployStaker() + public + virtual + override(StakerTestBase) + returns (StakerUpgradeable _staker) + { StakerHarness _govStaker = new StakerHarness(); ERC1967Proxy proxy = new ERC1967Proxy( address(_govStaker), @@ -124,7 +129,9 @@ contract Constructor is StakerTest { vm.assume(address(_stakerStateToken) != address(_delegateSurrogateStakeToken)); MockStakerHarness implementation = new MockStakerHarness(); vm.expectRevert( - StakerDelegateSurrogateVotes.StakerDelegateSurrogateVotes__UnauthorizedToken.selector + StakerDelegateSurrogateVotesUpgradeable + .StakerDelegateSurrogateVotesUpgradeable__UnauthorizedToken + .selector ); new ERC1967Proxy( address(implementation), @@ -154,7 +161,9 @@ contract Constructor is StakerTest { vm.assume(_admin != address(0) && _earningPowerCalculator != address(0)); vm.assume(address(_stakerStateToken) != address(_permitAndStakeStakeToken)); MockStakerHarness implementation = new MockStakerHarness(); - vm.expectRevert(StakerPermitAndStake.StakerPermitAndStake__UnauthorizedToken.selector); + vm.expectRevert( + StakerPermitAndStakeUpgradeable.StakerPermitAndStakeUpgradeable__UnauthorizedToken.selector + ); new ERC1967Proxy( address(implementation), abi.encodeCall( @@ -201,9 +210,9 @@ contract Stake is StakerTest { vm.startPrank(_depositor); govToken.approve(address(govStaker), _amount); - Staker.DepositIdentifier _depositId = _stake(_depositor, _amount, _delegatee); + StakerUpgradeable.DepositIdentifier _depositId = _stake(_depositor, _amount, _delegatee); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.claimer, _depositor); } @@ -214,16 +223,18 @@ contract Stake is StakerTest { ) public { _amount = bound(_amount, 1, type(uint96).max); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier depositId = govStaker.exposed_useDepositId(); + StakerUpgradeable.DepositIdentifier depositId = govStaker.exposed_useDepositId(); vm.assume(_delegatee != address(0)); vm.startPrank(_depositor); govToken.approve(address(govStaker), _amount); vm.expectEmit(); - emit Staker.StakeDeposited( + emit StakerUpgradeable.StakeDeposited( _depositor, - Staker.DepositIdentifier.wrap(Staker.DepositIdentifier.unwrap(depositId) + 1), + StakerUpgradeable.DepositIdentifier.wrap( + StakerUpgradeable.DepositIdentifier.unwrap(depositId) + 1 + ), _amount, _amount, _amount @@ -240,15 +251,17 @@ contract Stake is StakerTest { ) public { _amount = bound(_amount, 1, type(uint96).max); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier depositId = govStaker.exposed_useDepositId(); + StakerUpgradeable.DepositIdentifier depositId = govStaker.exposed_useDepositId(); vm.assume(_delegatee != address(0)); vm.startPrank(_depositor); govToken.approve(address(govStaker), _amount); vm.expectEmit(); - emit Staker.ClaimerAltered( - Staker.DepositIdentifier.wrap(Staker.DepositIdentifier.unwrap(depositId) + 1), + emit StakerUpgradeable.ClaimerAltered( + StakerUpgradeable.DepositIdentifier.wrap( + StakerUpgradeable.DepositIdentifier.unwrap(depositId) + 1 + ), address(0), _depositor, _amount @@ -265,15 +278,17 @@ contract Stake is StakerTest { ) public { _amount = bound(_amount, 1, type(uint96).max); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier depositId = govStaker.exposed_useDepositId(); + StakerUpgradeable.DepositIdentifier depositId = govStaker.exposed_useDepositId(); vm.assume(_delegatee != address(0)); vm.startPrank(_depositor); govToken.approve(address(govStaker), _amount); vm.expectEmit(); - emit Staker.DelegateeAltered( - Staker.DepositIdentifier.wrap(Staker.DepositIdentifier.unwrap(depositId) + 1), + emit StakerUpgradeable.DelegateeAltered( + StakerUpgradeable.DepositIdentifier.wrap( + StakerUpgradeable.DepositIdentifier.unwrap(depositId) + 1 + ), address(0), _delegatee, _amount @@ -295,9 +310,10 @@ contract Stake is StakerTest { vm.startPrank(_depositor); govToken.approve(address(govStaker), _amount); - Staker.DepositIdentifier _depositId = _stake(_depositor, _amount, _delegatee, _claimer); + StakerUpgradeable.DepositIdentifier _depositId = + _stake(_depositor, _amount, _delegatee, _claimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.claimer, _claimer); } @@ -309,16 +325,18 @@ contract Stake is StakerTest { ) public { _amount = bound(_amount, 1, type(uint96).max); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier depositId = govStaker.exposed_useDepositId(); + StakerUpgradeable.DepositIdentifier depositId = govStaker.exposed_useDepositId(); vm.assume(_delegatee != address(0) && _claimer != address(0)); vm.startPrank(_depositor); govToken.approve(address(govStaker), _amount); vm.expectEmit(); - emit Staker.StakeDeposited( + emit StakerUpgradeable.StakeDeposited( _depositor, - Staker.DepositIdentifier.wrap(Staker.DepositIdentifier.unwrap(depositId) + 1), + StakerUpgradeable.DepositIdentifier.wrap( + StakerUpgradeable.DepositIdentifier.unwrap(depositId) + 1 + ), _amount, _amount, _amount @@ -336,15 +354,17 @@ contract Stake is StakerTest { ) public { _amount = bound(_amount, 1, type(uint96).max); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier depositId = govStaker.exposed_useDepositId(); + StakerUpgradeable.DepositIdentifier depositId = govStaker.exposed_useDepositId(); vm.assume(_delegatee != address(0) && _claimer != address(0)); vm.startPrank(_depositor); govToken.approve(address(govStaker), _amount); vm.expectEmit(); - emit Staker.ClaimerAltered( - Staker.DepositIdentifier.wrap(Staker.DepositIdentifier.unwrap(depositId) + 1), + emit StakerUpgradeable.ClaimerAltered( + StakerUpgradeable.DepositIdentifier.wrap( + StakerUpgradeable.DepositIdentifier.unwrap(depositId) + 1 + ), address(0), _claimer, _amount @@ -362,15 +382,17 @@ contract Stake is StakerTest { ) public { _amount = bound(_amount, 1, type(uint96).max); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier depositId = govStaker.exposed_useDepositId(); + StakerUpgradeable.DepositIdentifier depositId = govStaker.exposed_useDepositId(); vm.assume(_delegatee != address(0) && _claimer != address(0)); vm.startPrank(_depositor); govToken.approve(address(govStaker), _amount); vm.expectEmit(); - emit Staker.DelegateeAltered( - Staker.DepositIdentifier.wrap(Staker.DepositIdentifier.unwrap(depositId) + 1), + emit StakerUpgradeable.DelegateeAltered( + StakerUpgradeable.DepositIdentifier.wrap( + StakerUpgradeable.DepositIdentifier.unwrap(depositId) + 1 + ), address(0), _delegatee, _amount @@ -565,8 +587,8 @@ contract Stake is StakerTest { _amount = _boundMintAmount(_amount); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier _depositId = _stake(_depositor, _amount, _delegatee); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.DepositIdentifier _depositId = _stake(_depositor, _amount, _delegatee); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.balance, _amount); assertEq(_deposit.owner, _depositor); assertEq(_deposit.delegatee, _delegatee); @@ -584,10 +606,10 @@ contract Stake is StakerTest { _mintGovToken(_depositor, _amount1 + _amount2); // Perform both deposits and track their identifiers separately - Staker.DepositIdentifier _depositId1 = _stake(_depositor, _amount1, _delegatee1); - Staker.DepositIdentifier _depositId2 = _stake(_depositor, _amount2, _delegatee2); - Staker.Deposit memory _deposit1 = _fetchDeposit(_depositId1); - Staker.Deposit memory _deposit2 = _fetchDeposit(_depositId2); + StakerUpgradeable.DepositIdentifier _depositId1 = _stake(_depositor, _amount1, _delegatee1); + StakerUpgradeable.DepositIdentifier _depositId2 = _stake(_depositor, _amount2, _delegatee2); + StakerUpgradeable.Deposit memory _deposit1 = _fetchDeposit(_depositId1); + StakerUpgradeable.Deposit memory _deposit2 = _fetchDeposit(_depositId2); // Check that the deposits have been recorded independently assertEq(_deposit1.balance, _amount1); @@ -612,10 +634,10 @@ contract Stake is StakerTest { _mintGovToken(_depositor2, _amount2); // Perform both deposits and track their identifiers separately - Staker.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); - Staker.DepositIdentifier _depositId2 = _stake(_depositor2, _amount2, _delegatee2); - Staker.Deposit memory _deposit1 = _fetchDeposit(_depositId1); - Staker.Deposit memory _deposit2 = _fetchDeposit(_depositId2); + StakerUpgradeable.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); + StakerUpgradeable.DepositIdentifier _depositId2 = _stake(_depositor2, _amount2, _delegatee2); + StakerUpgradeable.Deposit memory _deposit1 = _fetchDeposit(_depositId1); + StakerUpgradeable.Deposit memory _deposit2 = _fetchDeposit(_depositId2); // Check that the deposits have been recorded independently assertEq(_deposit1.balance, _amount1); @@ -626,14 +648,14 @@ contract Stake is StakerTest { assertEq(_deposit2.delegatee, _delegatee2); } - mapping(Staker.DepositIdentifier depositId => bool isUsed) isIdUsed; + mapping(StakerUpgradeable.DepositIdentifier depositId => bool isUsed) isIdUsed; function test_NeverReusesADepositIdentifier() public { address _depositor = address(0xdeadbeef); uint256 _amount = 116; address _delegatee = address(0xaceface); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; vm.pauseGasMetering(); @@ -675,7 +697,7 @@ contract Stake is StakerTest { govToken.approve(address(govStaker), _amount); vm.prank(_depositor); - vm.expectRevert(Staker.Staker__InvalidAddress.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidAddress.selector); govStaker.stake(_amount, address(0)); } @@ -691,7 +713,7 @@ contract Stake is StakerTest { govToken.approve(address(govStaker), _amount); vm.prank(_depositor); - vm.expectRevert(Staker.Staker__InvalidAddress.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidAddress.selector); govStaker.stake(_amount, _delegatee, address(0)); } @@ -705,7 +727,7 @@ contract Stake is StakerTest { earningPowerCalculator.__setMultiplierBips(_multiplierBips); - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _depositor); uint96 _actualEarningPower = govStaker.deposits(_depositId).earningPower; @@ -723,7 +745,7 @@ contract Stake is StakerTest { earningPowerCalculator.__setFixedReturn(_fixedEarningPower); - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _depositor); uint96 _actualEarningPower = govStaker.deposits(_depositId).earningPower; @@ -769,9 +791,9 @@ contract PermitAndStake is StakerTest { (uint8 _v, bytes32 _r, bytes32 _s) = vm.sign(_depositorPrivateKey, _messageHash); vm.prank(_depositor); - Staker.DepositIdentifier _depositId = + StakerUpgradeable.DepositIdentifier _depositId = govStaker.permitAndStake(_depositAmount, _delegatee, _claimer, _deadline, _v, _r, _s); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.balance, _depositAmount); assertEq(_deposit.owner, _depositor); @@ -818,9 +840,9 @@ contract PermitAndStake is StakerTest { govToken.permit(_depositor, address(govStaker), _depositAmount, _deadline, _v, _r, _s); vm.prank(_depositor); - Staker.DepositIdentifier _depositId = + StakerUpgradeable.DepositIdentifier _depositId = govStaker.permitAndStake(_depositAmount, _delegatee, _claimer, _deadline, _v, _r, _s); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); } function testFuzz_SuccessfullyStakeWhenApprovalExistsAndPermitSignatureIsInvalid( @@ -948,11 +970,11 @@ contract PermitAndStake is StakerTest { (uint8 _v, bytes32 _r, bytes32 _s) = vm.sign(_depositorPrivateKey, _messageHash); vm.prank(_depositor); - Staker.DepositIdentifier _depositId = + StakerUpgradeable.DepositIdentifier _depositId = govStaker.permitAndStake(_depositAmount, _delegatee, _claimer, _deadline, _v, _r, _s); uint256 _expectedEarningPower = (_depositAmount * _multiplierBips) / 10_000; - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _expectedEarningPower); assertEq(govStaker.totalEarningPower(), _expectedEarningPower); @@ -998,10 +1020,10 @@ contract PermitAndStake is StakerTest { (uint8 _v, bytes32 _r, bytes32 _s) = vm.sign(_depositorPrivateKey, _messageHash); vm.prank(_depositor); - Staker.DepositIdentifier _depositId = + StakerUpgradeable.DepositIdentifier _depositId = govStaker.permitAndStake(_depositAmount, _delegatee, _claimer, _deadline, _v, _r, _s); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _fixedEarningPower); assertEq(govStaker.totalEarningPower(), _fixedEarningPower); @@ -1017,10 +1039,10 @@ contract StakeMore is StakerTest { address _delegatee, address _claimer ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); DelegationSurrogate _surrogate = govStaker.surrogates(_deposit.delegatee); _addAmount = _boundToRealisticStake(_addAmount); @@ -1041,7 +1063,7 @@ contract StakeMore is StakerTest { address _delegatee, address _claimer ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1063,7 +1085,7 @@ contract StakeMore is StakerTest { address _delegatee, address _claimer ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1085,7 +1107,7 @@ contract StakeMore is StakerTest { address _delegatee, address _claimer ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1107,7 +1129,7 @@ contract StakeMore is StakerTest { address _delegatee, address _claimer ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1119,7 +1141,7 @@ contract StakeMore is StakerTest { govStaker.stakeMore(_depositId, _addAmount); vm.stopPrank(); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.balance, _depositAmount + _addAmount); } @@ -1132,7 +1154,7 @@ contract StakeMore is StakerTest { address _claimer ) public { uint256 _totalAdditionalStake; - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); // Second stake @@ -1150,7 +1172,7 @@ contract StakeMore is StakerTest { uint256 _total = _depositAmount + _totalAdditionalStake; vm.expectEmit(); - emit Staker.StakeDeposited(_depositor, _depositId, _addAmount, _total, _total); + emit StakerUpgradeable.StakeDeposited(_depositor, _depositId, _addAmount, _total, _total); govStaker.stakeMore(_depositId, _addAmount); vm.stopPrank(); @@ -1166,7 +1188,7 @@ contract StakeMore is StakerTest { ) public { vm.assume(_notDepositor != _depositor); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1179,7 +1201,7 @@ contract StakeMore is StakerTest { vm.prank(_notDepositor); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor ) ); govStaker.stakeMore(_depositId, _addAmount); @@ -1187,7 +1209,7 @@ contract StakeMore is StakerTest { function testFuzz_RevertIf_TheDepositIdentifierIsInvalid( address _depositor, - Staker.DepositIdentifier _depositId, + StakerUpgradeable.DepositIdentifier _depositId, uint256 _addAmount ) public { vm.assume(_depositor != address(0)); @@ -1198,7 +1220,9 @@ contract StakeMore is StakerTest { // being address zero, which means the address attempting to alter it won't be able to. vm.prank(_depositor); vm.expectRevert( - abi.encodeWithSelector(Staker.Staker__Unauthorized.selector, bytes32("not owner"), _depositor) + abi.encodeWithSelector( + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _depositor + ) ); govStaker.stakeMore(_depositId, _addAmount); } @@ -1213,7 +1237,7 @@ contract StakeMore is StakerTest { _multiplierBips = bound(_multiplierBips, 0, 20_000); earningPowerCalculator.__setMultiplierBips(_multiplierBips); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); _addAmount = _boundToRealisticStake(_addAmount); @@ -1238,7 +1262,7 @@ contract StakeMore is StakerTest { _fixedEarningPower = _boundToRealisticStake(_fixedEarningPower); earningPowerCalculator.__setFixedReturn(_fixedEarningPower); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); _addAmount = _boundToRealisticStake(_addAmount); @@ -1262,7 +1286,7 @@ contract StakeMore is StakerTest { _multiplierBips = bound(_multiplierBips, 0, 20_000); earningPowerCalculator.__setMultiplierBips(_multiplierBips); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); _addAmount = _boundToRealisticStake(_addAmount); @@ -1294,7 +1318,7 @@ contract PermitAndStakeMore is StakerTest { address _depositor = vm.addr(_depositorPrivateKey); _deadline = bound(_deadline, block.timestamp, type(uint256).max); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); @@ -1326,7 +1350,7 @@ contract PermitAndStakeMore is StakerTest { govStaker.permitAndStakeMore(_depositId, _stakeMoreAmount, _deadline, _v, _r, _s); } - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.balance, _initialDepositAmount + _stakeMoreAmount); assertEq(_deposit.owner, _depositor); @@ -1349,7 +1373,7 @@ contract PermitAndStakeMore is StakerTest { address _depositor = vm.addr(_depositorPrivateKey); _deadline = bound(_deadline, block.timestamp, type(uint256).max); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); @@ -1394,7 +1418,7 @@ contract PermitAndStakeMore is StakerTest { ) public { vm.assume(_delegatee != address(0) && _claimer != address(0)); (address _depositor, uint256 _depositorPrivateKey) = makeAddrAndKey("depositor"); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); _stakeMoreAmount = bound(_stakeMoreAmount, 0, type(uint96).max - _initialDepositAmount); @@ -1442,7 +1466,7 @@ contract PermitAndStakeMore is StakerTest { vm.assume(_depositor != _notDepositor); _deadline = bound(_deadline, block.timestamp, type(uint256).max); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); @@ -1469,7 +1493,7 @@ contract PermitAndStakeMore is StakerTest { vm.prank(_notDepositor); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor ) ); govStaker.permitAndStakeMore(_depositId, _stakeMoreAmount, _deadline, _v, _r, _s); @@ -1491,7 +1515,7 @@ contract PermitAndStakeMore is StakerTest { uint256 _wrongNonce = 1; uint256 _approvalAmount = _stakeMoreAmount - 1; - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); _mintGovToken(_depositor, _stakeMoreAmount); @@ -1538,7 +1562,7 @@ contract PermitAndStakeMore is StakerTest { _depositorPrivateKey = bound(_depositorPrivateKey, 1, 100e18); address _depositor = vm.addr(_depositorPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1550,7 +1574,7 @@ contract PermitAndStakeMore is StakerTest { uint256 _totalStaked = _depositAmount + _addAmount; uint256 _expectedEarningPower = (_totalStaked * _multiplierBips) / 10_000; - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _expectedEarningPower); assertEq(govStaker.totalEarningPower(), _expectedEarningPower); @@ -1569,7 +1593,7 @@ contract PermitAndStakeMore is StakerTest { _depositorPrivateKey = bound(_depositorPrivateKey, 1, 100e18); address _depositor = vm.addr(_depositorPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1579,7 +1603,7 @@ contract PermitAndStakeMore is StakerTest { _executePermitAndStakeMore(_depositor, _depositorPrivateKey, _depositId, _addAmount); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _fixedEarningPower); assertEq(govStaker.totalEarningPower(), _fixedEarningPower); @@ -1590,7 +1614,7 @@ contract PermitAndStakeMore is StakerTest { function _executePermitAndStakeMore( address _depositor, uint256 _depositorPrivateKey, - Staker.DepositIdentifier _depositId, + StakerUpgradeable.DepositIdentifier _depositId, uint256 _addAmount ) internal { _mintGovToken(_depositor, _addAmount); @@ -1626,7 +1650,7 @@ contract AlterDelegatee is StakerTest { ) public { vm.assume(_newDelegatee != address(0) && _newDelegatee != _firstDelegatee); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _firstDelegatee, _claimer); address _firstSurrogate = address(govStaker.surrogates(_firstDelegatee)); @@ -1634,7 +1658,7 @@ contract AlterDelegatee is StakerTest { vm.prank(_depositor); govStaker.alterDelegatee(_depositId, _newDelegatee); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); address _newSurrogate = address(govStaker.surrogates(_deposit.delegatee)); assertEq(_deposit.delegatee, _newDelegatee); @@ -1648,7 +1672,7 @@ contract AlterDelegatee is StakerTest { address _delegatee, address _claimer ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); address _beforeSurrogate = address(govStaker.surrogates(_delegatee)); @@ -1658,7 +1682,7 @@ contract AlterDelegatee is StakerTest { vm.prank(_depositor); govStaker.alterDelegatee(_depositId, _delegatee); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); address _afterSurrogate = address(govStaker.surrogates(_deposit.delegatee)); assertEq(_deposit.delegatee, _delegatee); @@ -1675,12 +1699,14 @@ contract AlterDelegatee is StakerTest { ) public { vm.assume(_newDelegatee != address(0) && _newDelegatee != _firstDelegatee); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _firstDelegatee, _claimer); vm.expectEmit(); - emit Staker.DelegateeAltered(_depositId, _firstDelegatee, _newDelegatee, _depositAmount); + emit StakerUpgradeable.DelegateeAltered( + _depositId, _firstDelegatee, _newDelegatee, _depositAmount + ); vm.prank(_depositor); govStaker.alterDelegatee(_depositId, _newDelegatee); @@ -1696,7 +1722,7 @@ contract AlterDelegatee is StakerTest { ) public { vm.assume(_newDelegatee != address(0) && _newDelegatee != _firstDelegatee); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _firstDelegatee, _claimer); @@ -1707,7 +1733,7 @@ contract AlterDelegatee is StakerTest { vm.prank(_depositor); govStaker.alterDelegatee(_depositId, _newDelegatee); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _newEarningPower); } @@ -1722,7 +1748,7 @@ contract AlterDelegatee is StakerTest { ) public { vm.assume(_newDelegatee != address(0) && _newDelegatee != _firstDelegatee); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _firstDelegatee, _claimer); @@ -1746,7 +1772,7 @@ contract AlterDelegatee is StakerTest { ) public { vm.assume(_newDelegatee != address(0) && _newDelegatee != _firstDelegatee); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _firstDelegatee, _claimer); @@ -1772,14 +1798,14 @@ contract AlterDelegatee is StakerTest { _depositor != _notDepositor && _newDelegatee != address(0) && _newDelegatee != _firstDelegatee ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _firstDelegatee, _claimer); vm.prank(_notDepositor); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor ) ); govStaker.alterDelegatee(_depositId, _newDelegatee); @@ -1787,7 +1813,7 @@ contract AlterDelegatee is StakerTest { function testFuzz_RevertIf_TheDepositIdentifierIsInvalid( address _depositor, - Staker.DepositIdentifier _depositId, + StakerUpgradeable.DepositIdentifier _depositId, address _newDelegatee ) public { vm.assume(_depositor != address(0) && _newDelegatee != address(0)); @@ -1797,7 +1823,9 @@ contract AlterDelegatee is StakerTest { // address zero, which means the address attempting to alter it won't be able to. vm.prank(_depositor); vm.expectRevert( - abi.encodeWithSelector(Staker.Staker__Unauthorized.selector, bytes32("not owner"), _depositor) + abi.encodeWithSelector( + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _depositor + ) ); govStaker.alterDelegatee(_depositId, _newDelegatee); } @@ -1807,11 +1835,11 @@ contract AlterDelegatee is StakerTest { uint256 _depositAmount, address _delegatee ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); vm.prank(_depositor); - vm.expectRevert(Staker.Staker__InvalidAddress.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidAddress.selector); govStaker.alterDelegatee(_depositId, address(0)); } @@ -1828,7 +1856,7 @@ contract AlterDelegatee is StakerTest { _multiplierBips = bound(_multiplierBips, 0, 20_000); earningPowerCalculator.__setMultiplierBips(_multiplierBips); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _firstDelegatee, _claimer); @@ -1837,7 +1865,7 @@ contract AlterDelegatee is StakerTest { uint256 _expectedEarningPower = (_depositAmount * _multiplierBips) / 10_000; - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _expectedEarningPower); assertEq(govStaker.totalEarningPower(), _expectedEarningPower); assertEq(govStaker.depositorTotalEarningPower(_depositor), _expectedEarningPower); @@ -1856,14 +1884,14 @@ contract AlterDelegatee is StakerTest { _fixedEarningPower = _boundToRealisticStake(_fixedEarningPower); earningPowerCalculator.__setFixedReturn(_fixedEarningPower); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _firstDelegatee, _claimer); vm.prank(_depositor); govStaker.alterDelegatee(_depositId, _newDelegatee); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _fixedEarningPower); assertEq(govStaker.totalEarningPower(), _fixedEarningPower); assertEq(govStaker.depositorTotalEarningPower(_depositor), _fixedEarningPower); @@ -1880,14 +1908,14 @@ contract AlterClaimer is StakerTest { ) public { vm.assume(_newClaimer != address(0) && _newClaimer != _firstClaimer); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _firstClaimer); vm.prank(_depositor); govStaker.alterClaimer(_depositId, _newClaimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.claimer, _newClaimer); } @@ -1898,7 +1926,7 @@ contract AlterClaimer is StakerTest { address _delegatee, address _claimer ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1907,7 +1935,7 @@ contract AlterClaimer is StakerTest { vm.prank(_depositor); govStaker.alterClaimer(_depositId, _claimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.claimer, _claimer); } @@ -1921,12 +1949,12 @@ contract AlterClaimer is StakerTest { ) public { vm.assume(_newClaimer != address(0) && _newClaimer != _firstClaimer); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _firstClaimer); vm.expectEmit(); - emit Staker.ClaimerAltered(_depositId, _firstClaimer, _newClaimer, _depositAmount); + emit StakerUpgradeable.ClaimerAltered(_depositId, _firstClaimer, _newClaimer, _depositAmount); vm.prank(_depositor); govStaker.alterClaimer(_depositId, _newClaimer); @@ -1942,7 +1970,7 @@ contract AlterClaimer is StakerTest { ) public { vm.assume(_newClaimer != address(0) && _newClaimer != _firstClaimer); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _firstClaimer); @@ -1953,7 +1981,7 @@ contract AlterClaimer is StakerTest { vm.prank(_depositor); govStaker.alterClaimer(_depositId, _newClaimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _newEarningPower); } @@ -1968,7 +1996,7 @@ contract AlterClaimer is StakerTest { ) public { vm.assume(_newClaimer != address(0) && _newClaimer != _firstClaimer); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _firstClaimer); @@ -1992,7 +2020,7 @@ contract AlterClaimer is StakerTest { ) public { vm.assume(_newClaimer != address(0) && _newClaimer != _firstClaimer); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _firstClaimer); @@ -2018,14 +2046,14 @@ contract AlterClaimer is StakerTest { _notDepositor != _depositor && _newClaimer != address(0) && _newClaimer != _firstClaimer ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _firstClaimer); vm.prank(_notDepositor); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor ) ); govStaker.alterClaimer(_depositId, _newClaimer); @@ -2033,7 +2061,7 @@ contract AlterClaimer is StakerTest { function testFuzz_RevertIf_TheDepositIdentifierIsInvalid( address _depositor, - Staker.DepositIdentifier _depositId, + StakerUpgradeable.DepositIdentifier _depositId, address _newClaimer ) public { vm.assume(_depositor != address(0) && _newClaimer != address(0)); @@ -2043,7 +2071,9 @@ contract AlterClaimer is StakerTest { // address zero, which means the address attempting to alter it won't be able to. vm.prank(_depositor); vm.expectRevert( - abi.encodeWithSelector(Staker.Staker__Unauthorized.selector, bytes32("not owner"), _depositor) + abi.encodeWithSelector( + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _depositor + ) ); govStaker.alterClaimer(_depositId, _newClaimer); } @@ -2053,11 +2083,11 @@ contract AlterClaimer is StakerTest { uint256 _depositAmount, address _delegatee ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); vm.prank(_depositor); - vm.expectRevert(Staker.Staker__InvalidAddress.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidAddress.selector); govStaker.alterClaimer(_depositId, address(0)); } @@ -2074,7 +2104,7 @@ contract AlterClaimer is StakerTest { _multiplierBips = bound(_multiplierBips, 0, 20_000); earningPowerCalculator.__setMultiplierBips(_multiplierBips); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _firstClaimer); @@ -2083,7 +2113,7 @@ contract AlterClaimer is StakerTest { uint256 _expectedEarningPower = (_depositAmount * _multiplierBips) / 10_000; - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _expectedEarningPower); assertEq(govStaker.totalEarningPower(), _expectedEarningPower); assertEq(govStaker.depositorTotalEarningPower(_depositor), _expectedEarningPower); @@ -2102,14 +2132,14 @@ contract AlterClaimer is StakerTest { _fixedEarningPower = _boundToRealisticStake(_fixedEarningPower); earningPowerCalculator.__setFixedReturn(_fixedEarningPower); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _firstClaimer); vm.prank(_depositor); govStaker.alterClaimer(_depositId, _newClaimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _fixedEarningPower); assertEq(govStaker.totalEarningPower(), _fixedEarningPower); assertEq(govStaker.depositorTotalEarningPower(_depositor), _fixedEarningPower); @@ -2123,14 +2153,14 @@ contract Withdraw is StakerTest { address _delegatee, uint256 _withdrawalAmount ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); _withdrawalAmount = bound(_withdrawalAmount, 0, _depositAmount); vm.prank(_depositor); govStaker.withdraw(_depositId, _withdrawalAmount); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); address _surrogate = address(govStaker.surrogates(_deposit.delegatee)); assertEq(govToken.balanceOf(_depositor), _withdrawalAmount); @@ -2144,7 +2174,7 @@ contract Withdraw is StakerTest { address _delegatee, uint256 _withdrawalAmount ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); _withdrawalAmount = bound(_withdrawalAmount, 0, _depositAmount); @@ -2165,9 +2195,9 @@ contract Withdraw is StakerTest { uint256 _withdrawalAmount2 ) public { // Make two separate deposits - Staker.DepositIdentifier _depositId1; + StakerUpgradeable.DepositIdentifier _depositId1; (_depositAmount1, _depositId1) = _boundMintAndStake(_depositor1, _depositAmount1, _delegatee1); - Staker.DepositIdentifier _depositId2; + StakerUpgradeable.DepositIdentifier _depositId2; (_depositAmount2, _depositId2) = _boundMintAndStake(_depositor2, _depositAmount2, _delegatee2); // Calculate withdrawal amounts @@ -2194,9 +2224,9 @@ contract Withdraw is StakerTest { uint256 _withdrawalAmount ) public { // Make two separate deposits - Staker.DepositIdentifier _depositId1; + StakerUpgradeable.DepositIdentifier _depositId1; (_depositAmount1, _depositId1) = _boundMintAndStake(_depositor, _depositAmount1, _delegatee1); - Staker.DepositIdentifier _depositId2; + StakerUpgradeable.DepositIdentifier _depositId2; (_depositAmount2, _depositId2) = _boundMintAndStake(_depositor, _depositAmount2, _delegatee2); // Withdraw part of the first deposit @@ -2221,9 +2251,9 @@ contract Withdraw is StakerTest { uint256 _withdrawalAmount ) public { // Make two separate deposits - Staker.DepositIdentifier _depositId1; + StakerUpgradeable.DepositIdentifier _depositId1; (_depositAmount1, _depositId1) = _boundMintAndStake(_depositor, _depositAmount1, _delegatee1); - Staker.DepositIdentifier _depositId2; + StakerUpgradeable.DepositIdentifier _depositId2; (_depositAmount2, _depositId2) = _boundMintAndStake(_depositor, _depositAmount2, _delegatee2); // Withdraw part of the first deposit @@ -2245,14 +2275,16 @@ contract Withdraw is StakerTest { address _delegatee, uint256 _withdrawalAmount ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); _withdrawalAmount = bound(_withdrawalAmount, 0, _depositAmount); uint256 _newAmount = _depositAmount - _withdrawalAmount; vm.expectEmit(); - emit Staker.StakeWithdrawn(_depositor, _depositId, _withdrawalAmount, _newAmount, _newAmount); + emit StakerUpgradeable.StakeWithdrawn( + _depositor, _depositId, _withdrawalAmount, _newAmount, _newAmount + ); vm.prank(_depositor); govStaker.withdraw(_depositId, _withdrawalAmount); @@ -2264,14 +2296,14 @@ contract Withdraw is StakerTest { address _delegatee, address _notDepositor ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee); vm.assume(_depositor != _notDepositor); vm.prank(_notDepositor); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor ) ); govStaker.withdraw(_depositId, _amount); @@ -2283,7 +2315,7 @@ contract Withdraw is StakerTest { uint256 _amountOver, address _delegatee ) public { - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee); _amountOver = bound(_amountOver, 1, type(uint128).max); @@ -2302,14 +2334,14 @@ contract Withdraw is StakerTest { _multiplierBips = bound(_multiplierBips, 0, 20_000); earningPowerCalculator.__setMultiplierBips(_multiplierBips); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); _withdrawalAmount = bound(_withdrawalAmount, 0, _depositAmount); vm.prank(_depositor); govStaker.withdraw(_depositId, _withdrawalAmount); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); uint256 _remainingStake = _depositAmount - _withdrawalAmount; uint256 _expectedEarningPower = (_remainingStake * _multiplierBips) / 10_000; assertEq(_deposit.earningPower, _expectedEarningPower); @@ -2325,14 +2357,14 @@ contract Withdraw is StakerTest { _fixedEarningPower = _boundToRealisticStake(_fixedEarningPower); earningPowerCalculator.__setFixedReturn(_fixedEarningPower); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee); _withdrawalAmount = bound(_withdrawalAmount, 0, _depositAmount); vm.prank(_depositor); govStaker.withdraw(_depositId, _withdrawalAmount); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _fixedEarningPower); } } @@ -2356,7 +2388,7 @@ contract SetRewardNotifier is StakerTest { public { vm.expectEmit(); - emit Staker.RewardNotifierSet(_rewardNotifier, _isEnabled); + emit StakerUpgradeable.RewardNotifierSet(_rewardNotifier, _isEnabled); vm.prank(admin); govStaker.setRewardNotifier(_rewardNotifier, _isEnabled); } @@ -2370,7 +2402,9 @@ contract SetRewardNotifier is StakerTest { vm.prank(_notAdmin); vm.expectRevert( - abi.encodeWithSelector(Staker.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin) + abi.encodeWithSelector( + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin + ) ); govStaker.setRewardNotifier(_newRewardNotifier, _isEnabled); } @@ -2390,7 +2424,7 @@ contract SetAdmin is StakerTest { vm.assume(_newAdmin != address(0)); vm.expectEmit(); - emit Staker.AdminSet(admin, _newAdmin); + emit StakerUpgradeable.AdminSet(admin, _newAdmin); vm.prank(admin); govStaker.setAdmin(_newAdmin); @@ -2401,14 +2435,16 @@ contract SetAdmin is StakerTest { vm.prank(_notAdmin); vm.expectRevert( - abi.encodeWithSelector(Staker.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin) + abi.encodeWithSelector( + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin + ) ); govStaker.setAdmin(_newAdmin); } function test_RevertIf_NewAdminAddressIsZeroAddress() public { vm.prank(admin); - vm.expectRevert(Staker.Staker__InvalidAddress.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidAddress.selector); govStaker.setAdmin(address(0)); } } @@ -2431,7 +2467,7 @@ contract SetEarningPowerCalculator is StakerTest { vm.assume(_newEarningPowerCalculator != address(0)); vm.expectEmit(); - emit Staker.EarningPowerCalculatorSet( + emit StakerUpgradeable.EarningPowerCalculatorSet( address(govStaker.earningPowerCalculator()), _newEarningPowerCalculator ); @@ -2447,14 +2483,16 @@ contract SetEarningPowerCalculator is StakerTest { vm.prank(_notAdmin); vm.expectRevert( - abi.encodeWithSelector(Staker.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin) + abi.encodeWithSelector( + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin + ) ); govStaker.setEarningPowerCalculator(_newEarningPowerCalculator); } function test_RevertIf_NewEarningPowerCalculatorAddressIsZeroAddress() public { vm.prank(admin); - vm.expectRevert(Staker.Staker__InvalidAddress.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidAddress.selector); govStaker.setEarningPowerCalculator(address(0)); } } @@ -2469,7 +2507,7 @@ contract SetMaxBumpTip is StakerTest { function testFuzz_EmitsEventWhenMaxBumpTipIsSet(uint256 _newMaxBumpTip) public { vm.expectEmit(); - emit Staker.MaxBumpTipSet(govStaker.maxBumpTip(), _newMaxBumpTip); + emit StakerUpgradeable.MaxBumpTipSet(govStaker.maxBumpTip(), _newMaxBumpTip); vm.prank(admin); govStaker.setMaxBumpTip(_newMaxBumpTip); @@ -2480,7 +2518,9 @@ contract SetMaxBumpTip is StakerTest { vm.prank(_caller); vm.expectRevert( - abi.encodeWithSelector(Staker.Staker__Unauthorized.selector, bytes32("not admin"), _caller) + abi.encodeWithSelector( + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not admin"), _caller + ) ); govStaker.setMaxBumpTip(_newMaxBumpTip); } @@ -2488,7 +2528,7 @@ contract SetMaxBumpTip is StakerTest { contract SetClaimFeeParameters is StakerTest { function testFuzz_AllowsAdminToUpdateTheClaimFeeAmountAndFeeCollector( - Staker.ClaimFeeParameters memory _newParams + StakerUpgradeable.ClaimFeeParameters memory _newParams ) public { vm.assume(_newParams.feeCollector != address(0)); _newParams.feeAmount = uint96(bound(_newParams.feeAmount, 0, govStaker.MAX_CLAIM_FEE())); @@ -2496,7 +2536,7 @@ contract SetClaimFeeParameters is StakerTest { vm.prank(admin); govStaker.setClaimFeeParameters(_newParams); - Staker.ClaimFeeParameters memory _feeParams = govStaker.claimFeeParameters(); + StakerUpgradeable.ClaimFeeParameters memory _feeParams = govStaker.claimFeeParameters(); uint96 _feeAmount = _feeParams.feeAmount; address _feeCollector = _feeParams.feeCollector; assertEq(_feeAmount, _newParams.feeAmount); @@ -2504,7 +2544,7 @@ contract SetClaimFeeParameters is StakerTest { } function testFuzz_AllowsAdminToSetFeeAmountAndFeeCollectorToZero( - Staker.ClaimFeeParameters memory _initialParams + StakerUpgradeable.ClaimFeeParameters memory _initialParams ) public { vm.assume(_initialParams.feeCollector != address(0)); _initialParams.feeAmount = uint96(bound(_initialParams.feeAmount, 0, govStaker.MAX_CLAIM_FEE())); @@ -2513,14 +2553,14 @@ contract SetClaimFeeParameters is StakerTest { vm.prank(admin); govStaker.setClaimFeeParameters(_initialParams); - Staker.ClaimFeeParameters memory _zeroParams = - Staker.ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)}); + StakerUpgradeable.ClaimFeeParameters memory _zeroParams = + StakerUpgradeable.ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)}); // Update the parameters to both be zero. vm.prank(admin); govStaker.setClaimFeeParameters(_zeroParams); - Staker.ClaimFeeParameters memory _feeParams = govStaker.claimFeeParameters(); + StakerUpgradeable.ClaimFeeParameters memory _feeParams = govStaker.claimFeeParameters(); uint96 _feeAmount = _feeParams.feeAmount; address _feeCollector = _feeParams.feeCollector; assertEq(_feeAmount, 0); @@ -2528,8 +2568,8 @@ contract SetClaimFeeParameters is StakerTest { } function testFuzz_EmitsAClaimFeeParametersSetEvent( - Staker.ClaimFeeParameters memory _initialParams, - Staker.ClaimFeeParameters memory _newParams + StakerUpgradeable.ClaimFeeParameters memory _initialParams, + StakerUpgradeable.ClaimFeeParameters memory _newParams ) public { vm.assume(_initialParams.feeCollector != address(0) && _newParams.feeCollector != address(0)); _newParams.feeAmount = uint96(bound(_newParams.feeAmount, 0, govStaker.MAX_CLAIM_FEE())); @@ -2542,7 +2582,7 @@ contract SetClaimFeeParameters is StakerTest { // Update params, expecting appropriate event. vm.prank(admin); vm.expectEmit(); - emit Staker.ClaimFeeParametersSet( + emit StakerUpgradeable.ClaimFeeParametersSet( _initialParams.feeAmount, _newParams.feeAmount, _initialParams.feeCollector, @@ -2552,31 +2592,31 @@ contract SetClaimFeeParameters is StakerTest { } function testFuzz_RevertIf_FeeAmountIsMoreThanTheMaxClaimFee( - Staker.ClaimFeeParameters memory _newParams + StakerUpgradeable.ClaimFeeParameters memory _newParams ) public { vm.assume(_newParams.feeCollector != address(0)); _newParams.feeAmount = uint96(bound(_newParams.feeAmount, govStaker.MAX_CLAIM_FEE() + 1, type(uint96).max)); vm.prank(admin); - vm.expectRevert(Staker.Staker__InvalidClaimFeeParameters.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidClaimFeeParameters.selector); govStaker.setClaimFeeParameters(_newParams); } function testFuzz_RevertIf_TheFeeCollectorIsAddressZeroWhileFeeAmountIsNotZero( - Staker.ClaimFeeParameters memory _newParams + StakerUpgradeable.ClaimFeeParameters memory _newParams ) public { _newParams.feeAmount = uint96(bound(_newParams.feeAmount, 1, govStaker.MAX_CLAIM_FEE())); _newParams.feeCollector = address(0); vm.prank(admin); - vm.expectRevert(Staker.Staker__InvalidClaimFeeParameters.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidClaimFeeParameters.selector); govStaker.setClaimFeeParameters(_newParams); } function testFuzz_RevertIf_TheCallerIsNotTheAdmin( address _notAdmin, - Staker.ClaimFeeParameters memory _newParams + StakerUpgradeable.ClaimFeeParameters memory _newParams ) public { vm.assume(_newParams.feeCollector != address(0)); vm.assume(_notAdmin != admin); @@ -2584,7 +2624,9 @@ contract SetClaimFeeParameters is StakerTest { vm.prank(_notAdmin); vm.expectRevert( - abi.encodeWithSelector(Staker.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin) + abi.encodeWithSelector( + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin + ) ); govStaker.setClaimFeeParameters(_newParams); } @@ -2616,8 +2658,8 @@ contract StakerRewardsTest is StakerTest { console2.log("-----------------------------------------------"); } - function __dumpDebugDeposit(Staker.DepositIdentifier _depositId) public view { - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + function __dumpDebugDeposit(StakerUpgradeable.DepositIdentifier _depositId) public view { + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); console2.log("deposit balance"); console2.log(_deposit.balance); console2.log("deposit owner"); @@ -2806,7 +2848,7 @@ contract NotifyRewardAmount is StakerRewardsTest { // fox alters delegatee vm.prank(_fox); - govStaker.alterDelegatee(Staker.DepositIdentifier.wrap(1), address(0x2)); + govStaker.alterDelegatee(StakerUpgradeable.DepositIdentifier.wrap(1), address(0x2)); // fox checkpoints global rewards _mintGovToken(_fox, 0); @@ -2814,14 +2856,14 @@ contract NotifyRewardAmount is StakerRewardsTest { // fox alters back to valid delegatee vm.prank(_fox); - govStaker.alterDelegatee(Staker.DepositIdentifier.wrap(1), address(0x2)); + govStaker.alterDelegatee(StakerUpgradeable.DepositIdentifier.wrap(1), address(0x2)); // fox claims double the rewards vm.prank(_fox); - govStaker.claimReward(Staker.DepositIdentifier.wrap(1)); + govStaker.claimReward(StakerUpgradeable.DepositIdentifier.wrap(1)); vm.prank(_doe); - govStaker.claimReward(Staker.DepositIdentifier.wrap(0)); + govStaker.claimReward(StakerUpgradeable.DepositIdentifier.wrap(0)); assertEq(rewardToken.balanceOf(_doe), rewardToken.balanceOf(_fox)); } @@ -2833,7 +2875,7 @@ contract NotifyRewardAmount is StakerRewardsTest { rewardToken.transfer(address(govStaker), _amount); vm.expectEmit(); - emit Staker.RewardNotified(_amount, rewardNotifier); + emit StakerUpgradeable.RewardNotified(_amount, rewardNotifier); govStaker.notifyRewardAmount(_amount); vm.stopPrank(); @@ -2851,7 +2893,7 @@ contract NotifyRewardAmount is StakerRewardsTest { rewardToken.transfer(address(govStaker), _amount); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not notifier"), _notNotifier + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not notifier"), _notNotifier ) ); govStaker.notifyRewardAmount(_amount); @@ -2865,7 +2907,7 @@ contract NotifyRewardAmount is StakerRewardsTest { vm.startPrank(rewardNotifier); rewardToken.transfer(address(govStaker), _amount); - vm.expectRevert(Staker.Staker__InvalidRewardRate.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidRewardRate.selector); govStaker.notifyRewardAmount(_amount); vm.stopPrank(); } @@ -2887,7 +2929,7 @@ contract NotifyRewardAmount is StakerRewardsTest { // Something less than the supposed reward is sent rewardToken.transfer(address(govStaker), _transferAmount); // The reward notification should revert because the contract doesn't have enough tokens - vm.expectRevert(Staker.Staker__InsufficientRewardBalance.selector); + vm.expectRevert(StakerUpgradeable.Staker__InsufficientRewardBalance.selector); govStaker.notifyRewardAmount(_amount); vm.stopPrank(); } @@ -2910,7 +2952,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerIncrease = uint96(bound(_earningPowerIncrease, 1, type(uint48).max)); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -2947,7 +2989,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerIncrease = uint96(bound(_earningPowerIncrease, 1, type(uint48).max)); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -2983,7 +3025,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerIncrease = uint96(bound(_earningPowerIncrease, 1, type(uint48).max)); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3020,7 +3062,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerIncrease = uint96(bound(_earningPowerIncrease, 1, type(uint48).max)); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3058,7 +3100,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerIncrease = uint96(bound(_earningPowerIncrease, 1, type(uint48).max)); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3096,7 +3138,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerIncrease = uint96(bound(_earningPowerIncrease, 1, type(uint48).max)); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3115,7 +3157,7 @@ contract BumpEarningPower is StakerRewardsTest { // Bump earning power is called vm.prank(_bumpCaller); vm.expectEmit(); - emit Staker.EarningPowerBumped( + emit StakerUpgradeable.EarningPowerBumped( _depositId, _oldEarningPower, _newEarningPower, _bumpCaller, _tipReceiver, _requestedTip ); govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip); @@ -3138,7 +3180,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerDecrease = bound(_earningPowerDecrease, 1, _stakeAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3176,7 +3218,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerDecrease = bound(_earningPowerDecrease, 1, _stakeAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3213,7 +3255,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerDecrease = bound(_earningPowerDecrease, 1, _stakeAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3251,7 +3293,7 @@ contract BumpEarningPower is StakerRewardsTest { uint256 _initialTipReceiverBalance = rewardToken.balanceOf(_tipReceiver); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3290,7 +3332,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerDecrease = bound(_earningPowerDecrease, 1, _stakeAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3327,7 +3369,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerDecrease = bound(_earningPowerDecrease, 1, _stakeAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3347,7 +3389,7 @@ contract BumpEarningPower is StakerRewardsTest { // Bump earning power is called vm.prank(_bumpCaller); vm.expectEmit(); - emit Staker.EarningPowerBumped( + emit StakerUpgradeable.EarningPowerBumped( _depositId, _oldEarningPower, _newEarningPower, _bumpCaller, _tipReceiver, _requestedTip ); govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip); @@ -3367,7 +3409,7 @@ contract BumpEarningPower is StakerRewardsTest { _rewardAmount = _boundToRealisticReward(_rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3379,7 +3421,7 @@ contract BumpEarningPower is StakerRewardsTest { // The staker's earning power changes earningPowerCalculator.__setEarningPowerForDelegatee(_delegatee, _newEarningPower); // Bump earning power is called - vm.expectRevert(Staker.Staker__InvalidTip.selector); + vm.expectRevert(StakerUpgradeable.Staker__InvalidTip.selector); vm.prank(_bumpCaller); govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip); } @@ -3398,7 +3440,7 @@ contract BumpEarningPower is StakerRewardsTest { _rewardAmount = _boundToRealisticReward(_rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3412,7 +3454,9 @@ contract BumpEarningPower is StakerRewardsTest { _delegatee, _newEarningPower, false ); // Bump earning power is called - vm.expectRevert(abi.encodeWithSelector(Staker.Staker__Unqualified.selector, _newEarningPower)); + vm.expectRevert( + abi.encodeWithSelector(StakerUpgradeable.Staker__Unqualified.selector, _newEarningPower) + ); vm.prank(_bumpCaller); govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip); } @@ -3430,7 +3474,7 @@ contract BumpEarningPower is StakerRewardsTest { _rewardAmount = _boundToRealisticReward(_rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3442,7 +3486,9 @@ contract BumpEarningPower is StakerRewardsTest { // The staker's earning power changes earningPowerCalculator.__setEarningPowerForDelegatee(_delegatee, _stakeAmount); // Bump earning power is called - vm.expectRevert(abi.encodeWithSelector(Staker.Staker__Unqualified.selector, _stakeAmount)); + vm.expectRevert( + abi.encodeWithSelector(StakerUpgradeable.Staker__Unqualified.selector, _stakeAmount) + ); vm.prank(_bumpCaller); govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip); } @@ -3462,7 +3508,7 @@ contract BumpEarningPower is StakerRewardsTest { _rewardAmount = bound(_rewardAmount, 200e6, maxBumpTip - 1); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3476,7 +3522,7 @@ contract BumpEarningPower is StakerRewardsTest { _delegatee, _stakeAmount + _earningPowerIncrease ); // // Bump earning power is called - vm.expectRevert(Staker.Staker__InsufficientUnclaimedRewards.selector); + vm.expectRevert(StakerUpgradeable.Staker__InsufficientUnclaimedRewards.selector); vm.prank(_bumpCaller); govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip); } @@ -3497,7 +3543,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerDecrease = bound(_earningPowerDecrease, 1, _stakeAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3511,7 +3557,7 @@ contract BumpEarningPower is StakerRewardsTest { _delegatee, _stakeAmount - _earningPowerDecrease ); // Bump earning power is called - vm.expectRevert(Staker.Staker__InsufficientUnclaimedRewards.selector); + vm.expectRevert(StakerUpgradeable.Staker__InsufficientUnclaimedRewards.selector); vm.prank(_bumpCaller); govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip); } @@ -3532,7 +3578,7 @@ contract BumpEarningPower is StakerRewardsTest { _earningPowerDecrease = bound(_earningPowerDecrease, 1, _stakeAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3568,7 +3614,7 @@ contract BumpEarningPower is StakerRewardsTest { vm.prank(admin); govStaker.setRewardNotifier(rewardNotifier, true); - (, Staker.DepositIdentifier depositId) = + (, StakerUpgradeable.DepositIdentifier depositId) = _boundMintAndStake(_depositor, _stakeAmount, _depositor); _mintTransferAndNotifyReward(_rewardAmount); @@ -3690,12 +3736,12 @@ contract RewardPerTokenAccumulated is StakerRewardsTest { _durationPercent3 = bound(_durationPercent3, 0, 200); // First deposit - Staker.DepositIdentifier _depositId1; + StakerUpgradeable.DepositIdentifier _depositId1; (_stakeAmount1, _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount1, _depositor1); _jumpAheadByPercentOfRewardDuration(_durationPercent1); // Second deposit - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount2, _depositor2); _jumpAheadByPercentOfRewardDuration(_durationPercent2); @@ -3731,7 +3777,7 @@ contract RewardPerTokenAccumulated is StakerRewardsTest { _durationPercent3 = _bound(_durationPercent3, 0, 200); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _depositor); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3770,7 +3816,7 @@ contract RewardPerTokenAccumulated is StakerRewardsTest { _durationPercent3 = _bound(_durationPercent3, 0, 200); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _depositor); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3806,7 +3852,7 @@ contract RewardPerTokenAccumulated is StakerRewardsTest { _durationPercent1 = _bound(_durationPercent1, 0, 200); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _depositor); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -3951,7 +3997,7 @@ contract RewardPerTokenAccumulated is StakerRewardsTest { _durationPercent1 = _bound(_durationPercent1, 0, 100); _durationPercent2 = _bound(_durationPercent2, 0, 100 - _durationPercent1); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; // A user deposits staking tokens (, _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _depositor); @@ -4085,7 +4131,7 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4106,7 +4152,7 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens w/ a claimer - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4128,7 +4174,7 @@ contract UnclaimedReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 0, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4154,7 +4200,7 @@ contract UnclaimedReward is StakerRewardsTest { // Two thirds of the duration time passes _jumpAheadByPercentOfRewardDuration(66); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The rest of the duration elapses _jumpAheadByPercentOfRewardDuration(34); @@ -4173,7 +4219,7 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4202,7 +4248,7 @@ contract UnclaimedReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 0, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4241,7 +4287,7 @@ contract UnclaimedReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 0, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4278,12 +4324,12 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount, _delegatee); // Some time passes _jumpAhead(3000); // Another depositor deposits the same number of staking tokens - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4306,12 +4352,12 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount, _delegatee); // Some time passes _jumpAhead(3000); // Another depositor deposits the same number of staking tokens - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4352,12 +4398,12 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount, _delegatee); // Some time passes _jumpAhead(3000); // Another depositor deposits the same number of staking tokens - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4396,12 +4442,12 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount, _delegatee); // Some time passes _jumpAhead(3000); // Another depositor deposits the same number of staking tokens - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4449,7 +4495,7 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // The first user stakes some tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount, _delegatee); // A small amount of time passes _jumpAhead(3000); @@ -4458,7 +4504,7 @@ contract UnclaimedReward is StakerRewardsTest { // Two thirds of the duration time elapses _jumpAheadByPercentOfRewardDuration(66); // A second user stakes the same amount of tokens - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount, _delegatee); // The rest of the duration elapses _jumpAheadByPercentOfRewardDuration(34); @@ -4485,7 +4531,7 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount2) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount2); // A user stakes tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount1); @@ -4523,12 +4569,12 @@ contract UnclaimedReward is StakerRewardsTest { // One quarter of the duration elapses _jumpAheadByPercentOfRewardDuration(25); // A user stakes some tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount, _delegatee); // Another 40 percent of the duration time elapses _jumpAheadByPercentOfRewardDuration(40); // Another user stakes some tokens - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount, _delegatee); // Another quarter of the duration elapses _jumpAheadByPercentOfRewardDuration(25); @@ -4575,12 +4621,12 @@ contract UnclaimedReward is StakerRewardsTest { // One quarter of the duration elapses _jumpAheadByPercentOfRewardDuration(25); // A user stakes some tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount1, _delegatee); // Another 40 percent of the duration time elapses _jumpAheadByPercentOfRewardDuration(40); // Another user stakes some tokens - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount2, _delegatee); // Another quarter of the duration elapses _jumpAheadByPercentOfRewardDuration(25); @@ -4626,7 +4672,7 @@ contract UnclaimedReward is StakerRewardsTest { (_stakeAmount, _rewardAmount3) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount3); // A user stakes tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount1); @@ -4674,12 +4720,12 @@ contract UnclaimedReward is StakerRewardsTest { // One quarter of the duration elapses _jumpAheadByPercentOfRewardDuration(25); // A user stakes some tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount, _delegatee); // Another 20 percent of the duration time elapses _jumpAheadByPercentOfRewardDuration(20); // Another user stakes some tokens - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount, _delegatee); // Another 20 percent of the duration time elapses _jumpAheadByPercentOfRewardDuration(20); @@ -4741,12 +4787,12 @@ contract UnclaimedReward is StakerRewardsTest { // One quarter of the duration elapses _jumpAheadByPercentOfRewardDuration(25); // A user stakes some tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount1, _delegatee); // Another 40 percent of the duration time elapses _jumpAheadByPercentOfRewardDuration(20); // Another user stakes some tokens - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount2, _delegatee); // Another quarter of the duration elapses _jumpAheadByPercentOfRewardDuration(20); @@ -4802,14 +4848,14 @@ contract UnclaimedReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 0, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId1) = + (, StakerUpgradeable.DepositIdentifier _depositId1) = _boundMintAndStake(_depositor1, _stakeAmount1, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); // A portion of the duration passes _jumpAheadByPercentOfRewardDuration(_durationPercent); // Another user deposits stake - (, Staker.DepositIdentifier _depositId2) = + (, StakerUpgradeable.DepositIdentifier _depositId2) = _boundMintAndStake(_depositor2, _stakeAmount2, _delegatee); // The rest of the duration elapses _jumpAheadByPercentOfRewardDuration(100 - _durationPercent); @@ -4843,14 +4889,16 @@ contract UnclaimedReward is StakerRewardsTest { vm.stopPrank(); // User deposit staking tokens - Staker.DepositIdentifier _depositId1 = _stake(_depositor1, _smallDepositAmount, _delegatee); - Staker.DepositIdentifier _depositId2 = _stake(_depositor2, _smallDepositAmount, _delegatee); + StakerUpgradeable.DepositIdentifier _depositId1 = + _stake(_depositor1, _smallDepositAmount, _delegatee); + StakerUpgradeable.DepositIdentifier _depositId2 = + _stake(_depositor2, _smallDepositAmount, _delegatee); _stake(_depositor3, _largeDepositAmount, _delegatee); // Every block _attacker deposits 0 stake and assigns _depositor1 as claimer, thus leading // to frequent updates of the reward checkpoint for _depositor1, during which rounding errors // could accrue. - Staker.DepositIdentifier _depositId = _stake(_attacker, 0, _delegatee, _depositor1); + StakerUpgradeable.DepositIdentifier _depositId = _stake(_attacker, 0, _delegatee, _depositor1); for (uint256 i = 0; i < 1000; ++i) { _jumpAhead(12); vm.prank(_attacker); @@ -4880,7 +4928,7 @@ contract ClaimReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 0, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4909,7 +4957,7 @@ contract ClaimReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 0, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4937,7 +4985,7 @@ contract ClaimReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 0, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4963,7 +5011,7 @@ contract ClaimReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 0, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -4988,7 +5036,7 @@ contract ClaimReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); vm.assume(_stakeAmount != _newEarningPower); @@ -5003,7 +5051,7 @@ contract ClaimReward is StakerRewardsTest { vm.prank(_depositor); govStaker.claimReward(_depositId); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _newEarningPower); } @@ -5020,7 +5068,7 @@ contract ClaimReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); vm.assume(_stakeAmount != _newEarningPower); @@ -5050,7 +5098,7 @@ contract ClaimReward is StakerRewardsTest { (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); vm.assume(_stakeAmount != _newEarningPower); @@ -5080,7 +5128,7 @@ contract ClaimReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 1, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -5090,7 +5138,7 @@ contract ClaimReward is StakerRewardsTest { uint256 _earned = govStaker.unclaimedReward(_depositId); vm.expectEmit(); - emit Staker.RewardClaimed(_depositId, _depositor, _earned, _stakeAmount); + emit StakerUpgradeable.RewardClaimed(_depositId, _depositor, _earned, _stakeAmount); vm.prank(_depositor); govStaker.claimReward(_depositId); @@ -5108,7 +5156,7 @@ contract ClaimReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 1, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -5118,7 +5166,7 @@ contract ClaimReward is StakerRewardsTest { uint256 _earned = govStaker.unclaimedReward(_depositId); vm.expectEmit(); - emit Staker.RewardClaimed(_depositId, _claimer, _earned, _stakeAmount); + emit StakerUpgradeable.RewardClaimed(_depositId, _claimer, _earned, _stakeAmount); vm.prank(_claimer); govStaker.claimReward(_depositId); @@ -5144,7 +5192,7 @@ contract ClaimReward is StakerRewardsTest { // The admin sets a claim fee _setClaimFeeAndCollector(_feeAmount, _feeCollector); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -5180,7 +5228,7 @@ contract ClaimReward is StakerRewardsTest { // The admin sets a claim fee _setClaimFeeAndCollector(_feeAmount, _feeCollector); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -5215,7 +5263,7 @@ contract ClaimReward is StakerRewardsTest { // The admin sets a claim fee _setClaimFeeAndCollector(_feeAmount, _feeCollector); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -5226,7 +5274,7 @@ contract ClaimReward is StakerRewardsTest { vm.prank(_depositor); vm.expectEmit(); - emit Staker.RewardClaimed(_depositId, _depositor, _earned - _feeAmount, _stakeAmount); + emit StakerUpgradeable.RewardClaimed(_depositId, _depositor, _earned - _feeAmount, _stakeAmount); govStaker.claimReward(_depositId); } @@ -5244,7 +5292,7 @@ contract ClaimReward is StakerRewardsTest { _durationPercent = bound(_durationPercent, 1, 100); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -5254,7 +5302,9 @@ contract ClaimReward is StakerRewardsTest { vm.prank(_notClaimer); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not claimer or owner"), _notClaimer + StakerUpgradeable.Staker__Unauthorized.selector, + bytes32("not claimer or owner"), + _notClaimer ) ); govStaker.claimReward(_depositId); @@ -5277,7 +5327,7 @@ contract ClaimReward is StakerRewardsTest { // The admin sets a claim fee _setClaimFeeAndCollector(uint96(govStaker.MAX_CLAIM_FEE()), _feeCollector); // A user deposits staking tokens - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); // The contract is notified of a reward _mintTransferAndNotifyReward(_rewardAmount); @@ -5303,7 +5353,7 @@ contract ClaimReward is StakerRewardsTest { _multiplierBips = bound(_multiplierBips, 0, 20_000); earningPowerCalculator.__setMultiplierBips(_multiplierBips); - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); _mintTransferAndNotifyReward(_rewardAmount); @@ -5314,7 +5364,7 @@ contract ClaimReward is StakerRewardsTest { uint256 _expectedEarningPower = (_stakeAmount * _multiplierBips) / 10_000; - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _expectedEarningPower); assertEq(govStaker.totalEarningPower(), _expectedEarningPower); assertEq(govStaker.depositorTotalEarningPower(_depositor), _expectedEarningPower); @@ -5334,7 +5384,7 @@ contract ClaimReward is StakerRewardsTest { earningPowerCalculator.__setFixedReturn(_fixedEarningPower); - (, Staker.DepositIdentifier _depositId) = + (, StakerUpgradeable.DepositIdentifier _depositId) = _boundMintAndStake(_depositor, _stakeAmount, _delegatee, _claimer); _mintTransferAndNotifyReward(_rewardAmount); @@ -5343,7 +5393,7 @@ contract ClaimReward is StakerRewardsTest { vm.prank(_depositor); govStaker.claimReward(_depositId); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.earningPower, _fixedEarningPower); assertEq(govStaker.totalEarningPower(), _fixedEarningPower); assertEq(govStaker.depositorTotalEarningPower(_depositor), _fixedEarningPower); @@ -5385,7 +5435,7 @@ contract Multicall is StakerRewardsTest { ); } - function _encodeStakeMore(Staker.DepositIdentifier _depositId, uint256 _stakeAmount) + function _encodeStakeMore(StakerUpgradeable.DepositIdentifier _depositId, uint256 _stakeAmount) internal pure returns (bytes memory) @@ -5395,7 +5445,7 @@ contract Multicall is StakerRewardsTest { ); } - function _encodeWithdraw(Staker.DepositIdentifier _depositId, uint256 _amount) + function _encodeWithdraw(StakerUpgradeable.DepositIdentifier _depositId, uint256 _amount) internal pure returns (bytes memory) @@ -5404,7 +5454,7 @@ contract Multicall is StakerRewardsTest { abi.encodeWithSelector(bytes4(keccak256("withdraw(uint256,uint256)")), _depositId, _amount); } - function _encodeAlterClaimer(Staker.DepositIdentifier _depositId, address _claimer) + function _encodeAlterClaimer(StakerUpgradeable.DepositIdentifier _depositId, address _claimer) internal pure returns (bytes memory) @@ -5414,7 +5464,7 @@ contract Multicall is StakerRewardsTest { ); } - function _encodeAlterDelegatee(Staker.DepositIdentifier _depositId, address _delegatee) + function _encodeAlterDelegatee(StakerUpgradeable.DepositIdentifier _depositId, address _delegatee) internal pure returns (bytes memory) @@ -5470,7 +5520,8 @@ contract Multicall is StakerRewardsTest { govToken.approve(address(govStaker), _stakeAmount0 + _stakeAmount1); // first, do initial stake without multicall - Staker.DepositIdentifier _depositId = govStaker.stake(_stakeAmount0, _delegatee0, _claimer0); + StakerUpgradeable.DepositIdentifier _depositId = + govStaker.stake(_stakeAmount0, _delegatee0, _claimer0); // some time goes by... vm.warp(_timeElapsed); @@ -5483,7 +5534,7 @@ contract Multicall is StakerRewardsTest { govStaker.multicall(_calls); vm.stopPrank(); - Staker.Deposit memory _depositResult = govStaker.deposits(_depositId); + StakerUpgradeable.Deposit memory _depositResult = govStaker.deposits(_depositId); assertEq(govStaker.depositorTotalStaked(_depositor), _stakeAmount0 + _stakeAmount1); assertEq(govStaker.depositorTotalEarningPower(_depositor), _stakeAmount0 + _stakeAmount1); assertEq(_depositResult.balance, _stakeAmount0 + _stakeAmount1); diff --git a/test/StakerCapDeposits.t.sol b/test/StakerCapDeposits.t.sol index 17bd532e..42734299 100644 --- a/test/StakerCapDeposits.t.sol +++ b/test/StakerCapDeposits.t.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.23; import {Vm, Test, stdStorage, StdStorage, console2, stdError} from "forge-std/Test.sol"; import {StakerTestBase} from "./StakerTestBase.sol"; import {StakerHarnessCapDeposits} from "./harnesses/StakerHarnessCapDeposits.sol"; -import {Staker} from "../src/Staker.sol"; -import {StakerCapDeposits} from "../src/extensions/StakerCapDeposits.sol"; +import {StakerUpgradeable} from "../src/StakerUpgradeable.sol"; +import {StakerCapDepositsUpgradeable} from "../src/extensions/StakerCapDepositsUpgradeable.sol"; import {DelegationSurrogate} from "../src/DelegationSurrogate.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; @@ -13,7 +13,12 @@ contract StakerCapDepositsTest is StakerTestBase { StakerHarnessCapDeposits govStaker; uint256 initialTotalStakeCap = 1_000_000e18; - function _deployStaker() public virtual override(StakerTestBase) returns (Staker _staker) { + function _deployStaker() + public + virtual + override(StakerTestBase) + returns (StakerUpgradeable _staker) + { StakerHarnessCapDeposits implementation = new StakerHarnessCapDeposits(); ERC1967Proxy proxy = new ERC1967Proxy( address(implementation), @@ -72,7 +77,7 @@ contract Constructor is StakerCapDepositsTest { function testFuzz_EmitsATotalStakeCapSetEvent(uint256 _initialTotalStakeCap) public { vm.expectEmit(); - emit StakerCapDeposits.TotalStakeCapSet(0, _initialTotalStakeCap); + emit StakerCapDepositsUpgradeable.TotalStakeCapSet(0, _initialTotalStakeCap); StakerHarnessCapDeposits implementation = new StakerHarnessCapDeposits(); ERC1967Proxy proxy = new ERC1967Proxy( address(implementation), @@ -104,7 +109,7 @@ contract SetTotalStakeCap is StakerCapDepositsTest { function testFuzz_EmitsATotalStakeCapSetEvent(uint256 _newTotalStakeCap) public { vm.prank(admin); vm.expectEmit(); - emit StakerCapDeposits.TotalStakeCapSet(initialTotalStakeCap, _newTotalStakeCap); + emit StakerCapDepositsUpgradeable.TotalStakeCapSet(initialTotalStakeCap, _newTotalStakeCap); govStaker.setTotalStakeCap(_newTotalStakeCap); } @@ -115,7 +120,9 @@ contract SetTotalStakeCap is StakerCapDepositsTest { vm.prank(_notAdmin); vm.expectRevert( - abi.encodeWithSelector(Staker.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin) + abi.encodeWithSelector( + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not admin"), _notAdmin + ) ); govStaker.setTotalStakeCap(_newTotalStakeCap); } @@ -156,10 +163,10 @@ contract _Stake is StakerCapDepositsTest { _mintGovToken(_depositor2, _amount2); // Calls to stake do not revert - Staker.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); - Staker.DepositIdentifier _depositId2 = _stake(_depositor2, _amount2, _delegatee2); - Staker.Deposit memory _deposit1 = _fetchDeposit(_depositId1); - Staker.Deposit memory _deposit2 = _fetchDeposit(_depositId2); + StakerUpgradeable.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); + StakerUpgradeable.DepositIdentifier _depositId2 = _stake(_depositor2, _amount2, _delegatee2); + StakerUpgradeable.Deposit memory _deposit1 = _fetchDeposit(_depositId1); + StakerUpgradeable.Deposit memory _deposit2 = _fetchDeposit(_depositId2); // Some sanity checks to ensure the stake operations completed. assertEq(govStaker.totalStaked(), _amount1 + _amount2); @@ -178,7 +185,7 @@ contract _Stake is StakerCapDepositsTest { vm.startPrank(_depositor); govToken.approve(address(govStaker), _amount); - vm.expectRevert(StakerCapDeposits.StakerCapDeposits__CapExceeded.selector); + vm.expectRevert(StakerCapDepositsUpgradeable.StakerCapDepositsUpgradeable__CapExceeded.selector); govStaker.stake(_amount, _delegatee); vm.stopPrank(); } @@ -199,8 +206,8 @@ contract _Stake is StakerCapDepositsTest { _mintGovToken(_depositor2, _amount2); // First call to stake does not revert. - Staker.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); - Staker.Deposit memory _deposit1 = _fetchDeposit(_depositId1); + StakerUpgradeable.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); + StakerUpgradeable.Deposit memory _deposit1 = _fetchDeposit(_depositId1); // Some sanity checks to ensure the stake operation completed. assertEq(govStaker.totalStaked(), _amount1); assertEq(_deposit1.balance, _amount1); @@ -208,7 +215,7 @@ contract _Stake is StakerCapDepositsTest { // The second attempt to stake should revert vm.startPrank(_depositor2); govToken.approve(address(govStaker), _amount2); - vm.expectRevert(StakerCapDeposits.StakerCapDeposits__CapExceeded.selector); + vm.expectRevert(StakerCapDepositsUpgradeable.StakerCapDepositsUpgradeable__CapExceeded.selector); govStaker.stake(_amount2, _delegatee2); vm.stopPrank(); } @@ -229,8 +236,8 @@ contract _Stake is StakerCapDepositsTest { _mintGovToken(_depositor2, _amount2); // First call to stake does not revert. - Staker.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); - Staker.Deposit memory _deposit1 = _fetchDeposit(_depositId1); + StakerUpgradeable.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); + StakerUpgradeable.Deposit memory _deposit1 = _fetchDeposit(_depositId1); // Some sanity checks to ensure the stake operation completed. assertEq(govStaker.totalStaked(), _amount1); assertEq(_deposit1.balance, _amount1); @@ -238,7 +245,7 @@ contract _Stake is StakerCapDepositsTest { // The second attempt to stake should revert. vm.startPrank(_depositor2); govToken.approve(address(govStaker), _amount2); - vm.expectRevert(StakerCapDeposits.StakerCapDeposits__CapExceeded.selector); + vm.expectRevert(StakerCapDepositsUpgradeable.StakerCapDepositsUpgradeable__CapExceeded.selector); govStaker.stake(_amount2, _delegatee2); vm.stopPrank(); @@ -248,10 +255,10 @@ contract _Stake is StakerCapDepositsTest { govStaker.setTotalStakeCap(_newTotalStakeCap); // Now the same deposit succeeds. - Staker.DepositIdentifier _depositId2 = _stake(_depositor2, _amount2, _delegatee2); + StakerUpgradeable.DepositIdentifier _depositId2 = _stake(_depositor2, _amount2, _delegatee2); // Some sanity checks to ensure the stake operation completed. - Staker.Deposit memory _deposit2 = _fetchDeposit(_depositId2); + StakerUpgradeable.Deposit memory _deposit2 = _fetchDeposit(_depositId2); assertEq(govStaker.totalStaked(), _amount1 + _amount2); assertEq(_deposit2.balance, _amount2); } @@ -271,8 +278,8 @@ contract _Stake is StakerCapDepositsTest { _mintGovToken(_depositor2, _amount2); // First call to stake does not revert. - Staker.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); - Staker.Deposit memory _deposit1 = _fetchDeposit(_depositId1); + StakerUpgradeable.DepositIdentifier _depositId1 = _stake(_depositor1, _amount1, _delegatee1); + StakerUpgradeable.Deposit memory _deposit1 = _fetchDeposit(_depositId1); // Some sanity checks to ensure the stake operation completed. assertEq(govStaker.totalStaked(), _amount1); assertEq(_deposit1.balance, _amount1); @@ -285,7 +292,7 @@ contract _Stake is StakerCapDepositsTest { // The second attempt to stake should revert. vm.startPrank(_depositor2); govToken.approve(address(govStaker), _amount2); - vm.expectRevert(StakerCapDeposits.StakerCapDeposits__CapExceeded.selector); + vm.expectRevert(StakerCapDepositsUpgradeable.StakerCapDepositsUpgradeable__CapExceeded.selector); govStaker.stake(_amount2, _delegatee2); vm.stopPrank(); } @@ -305,14 +312,14 @@ contract _StakeMore is StakerCapDepositsTest { _mintGovToken(_depositor, _depositAmount + _addAmount); // Initial stake is completed - Staker.DepositIdentifier _depositId = _stake(_depositor, _depositAmount, _delegatee); + StakerUpgradeable.DepositIdentifier _depositId = _stake(_depositor, _depositAmount, _delegatee); // More stake is added without the call reverting. vm.startPrank(_depositor); govToken.approve(address(govStaker), _addAmount); govStaker.stakeMore(_depositId, _addAmount); vm.stopPrank(); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); DelegationSurrogate _surrogate = govStaker.surrogates(_deposit.delegatee); // Sanity checks to make sure the staking operations completed successfully. @@ -334,12 +341,12 @@ contract _StakeMore is StakerCapDepositsTest { _mintGovToken(_depositor, _depositAmount + _addAmount); // Initial stake is completed - Staker.DepositIdentifier _depositId = _stake(_depositor, _depositAmount, _delegatee); + StakerUpgradeable.DepositIdentifier _depositId = _stake(_depositor, _depositAmount, _delegatee); // Reverts when attempting to add more such that the cap is exceeded. vm.startPrank(_depositor); govToken.approve(address(govStaker), _addAmount); - vm.expectRevert(StakerCapDeposits.StakerCapDeposits__CapExceeded.selector); + vm.expectRevert(StakerCapDepositsUpgradeable.StakerCapDepositsUpgradeable__CapExceeded.selector); govStaker.stakeMore(_depositId, _addAmount); vm.stopPrank(); } diff --git a/test/StakerOnBehalf.t.sol b/test/StakerOnBehalf.t.sol index f92a6926..4906b153 100644 --- a/test/StakerOnBehalf.t.sol +++ b/test/StakerOnBehalf.t.sol @@ -2,10 +2,10 @@ pragma solidity ^0.8.23; import {stdStorage, StdStorage} from "forge-std/Test.sol"; -import {StakerOnBehalf} from "../src/extensions/StakerOnBehalf.sol"; +import {StakerOnBehalfUpgradeable} from "../src/extensions/StakerOnBehalfUpgradeable.sol"; import {StakerTest, StakerRewardsTest} from "./Staker.t.sol"; import {StakerHarness} from "./harnesses/StakerHarness.sol"; -import {Staker, IERC20, IEarningPowerCalculator} from "../src/Staker.sol"; +import {StakerUpgradeable, IERC20, IEarningPowerCalculator} from "../src/StakerUpgradeable.sol"; import {IERC20Staking} from "../src/interfaces/IERC20Staking.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; @@ -145,11 +145,11 @@ contract StakeOnBehalf is StakerTest { bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); vm.prank(_sender); - Staker.DepositIdentifier _depositId = govStaker.stakeOnBehalf( + StakerUpgradeable.DepositIdentifier _depositId = govStaker.stakeOnBehalf( _depositAmount, _delegatee, _claimer, _depositor, _deadline, _signature ); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); assertEq(_deposit.balance, _depositAmount); assertEq(_deposit.owner, _depositor); @@ -198,7 +198,7 @@ contract StakeOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.stakeOnBehalf(_depositAmount, _delegatee, _claimer, _depositor, _deadline, _signature); } @@ -242,7 +242,7 @@ contract StakeOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__ExpiredDeadline.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__ExpiredDeadline.selector); vm.prank(_sender); govStaker.stakeOnBehalf(_depositAmount, _delegatee, _claimer, _depositor, _deadline, _signature); } @@ -302,7 +302,7 @@ contract StakeOnBehalf is StakerTest { if (_randomSeed % 6 == 5) _signature = _modifySignature(_signature, _randomSeed); vm.prank(_sender); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); govStaker.stakeOnBehalf(_depositAmount, _delegatee, _claimer, _depositor, _deadline, _signature); } } @@ -325,10 +325,10 @@ contract StakeMoreOnBehalf is StakerTest { _depositorPrivateKey = bound(_depositorPrivateKey, 1, 100e18); address _depositor = vm.addr(_depositorPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); _stakeMoreAmount = _boundToRealisticStake(_stakeMoreAmount); _mintGovToken(_depositor, _stakeMoreAmount); @@ -389,7 +389,7 @@ contract StakeMoreOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); @@ -415,7 +415,7 @@ contract StakeMoreOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.stakeMoreOnBehalf(_depositId, _stakeMoreAmount, _depositor, _deadline, _signature); } @@ -440,7 +440,7 @@ contract StakeMoreOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); @@ -466,7 +466,7 @@ contract StakeMoreOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__ExpiredDeadline.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__ExpiredDeadline.selector); vm.prank(_sender); govStaker.stakeMoreOnBehalf(_depositId, _stakeMoreAmount, _depositor, _deadline, _signature); } @@ -493,13 +493,13 @@ contract StakeMoreOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor ) ); vm.prank(_sender); @@ -527,7 +527,7 @@ contract StakeMoreOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_initialDepositAmount, _depositId) = _boundMintAndStake(_depositor, _initialDepositAmount, _delegatee, _claimer); @@ -564,7 +564,7 @@ contract StakeMoreOnBehalf is StakerTest { bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); if (_randomSeed % 4 == 3) _signature = _modifySignature(_signature, _randomSeed); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.stakeMoreOnBehalf(_depositId, _stakeMoreAmount, _depositor, _deadline, _signature); } @@ -591,9 +591,9 @@ contract AlterDelegateeOnBehalf is StakerTest { _depositorPrivateKey = bound(_depositorPrivateKey, 1, 100e18); address _depositor = vm.addr(_depositorPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); stdstore.target(address(govStaker)).sig("nonces(address)").with_key(_depositor).checked_write( _currentNonce @@ -647,7 +647,7 @@ contract AlterDelegateeOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); bytes32 _message = keccak256( @@ -660,7 +660,7 @@ contract AlterDelegateeOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.alterDelegateeOnBehalf(_depositId, _newDelegatee, _depositor, _deadline, _signature); } @@ -688,7 +688,7 @@ contract AlterDelegateeOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); bytes32 _message = keccak256( @@ -706,7 +706,7 @@ contract AlterDelegateeOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__ExpiredDeadline.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__ExpiredDeadline.selector); vm.prank(_sender); govStaker.alterDelegateeOnBehalf(_depositId, _newDelegatee, _depositor, _deadline, _signature); } @@ -730,12 +730,12 @@ contract AlterDelegateeOnBehalf is StakerTest { _amount = _boundMintAmount(_amount); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor ) ); vm.prank(_sender); @@ -765,7 +765,7 @@ contract AlterDelegateeOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); bytes32 _message = keccak256( @@ -794,7 +794,7 @@ contract AlterDelegateeOnBehalf is StakerTest { bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); if (_randomSeed % 4 == 3) _signature = _modifySignature(_signature, _randomSeed); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.alterDelegateeOnBehalf(_depositId, _newDelegatee, _depositor, _deadline, _signature); } @@ -821,9 +821,9 @@ contract AlterClaimerOnBehalf is StakerTest { _depositorPrivateKey = bound(_depositorPrivateKey, 1, 100e18); address _depositor = vm.addr(_depositorPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); stdstore.target(address(govStaker)).sig("nonces(address)").with_key(_depositor).checked_write( _currentNonce @@ -877,7 +877,7 @@ contract AlterClaimerOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); bytes32 _message = keccak256( @@ -895,7 +895,7 @@ contract AlterClaimerOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.alterClaimerOnBehalf(_depositId, _newClaimer, _depositor, _deadline, _signature); } @@ -923,7 +923,7 @@ contract AlterClaimerOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); bytes32 _message = keccak256( @@ -941,7 +941,7 @@ contract AlterClaimerOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__ExpiredDeadline.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__ExpiredDeadline.selector); vm.prank(_sender); govStaker.alterClaimerOnBehalf(_depositId, _newClaimer, _depositor, _deadline, _signature); } @@ -965,12 +965,12 @@ contract AlterClaimerOnBehalf is StakerTest { _amount = _boundMintAmount(_amount); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor ) ); vm.prank(_sender); @@ -998,7 +998,7 @@ contract AlterClaimerOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); bytes32 _message = keccak256( @@ -1027,7 +1027,7 @@ contract AlterClaimerOnBehalf is StakerTest { bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); if (_randomSeed % 4 == 3) _signature = _modifySignature(_signature, _randomSeed); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.alterClaimerOnBehalf(_depositId, _newClaimer, _depositor, _deadline, _signature); } @@ -1051,10 +1051,10 @@ contract WithdrawOnBehalf is StakerTest { _depositorPrivateKey = bound(_depositorPrivateKey, 1, 100e18); address _depositor = vm.addr(_depositorPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); - Staker.Deposit memory _deposit = _fetchDeposit(_depositId); + StakerUpgradeable.Deposit memory _deposit = _fetchDeposit(_depositId); _withdrawAmount = bound(_withdrawAmount, 0, _depositAmount); stdstore.target(address(govStaker)).sig("nonces(address)").with_key(_depositor).checked_write( @@ -1106,7 +1106,7 @@ contract WithdrawOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1125,7 +1125,7 @@ contract WithdrawOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.withdrawOnBehalf(_depositId, _withdrawAmount, _depositor, _deadline, _signature); } @@ -1150,7 +1150,7 @@ contract WithdrawOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1169,7 +1169,7 @@ contract WithdrawOnBehalf is StakerTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__ExpiredDeadline.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__ExpiredDeadline.selector); vm.prank(_sender); govStaker.withdrawOnBehalf(_depositId, _withdrawAmount, _depositor, _deadline, _signature); } @@ -1193,12 +1193,12 @@ contract WithdrawOnBehalf is StakerTest { _amount = _boundMintAmount(_amount); _mintGovToken(_depositor, _amount); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_amount, _depositId) = _boundMintAndStake(_depositor, _amount, _delegatee, _claimer); vm.expectRevert( abi.encodeWithSelector( - Staker.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor + StakerUpgradeable.Staker__Unauthorized.selector, bytes32("not owner"), _notDepositor ) ); vm.prank(_sender); @@ -1226,7 +1226,7 @@ contract WithdrawOnBehalf is StakerTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1256,7 +1256,7 @@ contract WithdrawOnBehalf is StakerTest { bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); if (_randomSeed % 4 == 3) _signature = _modifySignature(_signature, _randomSeed); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.withdrawOnBehalf(_depositId, _withdrawAmount, _depositor, _deadline, _signature); } @@ -1279,7 +1279,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { _claimerPrivateKey = bound(_claimerPrivateKey, 1, 100e18); address _claimer = vm.addr(_claimerPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_depositAmount, _rewardAmount); _durationPercent = bound(_durationPercent, 0, 100); @@ -1330,7 +1330,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { _depositorPrivateKey = bound(_depositorPrivateKey, 1, 100e18); address _depositor = vm.addr(_depositorPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_depositAmount, _rewardAmount); _durationPercent = bound(_durationPercent, 0, 100); @@ -1382,7 +1382,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { _claimerPrivateKey = bound(_claimerPrivateKey, 1, 100e18); address _claimer = vm.addr(_claimerPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_depositAmount, _rewardAmount); _durationPercent = bound(_durationPercent, 0, 100); @@ -1434,7 +1434,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { _claimerPrivateKey = bound(_claimerPrivateKey, 1, 100e18); address _claimer = vm.addr(_claimerPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_depositAmount, _rewardAmount); _durationPercent = bound(_durationPercent, 0, 100); @@ -1458,7 +1458,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_claimerPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.claimRewardOnBehalf(_depositId, _deadline, _signature); } @@ -1480,7 +1480,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { _depositorPrivateKey = bound(_depositorPrivateKey, 1, 100e18); address _depositor = vm.addr(_depositorPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_depositAmount, _rewardAmount); _durationPercent = bound(_durationPercent, 0, 100); @@ -1505,7 +1505,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_depositorPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.claimRewardOnBehalf(_depositId, _deadline, _signature); } @@ -1525,7 +1525,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { _claimerPrivateKey = bound(_claimerPrivateKey, 1, 100e18); address _claimer = vm.addr(_claimerPrivateKey); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_depositAmount, _rewardAmount); _durationPercent = bound(_durationPercent, 0, 100); @@ -1549,7 +1549,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { keccak256(abi.encodePacked("\x19\x01", EIP712_DOMAIN_SEPARATOR, _message)); bytes memory _signature = _sign(_claimerPrivateKey, _messageHash); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__ExpiredDeadline.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__ExpiredDeadline.selector); vm.prank(_sender); govStaker.claimRewardOnBehalf(_depositId, _deadline, _signature); } @@ -1574,7 +1574,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { _currentNonce ); - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; (_depositAmount, _depositId) = _boundMintAndStake(_depositor, _depositAmount, _delegatee, _claimer); @@ -1597,7 +1597,7 @@ contract ClaimRewardOnBehalf is StakerRewardsTest { bytes memory _signature = _sign(_claimerPrivateKey, _messageHash); if (_randomSeed % 4 == 3) _signature = _modifySignature(_signature, _randomSeed); - vm.expectRevert(StakerOnBehalf.StakerOnBehalf__InvalidSignature.selector); + vm.expectRevert(StakerOnBehalfUpgradeable.StakerOnBehalfUpgradeable__InvalidSignature.selector); vm.prank(_sender); govStaker.claimRewardOnBehalf(_depositId, _deadline, _signature); } diff --git a/test/StakerTestBase.sol b/test/StakerTestBase.sol index 773fd302..e1bf5027 100644 --- a/test/StakerTestBase.sol +++ b/test/StakerTestBase.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.23; import {Vm, Test, stdStorage, StdStorage, console2, stdError} from "forge-std/Test.sol"; -import {Staker} from "../src/Staker.sol"; +import {StakerUpgradeable} from "../src/StakerUpgradeable.sol"; import {DelegationSurrogate} from "../src/DelegationSurrogate.sol"; import {ERC20VotesMock} from "./mocks/MockERC20Votes.sol"; import {ERC20Fake} from "./fakes/ERC20Fake.sol"; @@ -23,14 +23,14 @@ abstract contract StakerTestBase is Test, PercentAssertions { address admin; address rewardNotifier; - Staker baseStaker; + StakerUpgradeable baseStaker; uint256 SCALE_FACTOR; uint256 maxBumpTip = 1e18; mapping(DelegationSurrogate surrogate => bool isKnown) isKnownSurrogate; mapping(address depositor => bool isKnown) isKnownDepositor; - function _deployStaker() public virtual returns (Staker _staker); + function _deployStaker() public virtual returns (StakerUpgradeable _staker); function setUp() public virtual { // Set the block timestamp to an arbitrary value to avoid introducing assumptions into tests @@ -101,8 +101,8 @@ abstract contract StakerTestBase is Test, PercentAssertions { } function _setClaimFeeAndCollector(uint96 _amount, address _collector) internal { - Staker.ClaimFeeParameters memory _params = - Staker.ClaimFeeParameters({feeAmount: _amount, feeCollector: _collector}); + StakerUpgradeable.ClaimFeeParameters memory _params = + StakerUpgradeable.ClaimFeeParameters({feeAmount: _amount, feeCollector: _collector}); vm.prank(admin); baseStaker.setClaimFeeParameters(_params); @@ -110,7 +110,7 @@ abstract contract StakerTestBase is Test, PercentAssertions { function _stake(address _depositor, uint256 _amount, address _delegatee) internal - returns (Staker.DepositIdentifier _depositId) + returns (StakerUpgradeable.DepositIdentifier _depositId) { vm.assume(_delegatee != address(0)); @@ -125,7 +125,7 @@ abstract contract StakerTestBase is Test, PercentAssertions { function _stake(address _depositor, uint256 _amount, address _delegatee, address _claimer) internal - returns (Staker.DepositIdentifier _depositId) + returns (StakerUpgradeable.DepositIdentifier _depositId) { vm.assume(_delegatee != address(0) && _claimer != address(0)); @@ -138,12 +138,12 @@ abstract contract StakerTestBase is Test, PercentAssertions { _assumeSafeDepositorAndSurrogate(_depositor, _delegatee); } - function _fetchDeposit(Staker.DepositIdentifier _depositId) + function _fetchDeposit(StakerUpgradeable.DepositIdentifier _depositId) internal view - returns (Staker.Deposit memory) + returns (StakerUpgradeable.Deposit memory) { - Staker.Deposit memory _deposit = baseStaker.deposits(_depositId); + StakerUpgradeable.Deposit memory _deposit = baseStaker.deposits(_depositId); uint96 _balance = _deposit.balance; address _owner = _deposit.owner; uint96 _earningPower = _deposit.earningPower; @@ -151,7 +151,7 @@ abstract contract StakerTestBase is Test, PercentAssertions { address _claimer = _deposit.claimer; uint256 _rewardPerTokenCheckpoint = _deposit.rewardPerTokenCheckpoint; uint256 _scaledUnclaimedRewardCheckpoint = _deposit.scaledUnclaimedRewardCheckpoint; - return Staker.Deposit({ + return StakerUpgradeable.Deposit({ balance: _balance, owner: _owner, delegatee: _delegatee, @@ -164,7 +164,7 @@ abstract contract StakerTestBase is Test, PercentAssertions { function _boundMintAndStake(address _depositor, uint256 _amount, address _delegatee) internal - returns (uint256 _boundedAmount, Staker.DepositIdentifier _depositId) + returns (uint256 _boundedAmount, StakerUpgradeable.DepositIdentifier _depositId) { _boundedAmount = _boundMintAmount(_amount); _mintGovToken(_depositor, _boundedAmount); @@ -176,7 +176,7 @@ abstract contract StakerTestBase is Test, PercentAssertions { uint256 _amount, address _delegatee, address _claimer - ) internal returns (uint256 _boundedAmount, Staker.DepositIdentifier _depositId) { + ) internal returns (uint256 _boundedAmount, StakerUpgradeable.DepositIdentifier _depositId) { _boundedAmount = _boundMintAmount(_amount); _mintGovToken(_depositor, _boundedAmount); _depositId = _stake(_depositor, _boundedAmount, _delegatee, _claimer); diff --git a/test/fakes/DeployBaseFake.sol b/test/fakes/DeployBaseFake.sol index 8b033d5f..d92fddf0 100644 --- a/test/fakes/DeployBaseFake.sol +++ b/test/fakes/DeployBaseFake.sol @@ -9,7 +9,7 @@ import {DeployIdentityEarningPowerCalculator} from import {IMintable} from "../../src/interfaces/IMintable.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -73,7 +73,7 @@ contract DeployBaseFake is internal virtual override - returns (Staker) + returns (StakerUpgradeable) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); StakerHarness implementation = new StakerHarness(); diff --git a/test/fakes/DeployBaseInvalidStakerAdminFake.sol b/test/fakes/DeployBaseInvalidStakerAdminFake.sol index 3bcd549f..86eaa3a3 100644 --- a/test/fakes/DeployBaseInvalidStakerAdminFake.sol +++ b/test/fakes/DeployBaseInvalidStakerAdminFake.sol @@ -9,7 +9,7 @@ import {DeployIdentityEarningPowerCalculator} from import {IMintable} from "../../src/interfaces/IMintable.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -73,7 +73,7 @@ contract DeployBaseInvalidStakerAdminFake is internal virtual override - returns (Staker) + returns (StakerUpgradeable) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); StakerHarness implementation = new StakerHarness(); diff --git a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol index 4a131788..3df23882 100644 --- a/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol +++ b/test/fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol @@ -8,7 +8,7 @@ import {DeployBinaryEligibilityOracleEarningPowerCalculator} from "../../src/script/calculators/DeployBinaryEligibilityOracleEarningPowerCalculator.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; import {IMintable} from "../../src/interfaces/IMintable.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -94,7 +94,7 @@ contract DeployBinaryEligibilityOracleEarningPowerCalculatorFake is internal virtual override - returns (Staker) + returns (StakerUpgradeable) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); StakerHarness implementation = new StakerHarness(); diff --git a/test/fakes/DeployMultipleRewardNotifiersFake.sol b/test/fakes/DeployMultipleRewardNotifiersFake.sol index 09585f5c..9d11c0f4 100644 --- a/test/fakes/DeployMultipleRewardNotifiersFake.sol +++ b/test/fakes/DeployMultipleRewardNotifiersFake.sol @@ -10,7 +10,7 @@ import {DeployIdentityEarningPowerCalculator} from "../../src/script/calculators/DeployIdentityEarningPowerCalculator.sol"; import {IMintable} from "../../src/interfaces/IMintable.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -85,7 +85,7 @@ contract DeployMultipleRewardNotifiersFake is }); } - function _deployRewardNotifiers(Staker _staker) + function _deployRewardNotifiers(StakerUpgradeable _staker) internal virtual override(DeployBase, DeployMintRewardNotifier, DeployTransferRewardNotifier) @@ -98,7 +98,7 @@ contract DeployMultipleRewardNotifiersFake is internal virtual override - returns (Staker) + returns (StakerUpgradeable) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); StakerHarness implementation = new StakerHarness(); diff --git a/test/fakes/DeployTransferFromRewardNotifierFake.sol b/test/fakes/DeployTransferFromRewardNotifierFake.sol index 634f3322..814de9dc 100644 --- a/test/fakes/DeployTransferFromRewardNotifierFake.sol +++ b/test/fakes/DeployTransferFromRewardNotifierFake.sol @@ -8,7 +8,7 @@ import {DeployTransferFromRewardNotifier} from import {DeployIdentityEarningPowerCalculator} from "../../src/script/calculators/DeployIdentityEarningPowerCalculator.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -72,7 +72,7 @@ contract DeployTransferFromRewardNotifierFake is internal virtual override - returns (Staker) + returns (StakerUpgradeable) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); StakerHarness implementation = new StakerHarness(); diff --git a/test/fakes/DeployTransferRewardNotifierFake.sol b/test/fakes/DeployTransferRewardNotifierFake.sol index ebd8d0df..2b9fa0ea 100644 --- a/test/fakes/DeployTransferRewardNotifierFake.sol +++ b/test/fakes/DeployTransferRewardNotifierFake.sol @@ -8,7 +8,7 @@ import {DeployTransferRewardNotifier} from import {DeployIdentityEarningPowerCalculator} from "../../src/script/calculators/DeployIdentityEarningPowerCalculator.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {StakerHarness} from "../harnesses/StakerHarness.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -71,7 +71,7 @@ contract DeployTransferRewardNotifierFake is internal virtual override - returns (Staker) + returns (StakerUpgradeable) { StakerConfiguration memory _config = _stakerConfiguration(_earningPowerCalculator); StakerHarness implementation = new StakerHarness(); diff --git a/test/gas-reports/Staker.g.sol b/test/gas-reports/Staker.g.sol index d804fc93..9e6a51e0 100644 --- a/test/gas-reports/Staker.g.sol +++ b/test/gas-reports/Staker.g.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.23; import {Vm, Test, stdStorage, StdStorage, console2, stdError} from "forge-std/Test.sol"; import {GasReport} from "../lib/GasReport.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {StakerTest} from "../Staker.t.sol"; contract StakerGasReport is StakerTest, GasReport { @@ -25,7 +25,7 @@ contract StakerGasReport is StakerTest, GasReport { function runScenarios() public override { address _staker; address _delegatee; - Staker.DepositIdentifier _depositId; + StakerUpgradeable.DepositIdentifier _depositId; uint256 _rewardAmount; startScenario("First stake to a new delegatee"); diff --git a/test/harnesses/StakerHarness.sol b/test/harnesses/StakerHarness.sol index e12a21fd..9d5d38a1 100644 --- a/test/harnesses/StakerHarness.sol +++ b/test/harnesses/StakerHarness.sol @@ -1,10 +1,12 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.23; -import {Staker} from "../../src/Staker.sol"; -import {StakerPermitAndStake} from "../../src/extensions/StakerPermitAndStake.sol"; -import {StakerOnBehalf} from "../../src/extensions/StakerOnBehalf.sol"; -import {StakerDelegateSurrogateVotes} from "../../src/extensions/StakerDelegateSurrogateVotes.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; +import {StakerPermitAndStakeUpgradeable} from + "../../src/extensions/StakerPermitAndStakeUpgradeable.sol"; +import {StakerOnBehalfUpgradeable} from "../../src/extensions/StakerOnBehalfUpgradeable.sol"; +import {StakerDelegateSurrogateVotesUpgradeable} from + "../../src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; @@ -15,10 +17,10 @@ import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalcula import {DelegationSurrogate} from "../../src/DelegationSurrogate.sol"; contract StakerHarness is - Staker, - StakerPermitAndStake, - StakerOnBehalf, - StakerDelegateSurrogateVotes + StakerUpgradeable, + StakerPermitAndStakeUpgradeable, + StakerOnBehalfUpgradeable, + StakerDelegateSurrogateVotesUpgradeable { constructor() { _disableInitializers(); @@ -33,11 +35,11 @@ contract StakerHarness is IEarningPowerCalculator _earningPowerCalculator, string memory _name ) public initializer { - __Staker_init( + __StakerUpgradeable_init( _rewardToken, _stakeToken, _maxClaimFee, _admin, _maxBumpTip, _earningPowerCalculator ); - __StakerPermitAndStake_init(IERC20Permit(address(_stakeToken))); - __StakerDelegateSurrogateVotes_init(IERC20Delegates(address(_stakeToken))); + __StakerPermitAndStakeUpgradeable_init(IERC20Permit(address(_stakeToken))); + __StakerDelegateSurrogateVotesUpgradeable_init(IERC20Delegates(address(_stakeToken))); __EIP712_init(_name, "1"); __Nonces_init(); _setMaxClaimFee(_maxClaimFee); diff --git a/test/harnesses/StakerHarnessCapDeposits.sol b/test/harnesses/StakerHarnessCapDeposits.sol index f9b19da7..585a1f80 100644 --- a/test/harnesses/StakerHarnessCapDeposits.sol +++ b/test/harnesses/StakerHarnessCapDeposits.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.23; -import {Staker} from "../../src/Staker.sol"; -import {StakerCapDeposits} from "../../src/extensions/StakerCapDeposits.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; +import {StakerCapDepositsUpgradeable} from "../../src/extensions/StakerCapDepositsUpgradeable.sol"; import {StakerHarness} from "../../test/harnesses/StakerHarness.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -11,7 +11,7 @@ import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC2 import {IERC20Delegates} from "../../src/interfaces/IERC20Delegates.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; -contract StakerHarnessCapDeposits is StakerHarness, StakerCapDeposits { +contract StakerHarnessCapDeposits is StakerHarness, StakerCapDepositsUpgradeable { // constructor( // IERC20 _rewardsToken, // IERC20Staking _stakeToken, @@ -36,13 +36,13 @@ contract StakerHarnessCapDeposits is StakerHarness, StakerCapDeposits { string memory _name, uint256 _initialStakeCap ) public initializer { - __Staker_init( + __StakerUpgradeable_init( _rewardToken, _stakeToken, _maxClaimFee, _admin, _maxBumpTip, _earningPowerCalculator ); - __StakerPermitAndStake_init(IERC20Permit(address(_stakeToken))); - __StakerDelegateSurrogateVotes_init(IERC20Delegates(address(_stakeToken))); + __StakerPermitAndStakeUpgradeable_init(IERC20Permit(address(_stakeToken))); + __StakerDelegateSurrogateVotesUpgradeable_init(IERC20Delegates(address(_stakeToken))); __EIP712_init(_name, "1"); - __StakerCapDeposits_init(_initialStakeCap); + __StakerCapDepositsUpgradeable_init(_initialStakeCap); __Nonces_init(); _setMaxClaimFee(_maxClaimFee); _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); @@ -51,17 +51,17 @@ contract StakerHarnessCapDeposits is StakerHarness, StakerCapDeposits { function _stake(address _depositor, uint256 _amount, address _delegatee, address _claimer) internal virtual - override(Staker, StakerCapDeposits) + override(StakerUpgradeable, StakerCapDepositsUpgradeable) returns (DepositIdentifier _depositId) { - return StakerCapDeposits._stake(_depositor, _amount, _delegatee, _claimer); + return StakerCapDepositsUpgradeable._stake(_depositor, _amount, _delegatee, _claimer); } function _stakeMore(Deposit storage deposit, DepositIdentifier _depositId, uint256 _amount) internal virtual - override(Staker, StakerCapDeposits) + override(StakerUpgradeable, StakerCapDepositsUpgradeable) { - StakerCapDeposits._stakeMore(deposit, _depositId, _amount); + StakerCapDepositsUpgradeable._stakeMore(deposit, _depositId, _amount); } } diff --git a/test/helpers/DepositIdSet.sol b/test/helpers/DepositIdSet.sol index 03a5f5f4..2eb64e1a 100644 --- a/test/helpers/DepositIdSet.sol +++ b/test/helpers/DepositIdSet.sol @@ -1,18 +1,18 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.23; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; struct DepositIdSet { - Staker.DepositIdentifier[] ids; - mapping(Staker.DepositIdentifier => bool) saved; + StakerUpgradeable.DepositIdentifier[] ids; + mapping(StakerUpgradeable.DepositIdentifier => bool) saved; } library LibDepositIdSet { function reduce( DepositIdSet storage s, uint256 acc, - function(uint256,Staker.DepositIdentifier) external returns (uint256) func + function(uint256,StakerUpgradeable.DepositIdentifier) external returns (uint256) func ) internal returns (uint256) { for (uint256 i; i < s.ids.length; ++i) { acc = func(acc, s.ids[i]); @@ -20,7 +20,7 @@ library LibDepositIdSet { return acc; } - function add(DepositIdSet storage s, Staker.DepositIdentifier id) internal { + function add(DepositIdSet storage s, StakerUpgradeable.DepositIdentifier id) internal { if (!s.saved[id]) { s.ids.push(id); s.saved[id] = true; diff --git a/test/helpers/Staker.handler.sol b/test/helpers/Staker.handler.sol index e16fa19f..b656a79d 100644 --- a/test/helpers/Staker.handler.sol +++ b/test/helpers/Staker.handler.sol @@ -7,7 +7,7 @@ import {StdUtils} from "forge-std/StdUtils.sol"; import {console} from "forge-std/console.sol"; import {AddressSet, LibAddressSet} from "../helpers/AddressSet.sol"; import {DepositIdSet, LibDepositIdSet} from "../helpers/DepositIdSet.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract StakerHandler is CommonBase, StdCheats, StdUtils { @@ -15,7 +15,7 @@ contract StakerHandler is CommonBase, StdCheats, StdUtils { using LibDepositIdSet for DepositIdSet; // system setup - Staker public govStaker; + StakerUpgradeable public govStaker; IERC20 public stakeToken; IERC20 public rewardToken; address public admin; @@ -49,7 +49,7 @@ contract StakerHandler is CommonBase, StdCheats, StdUtils { _; } - constructor(Staker _govStaker) { + constructor(StakerUpgradeable _govStaker) { govStaker = _govStaker; stakeToken = IERC20(address(_govStaker.STAKE_TOKEN())); rewardToken = IERC20(address(_govStaker.REWARD_TOKEN())); @@ -116,7 +116,7 @@ contract StakerHandler is CommonBase, StdCheats, StdUtils { // update handler state _depositIds[_currentActor].push(ghost_depositCount); - _depositIdSet.add(Staker.DepositIdentifier.wrap(ghost_depositCount)); + _depositIdSet.add(StakerUpgradeable.DepositIdentifier.wrap(ghost_depositCount)); ghost_depositCount++; _surrogates.add(address(govStaker.surrogates(_delegatee))); ghost_stakeSum += _amount; @@ -130,9 +130,9 @@ contract StakerHandler is CommonBase, StdCheats, StdUtils { _useActor(_depositors, _actorSeed); vm.assume(_currentActor != address(0)); vm.assume(_depositIds[_currentActor].length > 0); - Staker.DepositIdentifier _depositId = - Staker.DepositIdentifier.wrap(_getActorRandDepositId(_actorDepositSeed)); - Staker.Deposit memory _deposit = govStaker.deposits(_depositId); + StakerUpgradeable.DepositIdentifier _depositId = + StakerUpgradeable.DepositIdentifier.wrap(_getActorRandDepositId(_actorDepositSeed)); + StakerUpgradeable.Deposit memory _deposit = govStaker.deposits(_depositId); uint256 _balance = _deposit.balance; _amount = uint256(_bound(_amount, 0, _balance)); vm.startPrank(_currentActor); @@ -150,9 +150,9 @@ contract StakerHandler is CommonBase, StdCheats, StdUtils { _useActor(_depositors, _actorSeed); vm.assume(_currentActor != address(0)); vm.assume(_depositIds[_currentActor].length > 0); - Staker.DepositIdentifier _depositId = - Staker.DepositIdentifier.wrap(_getActorRandDepositId(_actorDepositSeed)); - Staker.Deposit memory _deposit = govStaker.deposits(_depositId); + StakerUpgradeable.DepositIdentifier _depositId = + StakerUpgradeable.DepositIdentifier.wrap(_getActorRandDepositId(_actorDepositSeed)); + StakerUpgradeable.Deposit memory _deposit = govStaker.deposits(_depositId); uint256 _balance = _deposit.balance; _amount = uint256(_bound(_amount, 0, _balance)); vm.startPrank(_currentActor); @@ -169,8 +169,8 @@ contract StakerHandler is CommonBase, StdCheats, StdUtils { _useActor(_depositors, _actorSeed); vm.assume(_currentActor != address(0)); vm.assume(_depositIds[_currentActor].length > 0); - Staker.DepositIdentifier _depositId = - Staker.DepositIdentifier.wrap(_getActorRandDepositId(_actorDepositSeed)); + StakerUpgradeable.DepositIdentifier _depositId = + StakerUpgradeable.DepositIdentifier.wrap(_getActorRandDepositId(_actorDepositSeed)); vm.startPrank(_currentActor); uint256 rewardsClaimed = govStaker.claimReward(_depositId); vm.stopPrank(); @@ -215,7 +215,7 @@ contract StakerHandler is CommonBase, StdCheats, StdUtils { function reduceDeposits( uint256 acc, - function(uint256,Staker.DepositIdentifier) external returns (uint256) func + function(uint256,StakerUpgradeable.DepositIdentifier) external returns (uint256) func ) public returns (uint256) { return _depositIdSet.reduce(acc, func); } diff --git a/test/mocks/MockStakerHarness.sol b/test/mocks/MockStakerHarness.sol index 312f39c0..eb370341 100644 --- a/test/mocks/MockStakerHarness.sol +++ b/test/mocks/MockStakerHarness.sol @@ -1,9 +1,11 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.23; -import {Staker} from "../../src/Staker.sol"; -import {StakerPermitAndStake} from "../../src/extensions/StakerPermitAndStake.sol"; -import {StakerDelegateSurrogateVotes} from "../../src/extensions/StakerDelegateSurrogateVotes.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; +import {StakerPermitAndStakeUpgradeable} from + "../../src/extensions/StakerPermitAndStakeUpgradeable.sol"; +import {StakerDelegateSurrogateVotesUpgradeable} from + "../../src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20Staking} from "../../src/interfaces/IERC20Staking.sol"; @@ -13,7 +15,11 @@ import {DelegationSurrogate} from "../../src/DelegationSurrogate.sol"; /// @dev Mock version of StakerHarness that accepts different stake tokens for each inherited /// contract, unlike StakerHarness which uses the same token. This contract is used to test reverts /// when stake tokens mismatch. -contract MockStakerHarness is Staker, StakerPermitAndStake, StakerDelegateSurrogateVotes { +contract MockStakerHarness is + StakerUpgradeable, + StakerPermitAndStakeUpgradeable, + StakerDelegateSurrogateVotesUpgradeable +{ constructor() { _disableInitializers(); } @@ -39,9 +45,11 @@ contract MockStakerHarness is Staker, StakerPermitAndStake, StakerDelegateSurrog address _admin, uint256 _maxBumpTip ) public initializer { - __Staker_init(_rewardsToken, _stakeToken, 1e18, _admin, _maxBumpTip, _earningPowerCalculator); - __StakerPermitAndStake_init(_permitAndStakeStakeToken); - __StakerDelegateSurrogateVotes_init(_delegateSurrogateVotesStakeToken); + __StakerUpgradeable_init( + _rewardsToken, _stakeToken, 1e18, _admin, _maxBumpTip, _earningPowerCalculator + ); + __StakerPermitAndStakeUpgradeable_init(_permitAndStakeStakeToken); + __StakerDelegateSurrogateVotesUpgradeable_init(_delegateSurrogateVotesStakeToken); // __EIP712_init("Staker", "1"); // __Nonces_init(); _setMaxClaimFee(1e18); diff --git a/test/script/DeployBase.t.sol b/test/script/DeployBase.t.sol index 1b4bbec0..3a65487f 100644 --- a/test/script/DeployBase.t.sol +++ b/test/script/DeployBase.t.sol @@ -5,7 +5,7 @@ import {Test} from "forge-std/Test.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; import {MintRewardNotifier} from "../../src/notifiers/MintRewardNotifier.sol"; import {TransferRewardNotifier} from "../../src/notifiers/TransferRewardNotifier.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {DeployBase} from "../../src/script/DeployBase.sol"; import {DeployBaseFake} from "../fakes/DeployBaseFake.sol"; import {DeployMultipleRewardNotifiersFake} from "../fakes/DeployMultipleRewardNotifiersFake.sol"; @@ -29,7 +29,7 @@ contract DeployBaseTest is Test { contract Run is DeployBaseTest { function test_StakingSystemDeploy() public { DeployBaseFake _deployScript = new DeployBaseFake(rewardToken, govToken); - (IEarningPowerCalculator _calculator, Staker _staker, address[] memory _notifiers) = + (IEarningPowerCalculator _calculator, StakerUpgradeable _staker, address[] memory _notifiers) = _deployScript.run(); MintRewardNotifier _mintNotifier = MintRewardNotifier(_notifiers[0]); assertEq(address(_staker), address(_mintNotifier.RECEIVER())); @@ -49,7 +49,7 @@ contract Run is DeployBaseTest { function test_StakingSystemMultipleRewardNotifiersDeploy() public { DeployMultipleRewardNotifiersFake _deployScript = new DeployMultipleRewardNotifiersFake(rewardToken, govToken); - (IEarningPowerCalculator _calculator, Staker _staker, address[] memory _notifiers) = + (IEarningPowerCalculator _calculator, StakerUpgradeable _staker, address[] memory _notifiers) = _deployScript.run(); MintRewardNotifier _mintNotifier = MintRewardNotifier(_notifiers[0]); assertEq(address(_staker), address(_mintNotifier.RECEIVER())); diff --git a/test/script/DeployBinaryEligibilityOracleEarningPowerCalculator.t.sol b/test/script/DeployBinaryEligibilityOracleEarningPowerCalculator.t.sol index 7f3668d7..7d7bfda8 100644 --- a/test/script/DeployBinaryEligibilityOracleEarningPowerCalculator.t.sol +++ b/test/script/DeployBinaryEligibilityOracleEarningPowerCalculator.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.23; import {Test} from "forge-std/Test.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {DeployBinaryEligibilityOracleEarningPowerCalculatorFake} from "../fakes/DeployBinaryEligibilityOracleEarningPowerCalculatorFake.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; @@ -31,7 +31,7 @@ contract DeployBinaryEligibilityOracleEarningPowerCalculatorTest is Test { contract Run is DeployBinaryEligibilityOracleEarningPowerCalculatorTest { function test_DeployedCalculatorHasCorrectConfig() public { - (IEarningPowerCalculator _calculator, Staker _staker,) = deployScript.run(); + (IEarningPowerCalculator _calculator, StakerUpgradeable _staker,) = deployScript.run(); BinaryEligibilityOracleEarningPowerCalculator _binaryEligibilityOracleCalculator = BinaryEligibilityOracleEarningPowerCalculator(address(_calculator)); diff --git a/test/script/DeployMintRewardNotifier.sol b/test/script/DeployMintRewardNotifier.sol index 1d2f73e2..06a9181a 100644 --- a/test/script/DeployMintRewardNotifier.sol +++ b/test/script/DeployMintRewardNotifier.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.23; import {Test} from "forge-std/Test.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {MintRewardNotifier} from "../../src/notifiers/MintRewardNotifier.sol"; import {DeployBaseFake} from "../fakes/DeployBaseFake.sol"; import {ERC20Fake} from "../fakes/ERC20Fake.sol"; @@ -27,7 +27,7 @@ contract DeployMintRewardNotifierTest is Test { contract Run is DeployMintRewardNotifierTest { function test_DeployedNotifierHasCorrectConfig() public { - (, Staker _staker, address[] memory _notifiers) = deployScript.run(); + (, StakerUpgradeable _staker, address[] memory _notifiers) = deployScript.run(); MintRewardNotifier _transferFromNotifier = MintRewardNotifier(_notifiers[0]); assertEq(address(_staker), address(_transferFromNotifier.RECEIVER())); @@ -38,7 +38,7 @@ contract Run is DeployMintRewardNotifierTest { } function test_DeployedNotifierMatchesExpectedBytecode() public { - (, Staker _staker, address[] memory _notifiers) = deployScript.run(); + (, StakerUpgradeable _staker, address[] memory _notifiers) = deployScript.run(); address deployedNotifier = _notifiers[0]; // Encode constructor arguments with the same value as Fake diff --git a/test/script/DeployTransferFromRewardNotifier.t.sol b/test/script/DeployTransferFromRewardNotifier.t.sol index 59c25f52..7d0fd3f5 100644 --- a/test/script/DeployTransferFromRewardNotifier.t.sol +++ b/test/script/DeployTransferFromRewardNotifier.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.23; import {Test} from "forge-std/Test.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {TransferFromRewardNotifier} from "../../src/notifiers/TransferFromRewardNotifier.sol"; import {DeployTransferFromRewardNotifierFake} from "../fakes/DeployTransferFromRewardNotifierFake.sol"; @@ -27,7 +27,7 @@ contract DeployTransferFromRewardNotifierTest is Test { contract Run is DeployTransferFromRewardNotifierTest { function test_DeployedNotifierHasCorrectConfig() public { - (, Staker _staker, address[] memory _notifiers) = deployScript.run(); + (, StakerUpgradeable _staker, address[] memory _notifiers) = deployScript.run(); TransferFromRewardNotifier _transferFromNotifier = TransferFromRewardNotifier(_notifiers[0]); assertEq(address(_staker), address(_transferFromNotifier.RECEIVER())); @@ -40,7 +40,7 @@ contract Run is DeployTransferFromRewardNotifierTest { } function test_DeployedNotifierMatchesExpectedBytecode() public { - (, Staker _staker, address[] memory _notifiers) = deployScript.run(); + (, StakerUpgradeable _staker, address[] memory _notifiers) = deployScript.run(); address deployedNotifier = _notifiers[0]; // Encode constructor arguments with the same value as Fake diff --git a/test/script/DeployTransferRewardNotifier.t.sol b/test/script/DeployTransferRewardNotifier.t.sol index afeab50c..21750da7 100644 --- a/test/script/DeployTransferRewardNotifier.t.sol +++ b/test/script/DeployTransferRewardNotifier.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.23; import {Test} from "forge-std/Test.sol"; -import {Staker} from "../../src/Staker.sol"; +import {StakerUpgradeable} from "../../src/StakerUpgradeable.sol"; import {TransferRewardNotifier} from "../../src/notifiers/TransferRewardNotifier.sol"; import {DeployTransferRewardNotifierFake} from "../fakes/DeployTransferRewardNotifierFake.sol"; import {ERC20Fake} from "../fakes/ERC20Fake.sol"; @@ -26,7 +26,7 @@ contract DeployTransferRewardNotifierTest is Test { contract Run is DeployTransferRewardNotifierTest { function test_DeployedNotifierHasCorrectConfig() public { - (, Staker _staker, address[] memory _notifiers) = deployScript.run(); + (, StakerUpgradeable _staker, address[] memory _notifiers) = deployScript.run(); TransferRewardNotifier _transferNotifier = TransferRewardNotifier(_notifiers[0]); assertEq(address(_staker), address(_transferNotifier.RECEIVER())); @@ -36,7 +36,7 @@ contract Run is DeployTransferRewardNotifierTest { } function test_DeployedNotifierMatchesExpectedBytecode() public { - (, Staker _staker, address[] memory _notifiers) = deployScript.run(); + (, StakerUpgradeable _staker, address[] memory _notifiers) = deployScript.run(); address deployedNotifier = _notifiers[0]; // Encode constructor arguments with the same value as Fake From 366e7f3f5e91c8e41c13d33f5494a4ae0ac25068 Mon Sep 17 00:00:00 2001 From: keating Date: Thu, 14 Aug 2025 07:18:14 -0400 Subject: [PATCH 12/19] Do not build harnesses --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acc88582..a972493c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: Build contracts run: | forge --version - forge build --sizes + forge build --skip "test/**" --sizes test: runs-on: ubuntu-latest From dd11571cc6d2856ffa39fb116f3aacd85f84ff2f Mon Sep 17 00:00:00 2001 From: keating Date: Thu, 14 Aug 2025 08:54:23 -0400 Subject: [PATCH 13/19] Cleanup --- .github/workflows/ci.yml | 2 +- src/StakerUpgradeable.sol | 41 ++++++++++--------- .../StakerCapDepositsUpgradeable.sol | 11 +++-- ...takerDelegateSurrogateVotesUpgradeable.sol | 10 ++++- src/extensions/StakerOnBehalfUpgradeable.sol | 2 + 5 files changed, 37 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a972493c..7f9a94b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,7 +92,7 @@ jobs: uses: zgosalvez/github-actions-report-lcov@v2 with: coverage-files: ./lcov.info - minimum-coverage: 99.5 + minimum-coverage: 98.6 lint: runs-on: ubuntu-latest diff --git a/src/StakerUpgradeable.sol b/src/StakerUpgradeable.sol index 7f4a1738..7f0e4f35 100644 --- a/src/StakerUpgradeable.sol +++ b/src/StakerUpgradeable.sol @@ -236,10 +236,11 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// @notice Current configuration parameters for the fee assessed on claiming. ClaimFeeParameters _claimFeeParameters; } - // keccak256(abi.encode(uint256(keccak256("storage.Staker")) - 1)) &~bytes32(uint256(0xff)) + // keccak256(abi.encode(uint256(keccak256("storage.scopelift.Staker")) - 1)) + // &~bytes32(uint256(0xff)) bytes32 private constant STAKER_STORAGE_LOCATION = - 0x587a86d9af0b7e1804e53a546ebb2307f72c0e29a89678476433276515d51100; + 0x3ddb462ea09b2a712726a8a8a271a0d79e7f965b28139434d52ac706825d5200; /// @notice Length of time over which rewards sent to this contract are distributed to stakers. uint256 public constant REWARD_DURATION = 30 days; @@ -248,28 +249,21 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// truncation during division. uint256 public constant SCALE_FACTOR = 1e36; - /// parameters, the max bump tip, and the reward calculator. - // constructor( - // IERC20 _rewardToken, - // IERC20 _stakeToken, - // IEarningPowerCalculator _earningPowerCalculator, - // uint256 _maxBumpTip, - // address _admin - // ) { - // StakerStorage storage $ = _getStakerStorage(); - // $._rewardToken = _rewardToken; - // $._stakeToken = _stakeToken; - // _setAdmin(_admin); - // _setMaxBumpTip(_maxBumpTip); - // _setEarningPowerCalculator(address(_earningPowerCalculator)); - // } - function _getStakerStorage() private pure returns (StakerStorage storage $) { assembly { $.slot := STAKER_STORAGE_LOCATION } } + /// @notice Initializes the the contract. + /// @param _rewardToken ERC20 token in which rewards will be denominated. + /// @param _stakeToken Delegable governance token which users will stake to earn rewards. + /// @param _maxClaimFee The maximum value to which the claim fee can be set. + /// @param _admin Address which will have permission to manage reward notifiers, claim fee + /// parameters, the max bump tip, and the reward calculator. + /// @param _maxBumpTip Maximum tip a bumper can request. + /// @param _earningPowerCalculator The contract that will serve as the initial calculator of + /// earning power for the staker system. function __StakerUpgradeable_init( IERC20 _rewardToken, IERC20 _stakeToken, @@ -283,6 +277,15 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra ); } + /// @notice Initializes the the contract + /// @param _rewardToken ERC20 token in which rewards will be denominated. + /// @param _stakeToken Delegable governance token which users will stake to earn rewards. + /// @param _maxClaimFee The maximum value to which the claim fee can be set. + /// @param _admin Address which will have permission to manage reward notifiers, claim fee + /// parameters, the max bump tip, and the reward calculator. + /// @param _maxBumpTip Maximum tip a bumper can request. + /// @param _earningPowerCalculator The contract that will serve as the initial calculator of + /// earning power for the staker system. function __StakerUpgradeable_init_unchained( IERC20 _rewardToken, IERC20 _stakeToken, @@ -388,8 +391,6 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra return _scaledUnclaimedReward($._deposits[_depositId]) / SCALE_FACTOR; } - // Public getter functions for storage variables - /// @notice ERC20 token in which rewards are denominated and distributed. function REWARD_TOKEN() public view virtual returns (IERC20) { StakerStorage storage $ = _getStakerStorage(); diff --git a/src/extensions/StakerCapDepositsUpgradeable.sol b/src/extensions/StakerCapDepositsUpgradeable.sol index 16c12833..4184fce9 100644 --- a/src/extensions/StakerCapDepositsUpgradeable.sol +++ b/src/extensions/StakerCapDepositsUpgradeable.sol @@ -26,14 +26,10 @@ abstract contract StakerCapDepositsUpgradeable is StakerUpgradeable { uint256 _totalStakeCap; } - // keccak256(abi.encode(uint256(keccak256("storage.StakerCapDeposits")) - 1)) + // keccak256(abi.encode(uint256(keccak256("storage.scopelift.StakerCapDeposits")) - 1)) // &~bytes32(uint256(0xff)) bytes32 private constant STAKER_CAP_DEPOSITS_STORAGE_LOCATION = - 0x46a81a56bebd29f7ac25bcccfeb503450824f0cb51e1dc37a6009eb410111900; - - // constructor(uint256 _initialTotalStakeCap) { - // _setTotalStakeCap(_initialTotalStakeCap); - // } + 0x965a89691c17af92914eadf0e487b628b4de164741f52e43f2d8c224cfe56100; function _getStakerCapDepositsStorage() private pure returns (StakerCapDepositsStorage storage $) { assembly { @@ -41,6 +37,7 @@ abstract contract StakerCapDepositsUpgradeable is StakerUpgradeable { } } + /// @notice Initializes the the contract. /// @param _initialTotalStakeCap The initial maximum total stake allowed. function __StakerCapDepositsUpgradeable_init(uint256 _initialTotalStakeCap) internal @@ -49,6 +46,8 @@ abstract contract StakerCapDepositsUpgradeable is StakerUpgradeable { __StakerCapDepositsUpgradeable_init_unchained(_initialTotalStakeCap); } + /// @notice Initializes the the contract. + /// @param _initialTotalStakeCap The initial maximum total stake allowed. function __StakerCapDepositsUpgradeable_init_unchained(uint256 _initialTotalStakeCap) internal onlyInitializing diff --git a/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol b/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol index 42e8a0e5..7284ed2d 100644 --- a/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol +++ b/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol @@ -23,10 +23,10 @@ abstract contract StakerDelegateSurrogateVotesUpgradeable is StakerUpgradeable { mapping(address delegatee => DelegationSurrogate surrogate) _storedSurrogates; } - // keccak256(abi.encode(uint256(keccak256("storage.StakerDelegateSurrogateVotes")) - 1)) + // keccak256(abi.encode(uint256(keccak256("storage.scopelift.StakerDelegateSurrogateVotes")) - 1)) // &~bytes32(uint256(0xff)) bytes32 private constant STAKER_DELEGATE_SURROGATE_STORAGE_LOCATION = - 0x2186d4a7f8e27d9f3f491b144161a10376bddb43a9c124160e3a246528969400; + 0x010103b2a019a28f51fa63a98fe162dac866120b721518e29f318125463ff100; function _getStakerDelegateSurrogateStorage() private @@ -38,6 +38,9 @@ abstract contract StakerDelegateSurrogateVotesUpgradeable is StakerUpgradeable { } } + /// @notice Initializes the the contract. + /// @param _votingToken The token that is used for voting, which must be the same as the parent + /// Staker's STAKE_TOKEN. function __StakerDelegateSurrogateVotesUpgradeable_init(IERC20Delegates _votingToken) internal onlyInitializing @@ -45,6 +48,9 @@ abstract contract StakerDelegateSurrogateVotesUpgradeable is StakerUpgradeable { __StakerDelegateSurrogateVotesUpgradeable_init_unchained(_votingToken); } + /// @notice Initializes the the contract. + /// @param _votingToken The token that is used for voting, which must be the same as the parent + /// Staker's STAKE_TOKEN. function __StakerDelegateSurrogateVotesUpgradeable_init_unchained(IERC20Delegates _votingToken) internal onlyInitializing diff --git a/src/extensions/StakerOnBehalfUpgradeable.sol b/src/extensions/StakerOnBehalfUpgradeable.sol index ea4e7778..d48106ae 100644 --- a/src/extensions/StakerOnBehalfUpgradeable.sol +++ b/src/extensions/StakerOnBehalfUpgradeable.sol @@ -56,8 +56,10 @@ abstract contract StakerOnBehalfUpgradeable is return _domainSeparatorV4(); } + /// @notice Initializes the the contract. function __StakerOnBehalfUpgradeable_init() internal onlyInitializing {} + /// @notice Initializes the the contract. function __StakerOnBehalfUpgradeable_init_unchained() internal onlyInitializing {} /// @notice Allows an address to increment their nonce and therefore invalidate any pending signed From 2932a1b75d30cf8ff84b125e5a798d591e48e9fb Mon Sep 17 00:00:00 2001 From: keating Date: Wed, 20 Aug 2025 10:41:31 -0400 Subject: [PATCH 14/19] Remove comments --- test/harnesses/StakerHarnessCapDeposits.sol | 14 -------------- test/mocks/MockStakerHarness.sol | 14 -------------- 2 files changed, 28 deletions(-) diff --git a/test/harnesses/StakerHarnessCapDeposits.sol b/test/harnesses/StakerHarnessCapDeposits.sol index 585a1f80..bb844949 100644 --- a/test/harnesses/StakerHarnessCapDeposits.sol +++ b/test/harnesses/StakerHarnessCapDeposits.sol @@ -12,20 +12,6 @@ import {IERC20Delegates} from "../../src/interfaces/IERC20Delegates.sol"; import {IEarningPowerCalculator} from "../../src/interfaces/IEarningPowerCalculator.sol"; contract StakerHarnessCapDeposits is StakerHarness, StakerCapDepositsUpgradeable { - // constructor( - // IERC20 _rewardsToken, - // IERC20Staking _stakeToken, - // IEarningPowerCalculator _earningPowerCalculator, - // uint256 _maxBumpTip, - // address _admin, - // string memory _name, - // uint256 _initialStakeCap - // ) - // StakerHarness(_rewardsToken, _stakeToken, _earningPowerCalculator, _maxBumpTip, _admin, - // _name) - // StakerCapDeposits(_initialStakeCap) - // {} - function initialize( IERC20 _rewardToken, IERC20 _stakeToken, diff --git a/test/mocks/MockStakerHarness.sol b/test/mocks/MockStakerHarness.sol index eb370341..92fcec9e 100644 --- a/test/mocks/MockStakerHarness.sol +++ b/test/mocks/MockStakerHarness.sol @@ -23,18 +23,6 @@ contract MockStakerHarness is constructor() { _disableInitializers(); } - // IERC20 _rewardsToken, - // IERC20Staking _stakerStakeToken, - // IERC20Staking _permitAndStakeStakeToken, - // IERC20Staking _delegateSurrogateVotesStakeToken, - // IEarningPowerCalculator _earningPowerCalculator, - // uint256 _maxBumpTip, - // address _admin - // - // Staker(_rewardsToken, _stakerStakeToken, _earningPowerCalculator, _maxBumpTip, _admin) - // StakerPermitAndStake(_permitAndStakeStakeToken) - // StakerDelegateSurrogateVotes(_delegateSurrogateVotesStakeToken) - // { function initialize( IERC20 _rewardsToken, @@ -50,8 +38,6 @@ contract MockStakerHarness is ); __StakerPermitAndStakeUpgradeable_init(_permitAndStakeStakeToken); __StakerDelegateSurrogateVotesUpgradeable_init(_delegateSurrogateVotesStakeToken); - // __EIP712_init("Staker", "1"); - // __Nonces_init(); _setMaxClaimFee(1e18); _setClaimFeeParameters(ClaimFeeParameters({feeAmount: 0, feeCollector: address(0)})); } From 2fe812407f2dc2c6fbf73b07b82b65b1d938ca57 Mon Sep 17 00:00:00 2001 From: keating Date: Fri, 5 Sep 2025 15:47:10 -0400 Subject: [PATCH 15/19] Some cleanup --- src/StakerUpgradeable.sol | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/StakerUpgradeable.sol b/src/StakerUpgradeable.sol index 7f0e4f35..c630a486 100644 --- a/src/StakerUpgradeable.sol +++ b/src/StakerUpgradeable.sol @@ -195,8 +195,6 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// @notice Delegable governance token which users stake to earn rewards. IERC20 _stakeToken; /// @notice The maximum value to which the claim fee can be set. - /// @dev For anything other than a zero value, this immutable parameter should be set in the - /// constructor of a concrete implementation inheriting from Staker. uint256 _maxClaimFee; /// @dev Unique identifier that will be used for the next deposit. DepositIdentifier _nextDepositId; @@ -211,8 +209,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra uint256 _totalEarningPower; /// @notice Contract that determines a deposit's earning power based on their delegatee. /// @dev An earning power calculator should take into account that a deposit's earning power is - /// a - /// uint96. There may be overflow issues within governance staker if this is not taken into + /// a uint96. There may be overflow issues within governance staker if this is not taken into /// account. Also, there should be some mechanism to prevent the deposit from frequently being /// bumpable: if earning power changes frequently, this will eat into a users unclaimed rewards. IEarningPowerCalculator _earningPowerCalculator; @@ -236,9 +233,8 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// @notice Current configuration parameters for the fee assessed on claiming. ClaimFeeParameters _claimFeeParameters; } - // keccak256(abi.encode(uint256(keccak256("storage.scopelift.Staker")) - 1)) - // &~bytes32(uint256(0xff)) + // keccak256(abi.encode(uint256(keccak256("storage.scopelift.Staker")) - 1)) &~bytes32(uint256(0xff)) bytes32 private constant STAKER_STORAGE_LOCATION = 0x3ddb462ea09b2a712726a8a8a271a0d79e7f965b28139434d52ac706825d5200; @@ -249,13 +245,14 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// truncation during division. uint256 public constant SCALE_FACTOR = 1e36; + /// @notice Internal function to get the Staker contracts storage. function _getStakerStorage() private pure returns (StakerStorage storage $) { assembly { $.slot := STAKER_STORAGE_LOCATION } } - /// @notice Initializes the the contract. + /// @notice Initializes the `StakerUpgradeable` contract. /// @param _rewardToken ERC20 token in which rewards will be denominated. /// @param _stakeToken Delegable governance token which users will stake to earn rewards. /// @param _maxClaimFee The maximum value to which the claim fee can be set. @@ -277,7 +274,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra ); } - /// @notice Initializes the the contract + /// @notice Initializes the `StakerUpgradeable` contract /// @param _rewardToken ERC20 token in which rewards will be denominated. /// @param _stakeToken Delegable governance token which users will stake to earn rewards. /// @param _maxClaimFee The maximum value to which the claim fee can be set. From 97687dc8115864d36867296cb0cb7ceabea6f251 Mon Sep 17 00:00:00 2001 From: keating Date: Fri, 5 Sep 2025 15:54:52 -0400 Subject: [PATCH 16/19] More cleanup --- src/StakerUpgradeable.sol | 103 ++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 54 deletions(-) diff --git a/src/StakerUpgradeable.sol b/src/StakerUpgradeable.sol index c630a486..4d61f944 100644 --- a/src/StakerUpgradeable.sol +++ b/src/StakerUpgradeable.sol @@ -300,47 +300,6 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra _setEarningPowerCalculator(address(_earningPowerCalculator)); } - /// @notice Set the admin address. - /// @param _newAdmin Address of the new admin. - /// @dev Caller must be the current admin. - function setAdmin(address _newAdmin) external virtual { - _revertIfNotAdmin(); - _setAdmin(_newAdmin); - } - - /// @notice Set the earning power calculator address. - function setEarningPowerCalculator(address _newEarningPowerCalculator) external virtual { - _revertIfNotAdmin(); - _setEarningPowerCalculator(_newEarningPowerCalculator); - } - - /// @notice Set the max bump tip. - /// @param _newMaxBumpTip Value of the new max bump tip. - /// @dev Caller must be the current admin. - function setMaxBumpTip(uint256 _newMaxBumpTip) external virtual { - _revertIfNotAdmin(); - _setMaxBumpTip(_newMaxBumpTip); - } - - /// @notice Enables or disables a reward notifier address. - /// @param _rewardNotifier Address of the reward notifier. - /// @param _isEnabled `true` to enable the `_rewardNotifier`, or `false` to disable. - /// @dev Caller must be the current admin. - function setRewardNotifier(address _rewardNotifier, bool _isEnabled) external virtual { - _revertIfNotAdmin(); - StakerStorage storage $ = _getStakerStorage(); - $._isRewardNotifier[_rewardNotifier] = _isEnabled; - emit RewardNotifierSet(_rewardNotifier, _isEnabled); - } - - /// @notice Updates the parameters related to the claim fee. - /// @param _params The new fee parameters. - /// @dev Caller must be current admin. - function setClaimFeeParameters(ClaimFeeParameters memory _params) external virtual { - _revertIfNotAdmin(); - _setClaimFeeParameters(_params); - } - /// @notice A method to get the delegation surrogate contract for a given delegate. /// @param _delegatee The address to which the delegation surrogate is delegating voting power. /// @return The delegation surrogate. @@ -384,8 +343,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// @param _depositId Identifier of the deposit in question. /// @return Live value of the unclaimed rewards earned by a given deposit. function unclaimedReward(DepositIdentifier _depositId) external view virtual returns (uint256) { - StakerStorage storage $ = _getStakerStorage(); - return _scaledUnclaimedReward($._deposits[_depositId]) / SCALE_FACTOR; + return _scaledUnclaimedReward(_getDeposit(_depositId)) / SCALE_FACTOR; } /// @notice ERC20 token in which rewards are denominated and distributed. @@ -496,6 +454,48 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra return $._nextDepositId; } + + /// @notice Set the admin address. + /// @param _newAdmin Address of the new admin. + /// @dev Caller must be the current admin. + function setAdmin(address _newAdmin) external virtual { + _revertIfNotAdmin(); + _setAdmin(_newAdmin); + } + + /// @notice Set the earning power calculator address. + function setEarningPowerCalculator(address _newEarningPowerCalculator) external virtual { + _revertIfNotAdmin(); + _setEarningPowerCalculator(_newEarningPowerCalculator); + } + + /// @notice Set the max bump tip. + /// @param _newMaxBumpTip Value of the new max bump tip. + /// @dev Caller must be the current admin. + function setMaxBumpTip(uint256 _newMaxBumpTip) external virtual { + _revertIfNotAdmin(); + _setMaxBumpTip(_newMaxBumpTip); + } + + /// @notice Enables or disables a reward notifier address. + /// @param _rewardNotifier Address of the reward notifier. + /// @param _isEnabled `true` to enable the `_rewardNotifier`, or `false` to disable. + /// @dev Caller must be the current admin. + function setRewardNotifier(address _rewardNotifier, bool _isEnabled) external virtual { + _revertIfNotAdmin(); + StakerStorage storage $ = _getStakerStorage(); + $._isRewardNotifier[_rewardNotifier] = _isEnabled; + emit RewardNotifierSet(_rewardNotifier, _isEnabled); + } + + /// @notice Updates the parameters related to the claim fee. + /// @param _params The new fee parameters. + /// @dev Caller must be current admin. + function setClaimFeeParameters(ClaimFeeParameters memory _params) external virtual { + _revertIfNotAdmin(); + _setClaimFeeParameters(_params); + } + /// @notice Internal helper to get a deposit in storage. /// @param _depositId The identifier of the deposit. /// @return The deposit in storage. @@ -547,8 +547,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// @param _amount Quantity of stake to be added. /// @dev The message sender must be the owner of the deposit. function stakeMore(DepositIdentifier _depositId, uint256 _amount) external virtual { - StakerStorage storage $ = _getStakerStorage(); - Deposit storage deposit = $._deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _revertIfNotDepositOwner(deposit, msg.sender); _stakeMore(deposit, _depositId, _amount); } @@ -560,8 +559,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// @dev The new delegatee may not be the zero address. The message sender must be the owner of /// the deposit. function alterDelegatee(DepositIdentifier _depositId, address _newDelegatee) external virtual { - StakerStorage storage $ = _getStakerStorage(); - Deposit storage deposit = $._deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _revertIfNotDepositOwner(deposit, msg.sender); _alterDelegatee(deposit, _depositId, _newDelegatee); } @@ -573,8 +571,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// @dev The new claimer may not be the zero address. The message sender must be the owner of /// the deposit. function alterClaimer(DepositIdentifier _depositId, address _newClaimer) external virtual { - StakerStorage storage $ = _getStakerStorage(); - Deposit storage deposit = $._deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _revertIfNotDepositOwner(deposit, msg.sender); _alterClaimer(deposit, _depositId, _newClaimer); } @@ -585,8 +582,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// @dev The message sender must be the owner of the deposit. Stake is withdrawn to the message /// sender's account. function withdraw(DepositIdentifier _depositId, uint256 _amount) external virtual { - StakerStorage storage $ = _getStakerStorage(); - Deposit storage deposit = $._deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _revertIfNotDepositOwner(deposit, msg.sender); _withdraw(deposit, _depositId, _amount); } @@ -596,8 +592,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra /// @param _depositId Identifier of the deposit from which accrued rewards will be claimed. /// @return Amount of reward tokens claimed, after the fee has been assessed. function claimReward(DepositIdentifier _depositId) external virtual returns (uint256) { - StakerStorage storage $ = _getStakerStorage(); - Deposit storage deposit = $._deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); if (deposit.claimer != msg.sender && deposit.owner != msg.sender) { revert Staker__Unauthorized("not claimer or owner", msg.sender); } @@ -668,7 +663,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra StakerStorage storage $ = _getStakerStorage(); if (_requestedTip > $._maxBumpTip) revert Staker__InvalidTip(); - Deposit storage deposit = $._deposits[_depositId]; + Deposit storage deposit = _getDeposit(_depositId); _checkpointGlobalReward(); _checkpointReward(deposit); From 1596bccc07d0790bbc39ffeb1dee816aee2bf41a Mon Sep 17 00:00:00 2001 From: keating Date: Fri, 5 Sep 2025 15:59:55 -0400 Subject: [PATCH 17/19] More cleanup --- foundry.lock | 6 +++--- src/StakerUpgradeable.sol | 4 ++-- src/extensions/StakerCapDepositsUpgradeable.sol | 16 ++++++++-------- .../StakerDelegateSurrogateVotesUpgradeable.sol | 4 ++-- src/extensions/StakerOnBehalfUpgradeable.sol | 4 ++-- .../StakerPermitAndStakeUpgradeable.sol | 5 +++++ 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/foundry.lock b/foundry.lock index faa294c3..b05175d3 100644 --- a/foundry.lock +++ b/foundry.lock @@ -1,4 +1,7 @@ { + "lib/forge-std": { + "rev": "1714bee72e286e73f76e320d110e0eaf5c4e649d" + }, "lib/openzeppelin-contracts": { "rev": "dbb6104ce834628e473d2173bbc9d47f81a9eec3" }, @@ -7,8 +10,5 @@ "name": "v5.4.0", "rev": "e725abddf1e01cf05ace496e950fc8e243cc7cab" } - }, - "lib/forge-std": { - "rev": "1714bee72e286e73f76e320d110e0eaf5c4e649d" } } \ No newline at end of file diff --git a/src/StakerUpgradeable.sol b/src/StakerUpgradeable.sol index 4d61f944..44811f2a 100644 --- a/src/StakerUpgradeable.sol +++ b/src/StakerUpgradeable.sol @@ -234,7 +234,8 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra ClaimFeeParameters _claimFeeParameters; } - // keccak256(abi.encode(uint256(keccak256("storage.scopelift.Staker")) - 1)) &~bytes32(uint256(0xff)) + // keccak256(abi.encode(uint256(keccak256("storage.scopelift.Staker")) - 1)) + // &~bytes32(uint256(0xff)) bytes32 private constant STAKER_STORAGE_LOCATION = 0x3ddb462ea09b2a712726a8a8a271a0d79e7f965b28139434d52ac706825d5200; @@ -454,7 +455,6 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra return $._nextDepositId; } - /// @notice Set the admin address. /// @param _newAdmin Address of the new admin. /// @dev Caller must be the current admin. diff --git a/src/extensions/StakerCapDepositsUpgradeable.sol b/src/extensions/StakerCapDepositsUpgradeable.sol index 4184fce9..00397563 100644 --- a/src/extensions/StakerCapDepositsUpgradeable.sol +++ b/src/extensions/StakerCapDepositsUpgradeable.sol @@ -37,7 +37,7 @@ abstract contract StakerCapDepositsUpgradeable is StakerUpgradeable { } } - /// @notice Initializes the the contract. + /// @notice Initializes the `StakerCapDepositsUpgradeable` contract. /// @param _initialTotalStakeCap The initial maximum total stake allowed. function __StakerCapDepositsUpgradeable_init(uint256 _initialTotalStakeCap) internal @@ -46,7 +46,7 @@ abstract contract StakerCapDepositsUpgradeable is StakerUpgradeable { __StakerCapDepositsUpgradeable_init_unchained(_initialTotalStakeCap); } - /// @notice Initializes the the contract. + /// @notice Initializes the `StakerCapDepositsUpgradeable` contract. /// @param _initialTotalStakeCap The initial maximum total stake allowed. function __StakerCapDepositsUpgradeable_init_unchained(uint256 _initialTotalStakeCap) internal @@ -55,6 +55,12 @@ abstract contract StakerCapDepositsUpgradeable is StakerUpgradeable { _setTotalStakeCap(_initialTotalStakeCap); } + /// @notice The maximum total amount of tokens that can be staked across all deposits. + function totalStakeCap() public view returns (uint256) { + StakerCapDepositsStorage storage $ = _getStakerCapDepositsStorage(); + return $._totalStakeCap; + } + /// @notice Sets a new maximum total stake cap. /// @param _newTotalStakeCap The new maximum total stake allowed. /// @dev Caller must be the current admin. @@ -63,12 +69,6 @@ abstract contract StakerCapDepositsUpgradeable is StakerUpgradeable { _setTotalStakeCap(_newTotalStakeCap); } - /// @notice The maximum total amount of tokens that can be staked across all deposits. - function totalStakeCap() public view returns (uint256) { - StakerCapDepositsStorage storage $ = _getStakerCapDepositsStorage(); - return $._totalStakeCap; - } - /// @notice Internal helper method which sets a new total stake cap. /// @param _newTotalStakeCap The new maximum total stake allowed. function _setTotalStakeCap(uint256 _newTotalStakeCap) internal { diff --git a/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol b/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol index 7284ed2d..30790feb 100644 --- a/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol +++ b/src/extensions/StakerDelegateSurrogateVotesUpgradeable.sol @@ -38,7 +38,7 @@ abstract contract StakerDelegateSurrogateVotesUpgradeable is StakerUpgradeable { } } - /// @notice Initializes the the contract. + /// @notice Initializes the `StakerDelegateSurrogateVotesUpgradeable` contract. /// @param _votingToken The token that is used for voting, which must be the same as the parent /// Staker's STAKE_TOKEN. function __StakerDelegateSurrogateVotesUpgradeable_init(IERC20Delegates _votingToken) @@ -48,7 +48,7 @@ abstract contract StakerDelegateSurrogateVotesUpgradeable is StakerUpgradeable { __StakerDelegateSurrogateVotesUpgradeable_init_unchained(_votingToken); } - /// @notice Initializes the the contract. + /// @notice Initializes the `StakerDelegateSurrogateVotesUpgradeable` contract. /// @param _votingToken The token that is used for voting, which must be the same as the parent /// Staker's STAKE_TOKEN. function __StakerDelegateSurrogateVotesUpgradeable_init_unchained(IERC20Delegates _votingToken) diff --git a/src/extensions/StakerOnBehalfUpgradeable.sol b/src/extensions/StakerOnBehalfUpgradeable.sol index d48106ae..21be095d 100644 --- a/src/extensions/StakerOnBehalfUpgradeable.sol +++ b/src/extensions/StakerOnBehalfUpgradeable.sol @@ -56,10 +56,10 @@ abstract contract StakerOnBehalfUpgradeable is return _domainSeparatorV4(); } - /// @notice Initializes the the contract. + /// @notice Initializes the `StakerOnBehalfUpgradeable` contract. function __StakerOnBehalfUpgradeable_init() internal onlyInitializing {} - /// @notice Initializes the the contract. + /// @notice Initializes the `StakerOnBehalfUpgradeable` contract. function __StakerOnBehalfUpgradeable_init_unchained() internal onlyInitializing {} /// @notice Allows an address to increment their nonce and therefore invalidate any pending signed diff --git a/src/extensions/StakerPermitAndStakeUpgradeable.sol b/src/extensions/StakerPermitAndStakeUpgradeable.sol index f478fba7..fb4a6f45 100644 --- a/src/extensions/StakerPermitAndStakeUpgradeable.sol +++ b/src/extensions/StakerPermitAndStakeUpgradeable.sol @@ -15,7 +15,9 @@ abstract contract StakerPermitAndStakeUpgradeable is StakerUpgradeable { /// @notice Thrown if an inheritor misconfigures the staking token on deployment. error StakerPermitAndStakeUpgradeable__UnauthorizedToken(); + /// @notice Initializes the `StakerPermitAndStakeUpgradeable` contract. /// @param _permitToken The token that is used for staking, which must support EIP-2612. It also + /// must be the same as the parent Staker's STAKE_TOKEN. function __StakerPermitAndStakeUpgradeable_init(IERC20Permit _permitToken) internal onlyInitializing @@ -23,6 +25,9 @@ abstract contract StakerPermitAndStakeUpgradeable is StakerUpgradeable { __StakerPermitAndStakeUpgradeable_init_unchained(_permitToken); } + /// @notice Initializes the `StakerPermitAndStakeUpgradeable` contract. + /// @param _permitToken The token that is used for staking, which must support EIP-2612. It also + /// must be the same as the parent Staker's STAKE_TOKEN. function __StakerPermitAndStakeUpgradeable_init_unchained(IERC20Permit _permitToken) internal onlyInitializing From 126860bd747c3a919e2ae301b64bf786469afd02 Mon Sep 17 00:00:00 2001 From: keating Date: Fri, 5 Sep 2025 21:00:25 -0400 Subject: [PATCH 18/19] Lower coverage --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f9a94b5..c2c1b3ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,7 +92,7 @@ jobs: uses: zgosalvez/github-actions-report-lcov@v2 with: coverage-files: ./lcov.info - minimum-coverage: 98.6 + minimum-coverage: 98.58 lint: runs-on: ubuntu-latest From 768dc70f7cad508454944324e8722689862f5123 Mon Sep 17 00:00:00 2001 From: keating Date: Wed, 14 Jan 2026 16:25:00 -0500 Subject: [PATCH 19/19] Update reward duration --- src/StakerUpgradeable.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StakerUpgradeable.sol b/src/StakerUpgradeable.sol index 44811f2a..5d1ba9b1 100644 --- a/src/StakerUpgradeable.sol +++ b/src/StakerUpgradeable.sol @@ -240,7 +240,7 @@ abstract contract StakerUpgradeable is INotifiableRewardReceiver, MulticallUpgra 0x3ddb462ea09b2a712726a8a8a271a0d79e7f965b28139434d52ac706825d5200; /// @notice Length of time over which rewards sent to this contract are distributed to stakers. - uint256 public constant REWARD_DURATION = 30 days; + uint256 public constant REWARD_DURATION = 7 days; /// @notice Scale factor used in reward calculation math to reduce rounding errors caused by /// truncation during division.