Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce deployment script for RewardsStreamerMP #89

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 51 additions & 10 deletions .gas-report
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
| script/DeployRewardsStreamerMP.s.sol:DeployRewardsStreamerMPScript contract | | | | | |
|-----------------------------------------------------------------------------|-----------------|---------|---------|---------|---------|
| Deployment Cost | Deployment Size | | | | |
| 6200681 | 29704 | | | | |
| Function Name | min | avg | median | max | # calls |
| run | 5302574 | 5302574 | 5302574 | 5302574 | 57 |


| script/DeploymentConfig.s.sol:DeploymentConfig contract | | | | | |
|---------------------------------------------------------|-----------------|-----|--------|-----|---------|
| Deployment Cost | Deployment Size | | | | |
| 0 | 0 | | | | |
| Function Name | min | avg | median | max | # calls |
| activeNetworkConfig | 454 | 454 | 454 | 454 | 114 |


| src/RewardsStreamer.sol:RewardsStreamer contract | | | | | |
|--------------------------------------------------|-----------------|--------|--------|--------|---------|
| Deployment Cost | Deployment Size | | | | |
Expand All @@ -21,7 +37,7 @@
| MAX_MULTIPLIER | 251 | 251 | 251 | 251 | 11 |
| MIN_LOCKUP_PERIOD | 297 | 297 | 297 | 297 | 11 |
| MP_RATE_PER_YEAR | 253 | 253 | 253 | 253 | 3 |
| STAKING_TOKEN | 2428 | 2428 | 2428 | 2428 | 292 |
| STAKING_TOKEN | 428 | 2037 | 2428 | 2428 | 292 |
| emergencyModeEnabled | 2420 | 2420 | 2420 | 2420 | 7 |
| enableEmergencyMode | 2485 | 19392 | 24677 | 24677 | 8 |
| getAccount | 1661 | 1661 | 1661 | 1661 | 72 |
Expand All @@ -31,7 +47,6 @@
| getUserTotalStakedBalance | 15118 | 15118 | 15118 | 15118 | 1 |
| getUserVaults | 5201 | 5201 | 5201 | 5201 | 4 |
| initialize | 115611 | 115611 | 115611 | 115611 | 59 |
| isTrustedCodehash | 519 | 519 | 519 | 519 | 231 |
| lastRewardTime | 395 | 1395 | 1395 | 2395 | 2 |
| leave | 56244 | 56244 | 56244 | 56244 | 1 |
| lock | 12063 | 34172 | 16480 | 73975 | 3 |
Expand All @@ -41,7 +56,7 @@
| rewardStartTime | 352 | 1352 | 1352 | 2352 | 2 |
| rewardsBalanceOf | 1317 | 1317 | 1317 | 1317 | 4 |
| setReward | 2583 | 50892 | 60278 | 102595 | 7 |
| setTrustedCodehash | 26243 | 26243 | 26243 | 26243 | 59 |
| setTrustedCodehash | 24243 | 24310 | 24243 | 26243 | 59 |
| stake | 131082 | 170202 | 177899 | 198232 | 66 |
| totalMP | 373 | 373 | 373 | 373 | 81 |
| totalMaxMP | 350 | 350 | 350 | 350 | 81 |
Expand All @@ -54,13 +69,39 @@
| upgradeToAndCall | 3225 | 9387 | 10926 | 10936 | 5 |


| src/StakeManagerProxy.sol:StakeManagerProxy contract | | | | | |
|------------------------------------------------------|-----------------|------|--------|--------|---------|
| Deployment Cost | Deployment Size | | | | |
| 256079 | 1231 | | | | |
| Function Name | min | avg | median | max | # calls |
| fallback | 678 | 8892 | 2115 | 136272 | 1047 |
| implementation | 343 | 808 | 343 | 2343 | 382 |
| src/StakeManagerProxy.sol:StakeManagerProxy contract | | | | | |
|------------------------------------------------------|-----------------|-------|--------|--------|---------|
| Deployment Cost | Deployment Size | | | | |
| 256467 | 1263 | | | | |
| Function Name | min | avg | median | max | # calls |
| MAX_LOCKUP_PERIOD | 5276 | 5276 | 5276 | 5276 | 4 |
| MAX_MULTIPLIER | 678 | 3132 | 5178 | 5178 | 11 |
| MIN_LOCKUP_PERIOD | 724 | 3996 | 5224 | 5224 | 11 |
| MP_RATE_PER_YEAR | 680 | 680 | 680 | 680 | 3 |
| STAKING_TOKEN | 855 | 6086 | 7355 | 7355 | 292 |
| emergencyModeEnabled | 7347 | 7347 | 7347 | 7347 | 7 |
| enableEmergencyMode | 28480 | 45381 | 50665 | 50665 | 8 |
| getAccount | 2115 | 2115 | 2115 | 2115 | 72 |
| getStakedBalance | 7559 | 7559 | 7559 | 7559 | 1 |
| getUserTotalMP | 9660 | 9660 | 9660 | 9660 | 1 |
| getUserTotalMaxMP | 3553 | 3553 | 3553 | 3553 | 1 |
| getUserTotalStakedBalance | 15548 | 15548 | 15548 | 15548 | 1 |
| getUserVaults | 5637 | 6762 | 5637 | 10137 | 4 |
| implementation | 343 | 808 | 343 | 2343 | 382 |
| lastRewardTime | 822 | 1822 | 1822 | 2822 | 2 |
| rewardEndTime | 800 | 1800 | 1800 | 2800 | 2 |
| rewardStartTime | 779 | 4029 | 4029 | 7279 | 2 |
| rewardsBalanceOf | 1747 | 1747 | 1747 | 1747 | 4 |
| setReward | 28863 | 77206 | 86636 | 128881 | 7 |
| setTrustedCodehash | 52889 | 52889 | 52889 | 52889 | 2 |
| totalMP | 800 | 800 | 800 | 800 | 81 |
| totalMaxMP | 777 | 777 | 777 | 777 | 81 |
| totalRewardsAccrued | 800 | 800 | 800 | 800 | 3 |
| totalRewardsSupply | 1387 | 2498 | 2151 | 11627 | 30 |
| totalStaked | 823 | 823 | 823 | 823 | 82 |
| updateAccountMP | 41755 | 44833 | 44257 | 61357 | 21 |
| updateGlobalState | 37076 | 54033 | 51237 | 136272 | 21 |
| upgradeToAndCall | 29868 | 36025 | 37562 | 37572 | 5 |


| src/StakeVault.sol:StakeVault contract | | | | | |
Expand Down
14 changes: 7 additions & 7 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ EmergencyExitTest:test_OnlyOwnerCanEnableEmergencyMode() (gas: 39430)
IntegrationTest:testStakeFoo() (gas: 1178499)
LeaveTest:test_LeaveShouldProperlyUpdateAccounting() (gas: 2960876)
LeaveTest:test_RevertWhenStakeManagerIsTrusted() (gas: 294826)
LeaveTest:test_TrustNewStakeManager() (gas: 3036018)
LeaveTest:test_TrustNewStakeManager() (gas: 3038518)
LockTest:test_LockFailsWithInvalidPeriod() (gas: 309911)
LockTest:test_LockFailsWithNoStake() (gas: 63708)
LockTest:test_LockWithoutPriorLock() (gas: 385937)
Expand All @@ -21,12 +21,12 @@ NFTMetadataGeneratorSVGTest:testSetImageStringsRevert() (gas: 35804)
NFTMetadataGeneratorURLTest:testGenerateMetadata() (gas: 102512)
NFTMetadataGeneratorURLTest:testSetBaseURL() (gas: 49555)
NFTMetadataGeneratorURLTest:testSetBaseURLRevert() (gas: 35979)
RewardsStreamerMP_RewardsTest:testRewardsBalanceOf() (gas: 670682)
RewardsStreamerMP_RewardsTest:testSetRewards() (gas: 160280)
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 39345)
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 39368)
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsNotAuthorized() (gas: 39381)
RewardsStreamerMP_RewardsTest:testTotalRewardsSupply() (gas: 610702)
RewardsStreamerMP_RewardsTest:testRewardsBalanceOf() (gas: 670670)
RewardsStreamerMP_RewardsTest:testSetRewards() (gas: 160274)
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 39339)
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 39362)
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsNotAuthorized() (gas: 39375)
RewardsStreamerMP_RewardsTest:testTotalRewardsSupply() (gas: 610684)
RewardsStreamerTest:testStake() (gas: 869181)
StakeTest:test_StakeMultipleAccounts() (gas: 494442)
StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 500380)
Expand Down
41 changes: 41 additions & 0 deletions script/Base.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.26 <=0.9.0;

import { Script } from "forge-std/Script.sol";

abstract contract BaseScript is Script {
/// @dev Included to enable compilation of the script without a $MNEMONIC environment variable.
string internal constant TEST_MNEMONIC = "test test test test test test test test test test test junk";

/// @dev Needed for the deterministic deployments.
bytes32 internal constant ZERO_SALT = bytes32(0);

/// @dev The address of the transaction broadcaster.
address internal broadcaster;

/// @dev Used to derive the broadcaster's address if $ETH_FROM is not defined.
string internal mnemonic;

/// @dev Initializes the transaction broadcaster like this:
///
/// - If $ETH_FROM is defined, use it.
/// - Otherwise, derive the broadcaster address from $MNEMONIC.
/// - If $MNEMONIC is not defined, default to a test mnemonic.
///
/// The use case for $ETH_FROM is to specify the broadcaster key and its address via the command line.
constructor() {
address from = vm.envOr({ name: "ETH_FROM", defaultValue: address(0) });
if (from != address(0)) {
broadcaster = from;
} else {
mnemonic = vm.envOr({ name: "MNEMONIC", defaultValue: TEST_MNEMONIC });
(broadcaster,) = deriveRememberKey({ mnemonic: mnemonic, index: 0 });
}
}

modifier broadcast() {
vm.startBroadcast(broadcaster);
_;
vm.stopBroadcast();
}
}
33 changes: 33 additions & 0 deletions script/DeployRewardsStreamerMP.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import { BaseScript } from "./Base.s.sol";
import { DeploymentConfig } from "./DeploymentConfig.s.sol";
import { IStakeManagerProxy } from "../src/interfaces/IStakeManagerProxy.sol";
import { StakeManagerProxy } from "../src/StakeManagerProxy.sol";
import { RewardsStreamerMP } from "../src/RewardsStreamerMP.sol";
import { StakeVault } from "../src/StakeVault.sol";

contract DeployRewardsStreamerMPScript is BaseScript {
function run() public returns (RewardsStreamerMP, DeploymentConfig) {
DeploymentConfig deploymentConfig = new DeploymentConfig(broadcaster);
(address deployer, address stakingToken) = deploymentConfig.activeNetworkConfig();

bytes memory initializeData = abi.encodeCall(RewardsStreamerMP.initialize, (deployer, stakingToken));

vm.startBroadcast(deployer);
address impl = address(new RewardsStreamerMP());
address proxy = address(new StakeManagerProxy(impl, initializeData));
vm.stopBroadcast();

RewardsStreamerMP stakeManager = RewardsStreamerMP(proxy);
StakeVault tempVault = new StakeVault(address(this), IStakeManagerProxy(proxy));
bytes32 vaultCodeHash = address(tempVault).codehash;

vm.startBroadcast(deployer);
stakeManager.setTrustedCodehash(vaultCodeHash, true);
vm.stopBroadcast();

return (stakeManager, deploymentConfig);
}
}
42 changes: 42 additions & 0 deletions script/DeploymentConfig.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.8.26 <=0.9.0;

import { Script } from "forge-std/Script.sol";
import { MockToken } from "../test/mocks/MockToken.sol";

contract DeploymentConfig is Script {
error DeploymentConfig_InvalidDeployerAddress();
error DeploymentConfig_NoConfigForChain(uint256);

struct NetworkConfig {
address deployer;
address stakingToken;
}

NetworkConfig public activeNetworkConfig;

address private deployer;

constructor(address _broadcaster) {
if (_broadcaster == address(0)) revert DeploymentConfig_InvalidDeployerAddress();
deployer = _broadcaster;
if (block.chainid == 31_337) {
activeNetworkConfig = getOrCreateAnvilEthConfig();
} else {
revert DeploymentConfig_NoConfigForChain(block.chainid);
}
}

function getOrCreateAnvilEthConfig() public returns (NetworkConfig memory) {
MockToken stakingToken = new MockToken("Staking Token", "ST");
return NetworkConfig({ deployer: deployer, stakingToken: address(stakingToken) });
}

// This function is a hack to have it excluded by `forge coverage` until
// https://github.com/foundry-rs/foundry/issues/2988 is fixed.
// See: https://github.com/foundry-rs/foundry/issues/2988#issuecomment-1437784542
// for more info.
// solhint-disable-next-line
function test() public { }
}
17 changes: 0 additions & 17 deletions script/RewardsStreamer.s.sol

This file was deleted.

28 changes: 9 additions & 19 deletions test/RewardsStreamerMP.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ pragma solidity ^0.8.26;

import { Test } from "forge-std/Test.sol";
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { DeployRewardsStreamerMPScript } from "../script/DeployRewardsStreamerMP.s.sol";
import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import { RewardsStreamerMP } from "../src/RewardsStreamerMP.sol";
import { StakeVault } from "../src/StakeVault.sol";
import { IStakeManagerProxy } from "../src/interfaces/IStakeManagerProxy.sol";
Expand All @@ -17,7 +18,7 @@ contract RewardsStreamerMPTest is Test {
MockToken stakingToken;
RewardsStreamerMP public streamer;

address admin = makeAddr("admin");
address admin;
address alice = makeAddr("alice");
address bob = makeAddr("bob");
address charlie = makeAddr("charlie");
Expand All @@ -26,20 +27,14 @@ contract RewardsStreamerMPTest is Test {
mapping(address owner => address vault) public vaults;

function setUp() public virtual {
stakingToken = new MockToken("Staking Token", "ST");
DeployRewardsStreamerMPScript deployment = new DeployRewardsStreamerMPScript();
(RewardsStreamerMP stakeManager, DeploymentConfig deploymentConfig) = deployment.run();

bytes memory initializeData = abi.encodeCall(RewardsStreamerMP.initialize, (admin, address(stakingToken)));
address impl = address(new RewardsStreamerMP());
address proxy = address(new StakeManagerProxy(impl, initializeData));
streamer = RewardsStreamerMP(proxy);
(address _deployer, address _stakingToken) = deploymentConfig.activeNetworkConfig();

// Create a temporary vault just to get the codehash
StakeVault tempVault = new StakeVault(address(this), IStakeManagerProxy(address(streamer)));
bytes32 vaultCodeHash = address(tempVault).codehash;

// Register the codehash before creating any user vaults
vm.prank(admin);
streamer.setTrustedCodehash(vaultCodeHash, true);
streamer = stakeManager;
stakingToken = MockToken(_stakingToken);
admin = _deployer;

address[4] memory accounts = [alice, bob, charlie, dave];
for (uint256 i = 0; i < accounts.length; i++) {
Expand Down Expand Up @@ -111,11 +106,6 @@ contract RewardsStreamerMPTest is Test {
vm.prank(owner);
vault = new StakeVault(owner, IStakeManagerProxy(address(streamer)));
vault.register();

if (!streamer.isTrustedCodehash(address(vault).codehash)) {
vm.prank(admin);
streamer.setTrustedCodehash(address(vault).codehash, true);
}
}

function _stake(address account, uint256 amount, uint256 lockupTime) public {
Expand Down
Loading