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

Remove reverts from validators checker #94

Merged
merged 2 commits into from
Jun 28, 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
14 changes: 12 additions & 2 deletions abi/IValidatorsChecker.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,13 @@
"outputs": [
{
"internalType": "uint256",
"name": "",
"name": "blockNumber",
"type": "uint256"
},
{
"internalType": "enum IValidatorsChecker.Status",
"name": "status",
"type": "uint8"
}
],
"stateMutability": "view",
Expand Down Expand Up @@ -70,8 +75,13 @@
"outputs": [
{
"internalType": "uint256",
"name": "",
"name": "blockNumber",
"type": "uint256"
},
{
"internalType": "enum IValidatorsChecker.Status",
"name": "status",
"type": "uint8"
}
],
"stateMutability": "view",
Expand Down
22 changes: 18 additions & 4 deletions contracts/interfaces/IValidatorsChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,33 @@ pragma solidity ^0.8.22;
* @notice Defines the interface for ValidatorsChecker
*/
interface IValidatorsChecker {
enum Status {
SUCCEEDED,
INVALID_VALIDATORS_REGISTRY_ROOT,
INVALID_VAULT,
INSUFFICIENT_ASSETS,
INVALID_SIGNATURE,
INVALID_VALIDATORS_MANAGER,
INVALID_VALIDATORS_COUNT,
INVALID_VALIDATORS_LENGTH,
INVALID_PROOF
}

/**
* @notice Function for checking validators manager signature
* @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
* @param signature The validators manager signature
* @return Current block number
* @return blockNumber Current block number
* @return status The status of the verification
*/
function checkValidatorsManagerSignature(
address vault,
bytes32 validatorsRegistryRoot,
bytes calldata validators,
bytes calldata signature
) external view returns (uint256);
) external view returns (uint256 blockNumber, Status status);

/**
* @notice Function for checking deposit data root
Expand All @@ -31,7 +44,8 @@ interface IValidatorsChecker {
* @param proof The proof used for the merkle tree verification
* @param proofFlags The multi proof flags for the merkle tree verification
* @param proofIndexes The indexes of the leaves for the merkle tree multi proof verification
* @return Current block number
* @return blockNumber Current block number
* @return status The status of the verification
*/
function checkDepositDataRoot(
address vault,
Expand All @@ -40,5 +54,5 @@ interface IValidatorsChecker {
bytes32[] calldata proof,
bool[] calldata proofFlags,
uint256[] calldata proofIndexes
) external view returns (uint256);
) external view returns (uint256 blockNumber, Status status);
}
38 changes: 23 additions & 15 deletions contracts/validators/ValidatorsChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,19 @@ abstract contract ValidatorsChecker is IValidatorsChecker {
bytes32 validatorsRegistryRoot,
bytes calldata validators,
bytes calldata signature
) external view override returns (uint256) {
) external view override returns (uint256 blockNumber, Status status) {
if (_validatorsRegistry.get_deposit_root() != validatorsRegistryRoot) {
revert Errors.InvalidValidatorsRegistryRoot();
return (block.number, Status.INVALID_VALIDATORS_REGISTRY_ROOT);
}
if (!_vaultsRegistry.vaults(vault) || IVaultVersion(vault).version() < 2) {
revert Errors.InvalidVault();
return (block.number, Status.INVALID_VAULT);
}

// verify vault has enough assets
if (
!_keeper.isCollateralized(vault) && IVaultState(vault).withdrawableAssets() < _depositAmount()
) {
revert Errors.InsufficientAssets();
return (block.number, Status.INSUFFICIENT_ASSETS);
}

// compose signing message
Expand All @@ -87,10 +87,10 @@ abstract contract ValidatorsChecker is IValidatorsChecker {
signature
)
) {
revert Errors.AccessDenied();
return (block.number, Status.INVALID_SIGNATURE);
}

return block.number;
return (block.number, Status.SUCCEEDED);
}

/// @inheritdoc IValidatorsChecker
Expand All @@ -101,25 +101,29 @@ abstract contract ValidatorsChecker is IValidatorsChecker {
bytes32[] calldata proof,
bool[] calldata proofFlags,
uint256[] calldata proofIndexes
) external view override returns (uint256) {
) external view override returns (uint256 blockNumber, Status status) {
if (_validatorsRegistry.get_deposit_root() != validatorsRegistryRoot) {
revert Errors.InvalidValidatorsRegistryRoot();
return (block.number, Status.INVALID_VALIDATORS_REGISTRY_ROOT);
}
if (!_vaultsRegistry.vaults(vault)) {
return (block.number, Status.INVALID_VAULT);
}
if (!_vaultsRegistry.vaults(vault)) revert Errors.InvalidVault();

// verify vault has enough assets
if (
!_keeper.isCollateralized(vault) && IVaultState(vault).withdrawableAssets() < _depositAmount()
) {
revert Errors.InsufficientAssets();
return (block.number, Status.INSUFFICIENT_ASSETS);
}

uint8 vaultVersion = IVaultVersion(vault).version();
if (vaultVersion >= 2) {
address validatorsManager = IVaultValidators(vault).validatorsManager();

// verify vault did not set custom validators manager
if (validatorsManager != address(_depositDataRegistry)) revert Errors.AccessDenied();
if (validatorsManager != address(_depositDataRegistry)) {
return (block.number, Status.INVALID_VALIDATORS_MANAGER);
}
}

uint256 currentIndex;
Expand All @@ -135,12 +139,16 @@ abstract contract ValidatorsChecker is IValidatorsChecker {

// define leaves for multiproof
uint256 validatorsCount = proofIndexes.length;
if (validatorsCount == 0) revert Errors.InvalidValidators();
if (validatorsCount == 0) {
return (block.number, Status.INVALID_VALIDATORS_COUNT);
}
bytes32[] memory leaves = new bytes32[](validatorsCount);

// calculate validator length
uint256 validatorLength = validators.length / validatorsCount;
if (validatorLength == 0) revert Errors.InvalidValidators();
if (validatorLength == 0 || validatorsCount * validatorLength != validators.length) {
return (block.number, Status.INVALID_VALIDATORS_LENGTH);
}

// calculate leaves
{
Expand All @@ -163,10 +171,10 @@ abstract contract ValidatorsChecker is IValidatorsChecker {

// check matches merkle root and next validator index
if (!MerkleProof.multiProofVerifyCalldata(proof, proofFlags, depositDataRoot, leaves)) {
revert Errors.InvalidProof();
return (block.number, Status.INVALID_PROOF);
}

return block.number;
return (block.number, Status.SUCCEEDED);
}

/**
Expand Down
Loading
Loading