Skip to content

Commit

Permalink
feat: Earner Manager
Browse files Browse the repository at this point in the history
  • Loading branch information
deluca-mike committed Jan 17, 2025
1 parent 8d7134c commit 821a060
Show file tree
Hide file tree
Showing 23 changed files with 1,944 additions and 291 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
MNEMONIC: ${{ secrets.MNEMONIC_FOR_TESTS }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }}
run: make coverage profile=ci
run: make coverage

- name: Report code coverage
uses: zgosalvez/github-actions-report-lcov@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-gas.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
FOUNDRY_FUZZ_SEED: 0x${{ github.event.pull_request.base.sha || github.sha }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }}
run: make gas-report profile=ci
run: make gas-report

- name: Compare gas reports
uses: Rubilmax/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ jobs:
env:
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }}
run: make integration profile=ci
run: make integration
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ invariant:
MAINNET_RPC_URL=$(MAINNET_RPC_URL) ./test.sh -d test/invariant -p $(profile)

coverage:
FOUNDRY_PROFILE=$(profile) MAINNET_RPC_URL=$(MAINNET_RPC_URL) forge coverage --no-match-path 'test/in*/**/*.sol' --report lcov && lcov --extract lcov.info --rc lcov_branch_coverage=1 --rc derive_function_end_line=0 -o lcov.info 'src/*' && genhtml lcov.info --rc branch_coverage=1 --rc derive_function_end_line=0 -o coverage
MAINNET_RPC_URL=$(MAINNET_RPC_URL) forge coverage --no-match-path 'test/in*/**/*.sol' --report lcov && lcov --extract lcov.info --rc lcov_branch_coverage=1 --rc derive_function_end_line=0 -o lcov.info 'src/*' && genhtml lcov.info --rc branch_coverage=1 --rc derive_function_end_line=0 -o coverage

gas-report:
FOUNDRY_PROFILE=production forge test --no-match-path 'test/integration/**/*.sol' --gas-report > gasreport.ansi
Expand Down
41 changes: 29 additions & 12 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ contract DeployProduction is Script, DeployBase {
address deployer_ = vm.rememberKey(vm.envUint("PRIVATE_KEY"));
address expectedDeployer_ = vm.envAddress("DEPLOYER");

uint64 deployerProxyNonce_ = uint64(vm.envUint("DEPLOYER_PROXY_NONCE"));
uint64 deployerWrappedMProxyNonce_ = uint64(vm.envUint("DEPLOYER_WRAPPED_M_PROXY_NONCE"));

address registrar_ = vm.envAddress("REGISTRAR");
address excessDestination_ = vm.envAddress("EXCESS_DESTINATION");
address mToken_ = vm.envAddress("M_TOKEN");
address migrationAdmin_ = vm.envAddress("MIGRATION_ADMIN");
address expectedProxy_ = vm.envAddress("EXPECTED_PROXY");
address wrappedMMigrationAdmin_ = vm.envAddress("WRAPPED_M_MIGRATION_ADMIN");
address earnerManagerMigrationAdmin_ = vm.envAddress("EARNER_MANAGER_MIGRATION_ADMIN");
address expectedWrappedMProxy_ = vm.envAddress("EXPECTED_WRAPPED_M_PROXY");

console2.log("Deployer:", deployer_);

Expand All @@ -38,15 +39,22 @@ contract DeployProduction is Script, DeployBase {
uint64 currentNonce_ = vm.getNonce(deployer_);

uint64 startNonce_ = currentNonce_;
address implementation_;
address proxy_;
address earnerManagerImplementation_;
address earnerManagerProxy_;
address wrappedMTokenImplementation_;
address wrappedMTokenProxy_;

while (true) {
if (startNonce_ > deployerProxyNonce_) revert DeployerNonceTooHigh();
if (startNonce_ > deployerWrappedMProxyNonce_) revert DeployerNonceTooHigh();

(implementation_, proxy_) = mockDeploy(deployer_, startNonce_);
(
earnerManagerImplementation_,
earnerManagerProxy_,
wrappedMTokenImplementation_,
wrappedMTokenProxy_
) = mockDeploy(deployer_, startNonce_);

if (proxy_ == expectedProxy_) break;
if (wrappedMTokenProxy_ == expectedWrappedMProxy_) break;

++startNonce_;
}
Expand All @@ -63,13 +71,22 @@ contract DeployProduction is Script, DeployBase {

if (currentNonce_ != startNonce_) revert UnexpectedDeployerNonce();

(implementation_, proxy_) = deploy(mToken_, registrar_, excessDestination_, migrationAdmin_);
(earnerManagerImplementation_, earnerManagerProxy_, wrappedMTokenImplementation_, wrappedMTokenProxy_) = deploy(
mToken_,
registrar_,
excessDestination_,
wrappedMMigrationAdmin_,
earnerManagerMigrationAdmin_
);

vm.stopBroadcast();

console2.log("Wrapped M Implementation address:", implementation_);
console2.log("Migrator address:", proxy_);
console2.log("Wrapped M Implementation address:", wrappedMTokenImplementation_);
console2.log("Wrapped M Proxy address:", wrappedMTokenProxy_);
console2.log("Earner Manager Implementation address:", earnerManagerImplementation_);
console2.log("Earner Manager Proxy address:", earnerManagerProxy_);

if (proxy_ != expectedProxy_) revert ResultingProxyMismatch(expectedProxy_, proxy_);
if (wrappedMTokenProxy_ != expectedWrappedMProxy_)
revert ResultingProxyMismatch(expectedWrappedMProxy_, wrappedMTokenProxy_);
}
}
163 changes: 120 additions & 43 deletions script/DeployBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,87 +5,164 @@ pragma solidity 0.8.26;
import { ContractHelper } from "../lib/common/src/libs/ContractHelper.sol";
import { Proxy } from "../lib/common/src/Proxy.sol";

import { MigratorV1 } from "../src/MigratorV1.sol";
import { EarnerManager } from "../src/EarnerManager.sol";
import { WrappedMTokenMigratorV1 } from "../src/WrappedMTokenMigratorV1.sol";
import { WrappedMToken } from "../src/WrappedMToken.sol";

contract DeployBase {
/**
* @dev Deploys Wrapped M Token.
* @param mToken_ The address of the M Token contract.
* @param registrar_ The address of the Registrar contract.
* @param excessDestination_ The address of the excess destination.
* @param migrationAdmin_ The address of the Migration Admin.
* @return implementation_ The address of the deployed Wrapped M Token implementation.
* @return proxy_ The address of the deployed Wrapped M Token proxy.
* @param mToken_ The address of the M Token contract.
* @param registrar_ The address of the Registrar contract.
* @param excessDestination_ The address of the excess destination.
* @param wrappedMMigrationAdmin_ The address of the Wrapped M Migration Admin.
* @param earnerManagerMigrationAdmin_ The address of the Earner Manager Migration Admin.
* @return earnerManagerImplementation_ The address of the deployed Earner Manager implementation.
* @return earnerManagerProxy_ The address of the deployed Earner Manager proxy.
* @return wrappedMTokenImplementation_ The address of the deployed Wrapped M Token implementation.
* @return wrappedMTokenProxy_ The address of the deployed Wrapped M Token proxy.
*/
function deploy(
address mToken_,
address registrar_,
address excessDestination_,
address migrationAdmin_
) public virtual returns (address implementation_, address proxy_) {
// Wrapped M token needs `mToken_`, `registrar_`, `excessDestination_`, and `migrationAdmin_` addresses.
// Proxy needs `implementation_` addresses.
address wrappedMMigrationAdmin_,
address earnerManagerMigrationAdmin_
)
public
virtual
returns (
address earnerManagerImplementation_,
address earnerManagerProxy_,
address wrappedMTokenImplementation_,
address wrappedMTokenProxy_
)
{
// Earner Manager Implementation constructor needs only known values.
// Earner Manager Proxy constructor needs `earnerManagerImplementation_`.
// Wrapped M Token Implementation constructor needs `earnerManagerProxy_`.
// Wrapped M Token Proxy constructor needs `wrappedMTokenImplementation_`.

implementation_ = address(new WrappedMToken(mToken_, registrar_, excessDestination_, migrationAdmin_));
proxy_ = address(new Proxy(implementation_));
earnerManagerImplementation_ = address(new EarnerManager(registrar_, earnerManagerMigrationAdmin_));

earnerManagerProxy_ = address(new Proxy(earnerManagerImplementation_));

wrappedMTokenImplementation_ = address(
new WrappedMToken(mToken_, registrar_, earnerManagerProxy_, excessDestination_, wrappedMMigrationAdmin_)
);

wrappedMTokenProxy_ = address(new Proxy(wrappedMTokenImplementation_));
}

/**
* @dev Deploys Wrapped M Token components needed to upgrade an existing Wrapped M proxy.
* @param mToken_ The address of the M Token contract.
* @param registrar_ The address of the Registrar contract.
* @param excessDestination_ The address of the excess destination.
* @param migrationAdmin_ The address of the Migration Admin.
* @return implementation_ The address of the deployed Wrapped M Token implementation.
* @return migrator_ The address of the deployed Migrator.
* @param mToken_ The address of the M Token contract.
* @param registrar_ The address of the Registrar contract.
* @param excessDestination_ The address of the excess destination.
* @param wrappedMMigrationAdmin_ The address of the Wrapped M Migration Admin.
* @param earnerManagerMigrationAdmin_ The address of the Earner Manager Migration Admin.
* @return earnerManagerImplementation_ The address of the deployed Earner Manager implementation.
* @return earnerManagerProxy_ The address of the deployed Earner Manager proxy.
* @return wrappedMTokenImplementation_ The address of the deployed Wrapped M Token implementation.
* @return wrappedMTokenMigrator_ The address of the deployed Wrapped M Token Migrator.
*/
function deployUpgrade(
address mToken_,
address registrar_,
address excessDestination_,
address migrationAdmin_
) public virtual returns (address implementation_, address migrator_) {
// Wrapped M token needs `mToken_`, `registrar_`, `excessDestination_`, and `migrationAdmin_` addresses.
// Migrator needs `implementation_` addresses.
address wrappedMMigrationAdmin_,
address earnerManagerMigrationAdmin_
)
public
virtual
returns (
address earnerManagerImplementation_,
address earnerManagerProxy_,
address wrappedMTokenImplementation_,
address wrappedMTokenMigrator_
)
{
// Earner Manager Implementation constructor needs only known values.
// Earner Manager Proxy constructor needs `earnerManagerImplementation_`.
// Wrapped M Token Implementation constructor needs `earnerManagerProxy_`.
// Migrator needs `wrappedMTokenImplementation_` addresses.

earnerManagerImplementation_ = address(new EarnerManager(registrar_, earnerManagerMigrationAdmin_));

earnerManagerProxy_ = address(new Proxy(earnerManagerImplementation_));

wrappedMTokenImplementation_ = address(
new WrappedMToken(mToken_, registrar_, earnerManagerProxy_, excessDestination_, wrappedMMigrationAdmin_)
);

implementation_ = address(new WrappedMToken(mToken_, registrar_, excessDestination_, migrationAdmin_));
migrator_ = address(new MigratorV1(implementation_));
wrappedMTokenMigrator_ = address(new WrappedMTokenMigratorV1(wrappedMTokenImplementation_));
}

/**
* @dev Mock deploys Wrapped M Token, returning the would-be addresses.
* @param deployer_ The address of the deployer.
* @param deployerNonce_ The nonce of the deployer.
* @return implementation_ The address of the would-be Wrapped M Token implementation.
* @return proxy_ The address of the would-be Wrapped M Token proxy.
* @param deployer_ The address of the deployer.
* @param deployerNonce_ The nonce of the deployer.
* @return earnerManagerImplementation_ The address of the would-be Earner Manager implementation.
* @return earnerManagerProxy_ The address of the would-be Earner Manager proxy.
* @return wrappedMTokenImplementation_ The address of the would-be Wrapped M Token implementation.
* @return wrappedMTokenProxy_ The address of the would-be Wrapped M Token proxy.
*/
function mockDeploy(
address deployer_,
uint256 deployerNonce_
) public view virtual returns (address implementation_, address proxy_) {
// Wrapped M token needs `mToken_`, `registrar_`, `excessDestination_`, and `migrationAdmin_` addresses.
// Proxy needs `implementation_` addresses.
)
public
view
virtual
returns (
address earnerManagerImplementation_,
address earnerManagerProxy_,
address wrappedMTokenImplementation_,
address wrappedMTokenProxy_
)
{
// Earner Manager Implementation constructor needs only known values.
// Earner Manager Proxy constructor needs `earnerManagerImplementation_`.
// Wrapped M Token Implementation constructor needs `earnerManagerProxy_`.
// Wrapped M Token Proxy constructor needs `wrappedMTokenImplementation_`.

implementation_ = ContractHelper.getContractFrom(deployer_, deployerNonce_);
proxy_ = ContractHelper.getContractFrom(deployer_, deployerNonce_ + 1);
earnerManagerImplementation_ = ContractHelper.getContractFrom(deployer_, deployerNonce_);
earnerManagerProxy_ = ContractHelper.getContractFrom(deployer_, deployerNonce_ + 1);
wrappedMTokenImplementation_ = ContractHelper.getContractFrom(deployer_, deployerNonce_ + 2);
wrappedMTokenProxy_ = ContractHelper.getContractFrom(deployer_, deployerNonce_ + 3);
}

/**
* @dev Mock deploys Wrapped M Token, returning the would-be addresses.
* @param deployer_ The address of the deployer.
* @param deployerNonce_ The nonce of the deployer.
* @return implementation_ The address of the would-be Wrapped M Token implementation.
* @return migrator_ The address of the would-be Migrator.
* @param deployer_ The address of the deployer.
* @param deployerNonce_ The nonce of the deployer.
* @return earnerManagerImplementation_ The address of the would-be Earner Manager implementation.
* @return earnerManagerProxy_ The address of the would-be Earner Manager proxy.
* @return wrappedMTokenImplementation_ The address of the would-be Wrapped M Token implementation.
* @return wrappedMTokenMigrator_ The address of the deployed Wrapped M Token Migrator.
*/
function mockDeployUpgrade(
address deployer_,
uint256 deployerNonce_
) public view virtual returns (address implementation_, address migrator_) {
// Wrapped M token needs `mToken_`, `registrar_`, `excessDestination_`, and `migrationAdmin_` addresses.
// Migrator needs `implementation_` addresses.
)
public
view
virtual
returns (
address earnerManagerImplementation_,
address earnerManagerProxy_,
address wrappedMTokenImplementation_,
address wrappedMTokenMigrator_
)
{
// Earner Manager Implementation constructor needs only known values.
// Earner Manager Proxy constructor needs `earnerManagerImplementation_`.
// Wrapped M Token Implementation constructor needs `earnerManagerProxy_`.
// Migrator needs `wrappedMTokenImplementation_` addresses.

implementation_ = ContractHelper.getContractFrom(deployer_, deployerNonce_);
migrator_ = ContractHelper.getContractFrom(deployer_, deployerNonce_ + 1);
earnerManagerImplementation_ = ContractHelper.getContractFrom(deployer_, deployerNonce_);
earnerManagerProxy_ = ContractHelper.getContractFrom(deployer_, deployerNonce_ + 1);
wrappedMTokenImplementation_ = ContractHelper.getContractFrom(deployer_, deployerNonce_ + 2);
wrappedMTokenMigrator_ = ContractHelper.getContractFrom(deployer_, deployerNonce_ + 3);
}
}
Loading

0 comments on commit 821a060

Please sign in to comment.