Skip to content
Open
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
17 changes: 12 additions & 5 deletions script/DeployBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,18 @@ contract DeployBase {
// Wrapped M Token Implementation constructor needs `earnerManagerProxy_`.
// Wrapped M Token Proxy constructor needs `wrappedMTokenImplementation_`.

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

earnerManagerProxy_ = address(new Proxy(earnerManagerImplementation_));

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

wrappedMTokenProxy_ = address(new Proxy(wrappedMTokenImplementation_));

EarnerManager(earnerManagerProxy_).initialize(earnerManagerMigrationAdmin_);
WrappedMToken(wrappedMTokenProxy_).initialize(wrappedMMigrationAdmin_);
}

/**
Expand Down Expand Up @@ -88,15 +91,19 @@ contract DeployBase {
// Wrapped M Token Implementation constructor needs `earnerManagerProxy_`.
// Migrator needs `wrappedMTokenImplementation_` addresses.

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

earnerManagerProxy_ = address(new Proxy(earnerManagerImplementation_));

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

wrappedMTokenMigrator_ = address(
new WrappedMTokenMigratorV1(wrappedMTokenImplementation_, earners_, wrappedMMigrationAdmin_)
);

wrappedMTokenMigrator_ = address(new WrappedMTokenMigratorV1(wrappedMTokenImplementation_, earners_));
EarnerManager(earnerManagerProxy_).initialize(earnerManagerMigrationAdmin_);
}

/**
Expand Down
71 changes: 59 additions & 12 deletions src/EarnerManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,49 @@ contract EarnerManager is IEarnerManager, Migratable {
/// @inheritdoc IEarnerManager
address public immutable registrar;

/// @dev Used to check if the contract is the implementation or a proxy.
address internal immutable _self = address(this);

/// @inheritdoc IEarnerManager
address public migrationAdmin;

/// @inheritdoc IEarnerManager
address public immutable migrationAdmin;
address public pendingMigrationAdmin;

/// @dev Mapping of account to earner details.
mapping(address account => EarnerDetails earnerDetails) internal _earnerDetails;

/* ============ Modifiers ============ */

modifier onlyMigrationAdmin() {
_revertIfNotMigrationAdmin();
_;
}

modifier onlyAdmin() {
_revertIfNotAdmin();
_;
}

/* ============ Constructor ============ */
/* ============ Constructor and Initializer ============ */

/**
* @dev Constructs the contract.
* @param registrar_ The address of a Registrar contract.
* @param migrationAdmin_ The address of a migration admin.
* @param registrar_ The address of a Registrar contract.
*/
constructor(address registrar_, address migrationAdmin_) {
constructor(address registrar_) {
if ((registrar = registrar_) == address(0)) revert ZeroRegistrar();
if ((migrationAdmin = migrationAdmin_) == address(0)) revert ZeroMigrationAdmin();
}

/**
* @dev Used by a proxy of this implementation to initialize its state.
* @param migrationAdmin_ The address of a migration admin.
*/
function initialize(address migrationAdmin_) external {
if (address(this) == _self) revert NotProxy();
if (migrationAdmin != address(0)) revert AlreadyInitialized();

_setMigrationAdmin(migrationAdmin_);
}

/* ============ Interactive Functions ============ */
Expand Down Expand Up @@ -95,12 +115,24 @@ contract EarnerManager is IEarnerManager, Migratable {
/* ============ Temporary Admin Migration ============ */

/// @inheritdoc IEarnerManager
function migrate(address migrator_) external {
if (msg.sender != migrationAdmin) revert UnauthorizedMigration();

function migrate(address migrator_) external onlyMigrationAdmin {
_migrate(migrator_);
}

/// @inheritdoc IEarnerManager
function setPendingMigrationAdmin(address migrationAdmin_) external onlyMigrationAdmin {
emit PendingMigrationAdminSet(pendingMigrationAdmin = migrationAdmin_);
}

/// @inheritdoc IEarnerManager
function acceptMigrationAdmin() external {
if (msg.sender != pendingMigrationAdmin) revert NotPendingMigrationAdmin();

_setMigrationAdmin(msg.sender);

delete pendingMigrationAdmin;
}

/* ============ View/Pure Functions ============ */

/// @inheritdoc IEarnerManager
Expand Down Expand Up @@ -228,10 +260,13 @@ contract EarnerManager is IEarnerManager, Migratable {
}

/**
* @dev Reverts if the caller is not an admin.
* @dev Sets the migration admin to `migrationAdmin_`.
* @param migrationAdmin_ The address of the account to set as the migration admin.
*/
function _revertIfNotAdmin() internal view {
if (!isAdmin(msg.sender)) revert NotAdmin();
function _setMigrationAdmin(address migrationAdmin_) internal {
if ((migrationAdmin = migrationAdmin_) == address(0)) revert ZeroMigrationAdmin();

emit MigrationAdminSet(migrationAdmin_);
}

/* ============ Internal View/Pure Functions ============ */
Expand All @@ -255,4 +290,16 @@ contract EarnerManager is IEarnerManager, Migratable {
function _isValidAdmin(address admin_) internal view returns (bool isValidAdmin_) {
return (admin_ != address(0)) && isAdmin(admin_);
}

/**
* @dev Reverts if the caller is not an admin.
*/
function _revertIfNotAdmin() internal view {
if (!isAdmin(msg.sender)) revert NotAdmin();
}

/// @dev Reverts if the caller is not the migration admin.
function _revertIfNotMigrationAdmin() internal view {
if (msg.sender != migrationAdmin) revert NotMigrationAdmin();
}
}
Loading