Skip to content

Commit

Permalink
Replace signature with vault validators signature
Browse files Browse the repository at this point in the history
  • Loading branch information
tsudmi committed Jun 10, 2024
1 parent 2784e62 commit 2cad8df
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 172 deletions.
51 changes: 1 addition & 50 deletions abi/IValidatorsChecker.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
[
{
"anonymous": false,
"inputs": [],
"name": "EIP712DomainChanged",
"type": "event"
},
{
"inputs": [
{
Expand Down Expand Up @@ -63,7 +57,7 @@
},
{
"internalType": "bytes",
"name": "publicKeys",
"name": "validators",
"type": "bytes"
},
{
Expand All @@ -82,48 +76,5 @@
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "eip712Domain",
"outputs": [
{
"internalType": "bytes1",
"name": "fields",
"type": "bytes1"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "version",
"type": "string"
},
{
"internalType": "uint256",
"name": "chainId",
"type": "uint256"
},
{
"internalType": "address",
"name": "verifyingContract",
"type": "address"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "uint256[]",
"name": "extensions",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
}
]
8 changes: 3 additions & 5 deletions contracts/interfaces/IValidatorsChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,24 @@

pragma solidity =0.8.22;

import {IERC5267} from '@openzeppelin/contracts/interfaces/IERC5267.sol';

/**
* @title IValidatorsChecker
* @author StakeWise
* @notice Defines the interface for ValidatorsChecker
*/
interface IValidatorsChecker is IERC5267 {
interface IValidatorsChecker {
/**
* @notice Function for checking validators manager signature
* @param vault The address of the vault
* @param validatorsRegistryRoot The validators registry root
* @param publicKeys The concatenation of the validators' public keys
* @param validators The concatenation of the validators' public key, deposit signature, deposit root and optionally withdrawal address
* @param signature The validators manager signature
* @return Current block number
*/
function checkValidatorsManagerSignature(
address vault,
bytes32 validatorsRegistryRoot,
bytes calldata publicKeys,
bytes calldata validators,
bytes calldata signature
) external view returns (uint256);

Expand Down
18 changes: 2 additions & 16 deletions contracts/validators/EthValidatorsChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@

pragma solidity =0.8.22;

import {EIP712} from '@openzeppelin/contracts/utils/cryptography/EIP712.sol';
import {IValidatorsRegistry} from '../interfaces/IValidatorsRegistry.sol';
import {IKeeper} from '../interfaces/IKeeper.sol';
import {IDepositDataRegistry} from '../interfaces/IDepositDataRegistry.sol';
import {IVaultsRegistry} from '../interfaces/IVaultsRegistry.sol';
import {ValidatorsChecker} from './ValidatorsChecker.sol';

/**
Expand All @@ -27,18 +22,9 @@ contract EthValidatorsChecker is ValidatorsChecker {
address keeper,
address vaultsRegistry,
address depositDataRegistry
)
ValidatorsChecker(validatorsRegistry, keeper, vaultsRegistry, depositDataRegistry)
EIP712('EthValidatorsChecker', '1')
{}

function _validatorsManagerSignatureTypeHash() internal pure override returns (bytes32) {
return
keccak256(
'EthValidatorsChecker(bytes32 validatorsRegistryRoot,address vault,bytes validators)'
);
}
) ValidatorsChecker(validatorsRegistry, keeper, vaultsRegistry, depositDataRegistry) {}

/// @inheritdoc ValidatorsChecker
function _depositAmount() internal pure override returns (uint256) {
return 32 ether;
}
Expand Down
18 changes: 2 additions & 16 deletions contracts/validators/GnoValidatorsChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@

pragma solidity =0.8.22;

import {EIP712} from '@openzeppelin/contracts/utils/cryptography/EIP712.sol';
import {IValidatorsRegistry} from '../interfaces/IValidatorsRegistry.sol';
import {IKeeper} from '../interfaces/IKeeper.sol';
import {IDepositDataRegistry} from '../interfaces/IDepositDataRegistry.sol';
import {IVaultsRegistry} from '../interfaces/IVaultsRegistry.sol';
import {ValidatorsChecker} from './ValidatorsChecker.sol';

/**
Expand All @@ -27,18 +22,9 @@ contract GnoValidatorsChecker is ValidatorsChecker {
address keeper,
address vaultsRegistry,
address depositDataRegistry
)
ValidatorsChecker(validatorsRegistry, keeper, vaultsRegistry, depositDataRegistry)
EIP712('GnoValidatorsChecker', '1')
{}

function _validatorsManagerSignatureTypeHash() internal pure override returns (bytes32) {
return
keccak256(
'GnoValidatorsChecker(bytes32 validatorsRegistryRoot,address vault,bytes validators)'
);
}
) ValidatorsChecker(validatorsRegistry, keeper, vaultsRegistry, depositDataRegistry) {}

/// @inheritdoc ValidatorsChecker
function _depositAmount() internal pure override returns (uint256) {
return 1 ether;
}
Expand Down
79 changes: 62 additions & 17 deletions contracts/validators/ValidatorsChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
pragma solidity =0.8.22;

import {MerkleProof} from '@openzeppelin/contracts/utils/cryptography/MerkleProof.sol';
import {ECDSA} from '@openzeppelin/contracts/utils/cryptography/ECDSA.sol';
import {EIP712} from '@openzeppelin/contracts/utils/cryptography/EIP712.sol';
import {MessageHashUtils} from '@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol';
import {SignatureChecker} from '@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol';
import {IValidatorsRegistry} from '../interfaces/IValidatorsRegistry.sol';
import {IKeeper} from '../interfaces/IKeeper.sol';
import {IValidatorsChecker} from '../interfaces/IValidatorsChecker.sol';
Expand All @@ -27,7 +27,10 @@ interface IVaultValidatorsV1 {
* * checking validators manager signature
* * checking deposit data root
*/
abstract contract ValidatorsChecker is IValidatorsChecker, EIP712 {
abstract contract ValidatorsChecker is IValidatorsChecker {
bytes32 private constant _registerValidatorsTypeHash =
keccak256('VaultValidators(bytes32 validatorsRegistryRoot,bytes validators)');

IValidatorsRegistry private immutable _validatorsRegistry;
IKeeper private immutable _keeper;
IVaultsRegistry private immutable _vaultsRegistry;
Expand Down Expand Up @@ -56,7 +59,7 @@ abstract contract ValidatorsChecker is IValidatorsChecker, EIP712 {
function checkValidatorsManagerSignature(
address vault,
bytes32 validatorsRegistryRoot,
bytes calldata publicKeys,
bytes calldata validators,
bytes calldata signature
) external view override returns (uint256) {
if (_validatorsRegistry.get_deposit_root() != validatorsRegistryRoot) {
Expand All @@ -74,20 +77,18 @@ abstract contract ValidatorsChecker is IValidatorsChecker, EIP712 {
}

// compose signing message
bytes32 message = keccak256(
abi.encode(
_validatorsManagerSignatureTypeHash(),
validatorsRegistryRoot,
vault,
keccak256(publicKeys)
)
);
bytes32 digest = _hashTypedDataV4(message);

address signer = ECDSA.recover(digest, signature);
bytes32 message = _getValidatorsManagerMessageHash(vault, validatorsRegistryRoot, validators);

// verify validators manager ECDSA signature
if (IVaultValidators(vault).validatorsManager() != signer) revert Errors.AccessDenied();
if (
!SignatureChecker.isValidSignatureNow(
IVaultValidators(vault).validatorsManager(),
message,
signature
)
) {
revert Errors.AccessDenied();
}

return block.number;
}
Expand Down Expand Up @@ -168,7 +169,51 @@ abstract contract ValidatorsChecker is IValidatorsChecker, EIP712 {
return block.number;
}

function _validatorsManagerSignatureTypeHash() internal pure virtual returns (bytes32);
/**
* @notice Get the hash to be signed by the validators manager
* @param vault The address of the vault
* @param validatorsRegistryRoot The validators registry root
* @param validators The concatenation of the validators' public key, deposit signature, deposit root and optionally withdrawal address
* @return The hash to be signed by the validators manager
*/
function _getValidatorsManagerMessageHash(
address vault,
bytes32 validatorsRegistryRoot,
bytes calldata validators
) private view returns (bytes32) {
bytes32 domainSeparator = _computeVaultValidatorsDomain(vault);
return
MessageHashUtils.toTypedDataHash(
domainSeparator,
keccak256(
abi.encode(_registerValidatorsTypeHash, validatorsRegistryRoot, keccak256(validators))
)
);
}

/**
* @notice Computes the hash of the EIP712 typed data for the vault
* @dev This function is used to compute the hash of the EIP712 typed data
* @return The hash of the EIP712 typed data
*/
function _computeVaultValidatorsDomain(address vault) private view returns (bytes32) {
return
keccak256(
abi.encode(
keccak256(
'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'
),
keccak256(bytes('VaultValidators')),
keccak256('1'),
block.chainid,
vault
)
);
}

/**
* @notice Get the amount of assets required for validator deposit
* @return The amount of assets required for deposit
*/
function _depositAmount() internal pure virtual returns (uint256);
}
17 changes: 11 additions & 6 deletions tasks/eth-full-deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,17 @@ task('eth-full-deploy', 'deploys StakeWise V3 for Ethereum').setAction(async (ta
const depositDataRegistryAddress = await depositDataRegistry.getAddress()

// Deploy ValidatorsChecker
const ethValidatorsChecker = await deployContract(hre, 'EthValidatorsChecker', [
networkConfig.validatorsRegistry,
keeperAddress,
vaultsRegistryAddress,
depositDataRegistryAddress,
])
const ethValidatorsChecker = await deployContract(
hre,
'EthValidatorsChecker',
[
networkConfig.validatorsRegistry,
keeperAddress,
vaultsRegistryAddress,
depositDataRegistryAddress,
],
'contracts/validators/EthValidatorsChecker.sol:EthValidatorsChecker'
)
const ethValidatorsCheckerAddress = await ethValidatorsChecker.getAddress()

const factories: string[] = []
Expand Down
15 changes: 15 additions & 0 deletions tasks/eth-upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,26 @@ task('eth-upgrade', 'upgrades StakeWise V3 for Ethereum').setAction(async (taskA
)
const rewardSplitterFactoryAddress = await rewardSplitterFactory.getAddress()

// Deploy ValidatorsChecker
const ethValidatorsChecker = await deployContract(
hre,
'EthValidatorsChecker',
[
networkConfig.validatorsRegistry,
keeperAddress,
vaultsRegistryAddress,
depositDataRegistryAddress,
],
'contracts/validators/EthValidatorsChecker.sol:EthValidatorsChecker'
)
const ethValidatorsCheckerAddress = await ethValidatorsChecker.getAddress()

// Save the addresses
const addresses = {
VaultsRegistry: vaultsRegistryAddress,
Keeper: keeperAddress,
DepositDataRegistry: depositDataRegistryAddress,
EthValidatorsChecker: ethValidatorsCheckerAddress,
EthGenesisVault: genesisVaultAddress,
EthVaultFactory: factories[0],
EthPrivVaultFactory: factories[1],
Expand Down
17 changes: 11 additions & 6 deletions tasks/gno-full-deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,17 @@ task('gno-full-deploy', 'deploys StakeWise V3 for Gnosis').setAction(async (task
const depositDataRegistryAddress = await depositDataRegistry.getAddress()

// Deploy ValidatorsChecker
const gnoValidatorsChecker = await deployContract(hre, 'GnoValidatorsChecker', [
networkConfig.validatorsRegistry,
keeperAddress,
vaultsRegistryAddress,
depositDataRegistryAddress,
])
const gnoValidatorsChecker = await deployContract(
hre,
'GnoValidatorsChecker',
[
networkConfig.validatorsRegistry,
keeperAddress,
vaultsRegistryAddress,
depositDataRegistryAddress,
],
'contracts/validators/GnoValidatorsChecker.sol:GnoValidatorsChecker'
)
const gnoValidatorsCheckerAddress = await gnoValidatorsChecker.getAddress()

// Deploy XdaiExchange implementation
Expand Down
Loading

0 comments on commit 2cad8df

Please sign in to comment.