Skip to content

Conversation

@WalidOfNow
Copy link
Contributor

No description provided.

@WalidOfNow WalidOfNow force-pushed the feat/alt-validator-registration branch from 7683ad4 to 37f7a26 Compare October 8, 2024 20:18
@WalidOfNow WalidOfNow marked this pull request as ready for review October 9, 2024 07:11
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;

import { MerkleUtils } from "./MerkleUtils.sol";
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in general, MerkleProof you have less control over the structure of provided proof.

1- MerkleUtils has a merkleize() function to construct a Merkle tree from an array of chunks. which is used for constructing the validator tree hash. It's important that we pass the validator information so we can check them in the sc and contruct the validator tree hash
2- proof verification takes an additional paramter index which helps with partial proofs.
3- not a big reason but we would need to pass a hashing function that uses sha256 for MerkleProof since the default one is keccak256

I am experimenting with the proving logic in general and trying to find a good balance between readability and control of the proofs.

@WalidOfNow WalidOfNow requested a review from bxmmm1 October 21, 2024 06:36
* @param newDelay The new registration delay in seconds.
* @dev Restricted to the DAO
*/
function setRegistrationDelay(uint64 newDelay) external;
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO interface doesn't need to contain functions that are not meant to to be called by public. It adds unnecessary noise and LOC. I vote fore removing functions like this from the Interface and just keeping them + natspec in the contract

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function is callable by DAO. So if our DAO becomes a contract in the future, we would need the interface for it.

Copy link
Contributor

Choose a reason for hiding this comment

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

True, but DAO contracts generally do not import interfaces. They deal with target & calldata. e.g. https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/governance/Governor.sol

* @inheritdoc IUniFiAVSManager
*/
function avsDirectory() external view returns (address) {
return address(AVS_DIRECTORY);
Copy link
Contributor

Choose a reason for hiding this comment

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

Inconsistent getter naming, the previous function is called getRestakeableStrategies and this one just avsDirectory

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this interface is required by EigenLayer. Hence why the naming convention is different.

}

$.slashedOperators[operator].push(
InvalidValidator({ slashingBeneficiary: msg.sender, blsPubKeyHash: blsPubKeyHash })
Copy link
Contributor

Choose a reason for hiding this comment

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

slashingBeneficiary naming is bad, how can somebody benefit from being slashed? :D maybe use slashedOperator?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

slashingBeneficiary is the person calling the slashing function. which is the person getting reward.

error BeaconBlockProofForProposerIndex();

function verifyValidatorExistence(InclusionProof memory inclusionProof) internal returns (bool) {
(, bytes32 beaconBlockRoot) = getRootFromTimestamp(inclusionProof.timestamp);
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be moved down in this function after the 2 proof checks to save on some gas in case of bad proof

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good call! although this would revert the outer call so the whole transaction should be reverting. But I think it's good to add it in case we use this in another place.

@WalidOfNow WalidOfNow requested a review from bxmmm1 October 29, 2024 20:27
function setDeregistrationDelay(uint64 newDelay) external restricted {
_setDeregistrationDelay(newDelay);
}

Choose a reason for hiding this comment

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

If an operator calls setOperatorCommitment multiple times before updateOperatorCommitment, earlier pending commitments are overwritten without any checks, so is this expected?

}

ValidatorRegistrationData storage validatorRegistrationData = $.validatorRegistrations[storedBlsPubKeyHash];
if (proof.timestamp < validatorRegistrationData.registeredAt || proof.timestamp > validator.registeredUntil) {

Choose a reason for hiding this comment

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

proof timestamp validation doesn't account for block.timestamp vs block.number inconsistencies, so may allow proofs from future blocks to be valid. can add checks for those also

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants