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

[Proposed] ACP-99: Implement using inheritance #667

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
59 changes: 59 additions & 0 deletions contracts/validator-manager/ACP99ValidatorManager.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// (c) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

// SPDX-License-Identifier: Ecosystem

import {IACP99SecurityModule} from "./interfaces/IACP99SecurityModule.sol";
import {ValidatorManager} from "./ValidatorManager.sol";
import {IACP99ValidatorManager, ConversionData, ValidatorRegistrationInput} from "./interfaces/IACP99ValidatorManager.sol";

pragma solidity 0.8.25;

abstract contract ACP99ValidatorManager is IACP99ValidatorManager, ValidatorManager {
IACP99SecurityModule public securityModule;

// TODO: calling this should be restricted to...who?
function setSecurityModule(IACP99SecurityModule _securityModule) external {
securityModule = _securityModule;
}

function initializeValidatorSet(
ConversionData calldata conversionData,
uint32 messageIndex
) external {
_initializeValidatorSet(conversionData, messageIndex);
}

function initializeValidatorRegistration(
ValidatorRegistrationInput calldata input,
uint64 weight,
bytes calldata args
) external returns (bytes32){
bytes32 validationID = _initializeValidatorRegistration(input, weight);
securityModule.handleInitializeValidatorRegistration(validationID, weight, args);
return validationID;
}

function completeValidatorRegistration(uint32 messageIndex) external{
bytes32 validationID = _completeValidatorRegistration(messageIndex);
securityModule.handleCompleteValidatorRegistration(validationID);
}

function initializeEndValidation(bytes32 validationID, bytes calldata args) external{
_initializeEndValidation(validationID);
securityModule.handleInitializeEndValidation(validationID, args);
}

function completeEndValidation(uint32 messageIndex) external{
bytes32 validationID = _completeEndValidation(messageIndex);
securityModule.handleCompleteEndValidation(validationID);
}

function initializeValidatorWeightChange(bytes32 validationID, uint64 weight, bytes calldata args) external{
securityModule.handleInitializeValidatorWeightChange(validationID, weight, args);
}

function completeValidatorWeightChange(bytes32 validationID, bytes calldata args) external{
securityModule.handleCompleteValidatorWeightChange(validationID, args);
}
}
20 changes: 2 additions & 18 deletions contracts/validator-manager/ERC20TokenStakingManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,22 @@ pragma solidity 0.8.25;

import {PoSValidatorManager} from "./PoSValidatorManager.sol";
import {PoSValidatorManagerSettings} from "./interfaces/IPoSValidatorManager.sol";
import {ValidatorRegistrationInput} from "./interfaces/IValidatorManager.sol";
import {IERC20TokenStakingManager} from "./interfaces/IERC20TokenStakingManager.sol";
import {IERC20Mintable} from "./interfaces/IERC20Mintable.sol";
import {ICMInitializable} from "@utilities/ICMInitializable.sol";
import {SafeERC20TransferFrom} from "@utilities/SafeERC20TransferFrom.sol";
import {Initializable} from
"@openzeppelin/[email protected]/proxy/utils/Initializable.sol";
import {SafeERC20} from "@openzeppelin/[email protected]/token/ERC20/utils/SafeERC20.sol";


/**
* @dev Implementation of the {IERC20TokenStakingManager} interface.
*
* @custom:security-contact https://github.com/ava-labs/teleporter/blob/main/SECURITY.md
*/
contract ERC20TokenStakingManager is
Initializable,
PoSValidatorManager,
IERC20TokenStakingManager
PoSValidatorManager
{
using SafeERC20 for IERC20Mintable;
using SafeERC20TransferFrom for IERC20Mintable;
Expand Down Expand Up @@ -95,20 +93,6 @@ contract ERC20TokenStakingManager is
$._token = token;
}

/**
* @notice See {IERC20TokenStakingManager-initializeValidatorRegistration}
*/
function initializeValidatorRegistration(
ValidatorRegistrationInput calldata registrationInput,
uint16 delegationFeeBips,
uint64 minStakeDuration,
uint256 stakeAmount
) external nonReentrant returns (bytes32 validationID) {
return _initializeValidatorRegistration(
registrationInput, delegationFeeBips, minStakeDuration, stakeAmount
);
}

/**
* @notice See {IERC20TokenStakingManager-initializeDelegatorRegistration}
*/
Expand Down
18 changes: 1 addition & 17 deletions contracts/validator-manager/NativeTokenStakingManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ pragma solidity 0.8.25;

import {PoSValidatorManager} from "./PoSValidatorManager.sol";
import {PoSValidatorManagerSettings} from "./interfaces/IPoSValidatorManager.sol";
import {ValidatorRegistrationInput} from "./interfaces/IValidatorManager.sol";
import {INativeTokenStakingManager} from "./interfaces/INativeTokenStakingManager.sol";
import {INativeMinter} from
"@avalabs/[email protected]/contracts/interfaces/INativeMinter.sol";
import {ICMInitializable} from "@utilities/ICMInitializable.sol";
Expand All @@ -23,8 +21,7 @@ import {Initializable} from
*/
contract NativeTokenStakingManager is
Initializable,
PoSValidatorManager,
INativeTokenStakingManager
PoSValidatorManager
{
using Address for address payable;

Expand Down Expand Up @@ -58,19 +55,6 @@ contract NativeTokenStakingManager is
// solhint-disable-next-line func-name-mixedcase, no-empty-blocks
function __NativeTokenStakingManager_init_unchained() internal onlyInitializing {}

/**
* @notice See {INativeTokenStakingManager-initializeValidatorRegistration}.
*/
function initializeValidatorRegistration(
ValidatorRegistrationInput calldata registrationInput,
uint16 delegationFeeBips,
uint64 minStakeDuration
) external payable nonReentrant returns (bytes32) {
return _initializeValidatorRegistration(
registrationInput, delegationFeeBips, minStakeDuration, msg.value
);
}

/**
* @notice See {INativeTokenStakingManager-initializeDelegatorRegistration}.
*/
Expand Down
47 changes: 25 additions & 22 deletions contracts/validator-manager/PoAValidatorManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,21 @@

pragma solidity 0.8.25;

import {ValidatorManager} from "./ValidatorManager.sol";
import {
ValidatorManagerSettings,
ValidatorRegistrationInput
ValidatorManagerSettings
} from "./interfaces/IValidatorManager.sol";
import {IPoAValidatorManager} from "./interfaces/IPoAValidatorManager.sol";
import {ICMInitializable} from "@utilities/ICMInitializable.sol";
import {OwnableUpgradeable} from
"@openzeppelin/[email protected]/access/OwnableUpgradeable.sol";
import {IACP99SecurityModule} from "./interfaces/IACP99SecurityModule.sol";
import {ACP99ValidatorManager} from "./ACP99ValidatorManager.sol";

/**
* @dev Implementation of the {IPoAValidatorManager} interface.
*
* @custom:security-contact https://github.com/ava-labs/teleporter/blob/main/SECURITY.md
*/
contract PoAValidatorManager is IPoAValidatorManager, ValidatorManager, OwnableUpgradeable {
contract PoAValidatorManager is IACP99SecurityModule, ACP99ValidatorManager, OwnableUpgradeable {
constructor(ICMInitializable init) {
if (init == ICMInitializable.Disallowed) {
_disableInitializers();
Expand All @@ -46,30 +45,34 @@ contract PoAValidatorManager is IPoAValidatorManager, ValidatorManager, OwnableU
// solhint-disable-next-line no-empty-blocks
function __PoAValidatorManager_init_unchained() internal onlyInitializing {}

// solhint-enable func-name-mixedcase

/**
* @notice See {IPoAValidatorManager-initializeValidatorRegistration}.
*/
function initializeValidatorRegistration(
ValidatorRegistrationInput calldata registrationInput,
uint64 weight
) external onlyOwner returns (bytes32 validationID) {
return _initializeValidatorRegistration(registrationInput, weight);
}

// solhint-enable ordering
/**
* @notice See {IPoAValidatorManager-initializeEndValidation}.
*/
function initializeEndValidation(bytes32 validationID) external override onlyOwner {
_initializeEndValidation(validationID);
}

/**
* @notice See {IValidatorManager-completeEndValidation}.
*/
function completeEndValidation(uint32 messageIndex) external {
_completeEndValidation(messageIndex);
function handleInitializeValidatorRegistration(bytes32 validationID, uint64 weight, bytes calldata args) external {
}

function handleCompleteValidatorRegistration(bytes32 validationID) external {
// No-op
}

function handleInitializeEndValidation(bytes32 validationID, bytes calldata args) external {
// No-op
}

function handleCompleteEndValidation(bytes32 validationID) external {
// No-op
}

function handleInitializeValidatorWeightChange(bytes32 validationID, uint64 weight, bytes calldata args) external {
// No-op
}

function handleCompleteValidatorWeightChange(bytes32 validationID, bytes calldata args) external {
// No-op
Comment on lines +56 to +76
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait... shouldn't POA still be able to cycle validators? Maybe I just don't have the full picture

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, these handlers should likely implement checks against the owner address/key. Keep in mind this PR is meant to demonstrate the architectural changes needed to implement ACP-99, so missing features are expected

}
}
Loading