Skip to content

Commit

Permalink
Remove reverts from validators checker (#94)
Browse files Browse the repository at this point in the history
* Remove reverts from validators checker

* Fix function name
  • Loading branch information
tsudmi authored Jun 28, 2024
1 parent 4b544b0 commit d643271
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 159 deletions.
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

0 comments on commit d643271

Please sign in to comment.