From d5b5b935f841c5766923ec5f31161e8d5c98f42c Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 3 Dec 2024 13:56:03 -0600 Subject: [PATCH] acp99 delegation handling --- .../validator-manager/PoAValidatorManager.sol | 4 +- .../validator-manager/PoSValidatorManager.sol | 106 +++++------------- .../interfaces/IACP99SecurityModule.sol | 6 +- .../interfaces/IPoSValidatorManager.sol | 89 --------------- 4 files changed, 34 insertions(+), 171 deletions(-) diff --git a/contracts/validator-manager/PoAValidatorManager.sol b/contracts/validator-manager/PoAValidatorManager.sol index 22a1b7379..9f786e6a3 100644 --- a/contracts/validator-manager/PoAValidatorManager.sol +++ b/contracts/validator-manager/PoAValidatorManager.sol @@ -70,11 +70,11 @@ contract PoAValidatorManager is IACP99SecurityModule, ACP99ValidatorManager, Own // No-op } - function handleInitializeValidatorWeightChange() external { + function handleInitializeValidatorWeightChange(bytes32 validationID, uint64 weight, bytes calldata args) external { // No-op } - function handleCompleteValidatorWeightChange() external { + function handleCompleteValidatorWeightChange(bytes32 validationID, bytes calldata args) external { // No-op } } diff --git a/contracts/validator-manager/PoSValidatorManager.sol b/contracts/validator-manager/PoSValidatorManager.sol index 29079e7b2..15ba9041b 100644 --- a/contracts/validator-manager/PoSValidatorManager.sol +++ b/contracts/validator-manager/PoSValidatorManager.sol @@ -205,10 +205,31 @@ abstract contract PoSValidatorManager is _completeEndValidation(validationID); } - function handleInitializeValidatorWeightChange() external { + function handleInitializeValidatorWeightChange(bytes32 validationID, uint64 weight, bytes calldata args) external { + (bytes32 delegationID, bytes memory innerArgs) = abi.decode(args, (bytes32, bytes)); + if (_getPoSValidatorManagerStorage()._delegatorStakes[delegationID].status == DelegatorStatus.Unknown) { + address delegatorAddress = abi.decode(innerArgs, (address)); + uint64 delegatorWeight = getValidator(validationID).weight - weight; + _initializeDelegatorRegistration(validationID, delegatorAddress, weightToValue(delegatorWeight)); + } else { + (bool force, bool includeUptimeProof, uint32 messageIndex, address rewardRecipient) = abi.decode(innerArgs, (bool, bool, uint32, address)); + bool success = _initializeEndDelegation(delegationID, includeUptimeProof, messageIndex, rewardRecipient); + if (force) { + return; + } + if (!success) { + revert DelegatorIneligibleForRewards(delegationID); + } + } } - function handleCompleteValidatorWeightChange() external { + function handleCompleteValidatorWeightChange(bytes32, bytes calldata args) external { + (bytes32 delegationID, uint32 messageIndex) = abi.decode(args, (bytes32, uint32)); + if (_getPoSValidatorManagerStorage()._delegatorStakes[delegationID].status == DelegatorStatus.PendingAdded) { + _completeDelegatorRegistration(delegationID, messageIndex); + } else { + _completeEndDelegation(delegationID, messageIndex); + } } /** @@ -536,7 +557,7 @@ abstract contract PoSValidatorManager is /** * @notice See {IPoSValidatorManager-completeDelegatorRegistration}. */ - function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) external { + function _completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) internal { PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); Delegator memory delegator = $._delegatorStakes[delegationID]; @@ -553,7 +574,7 @@ abstract contract PoSValidatorManager is // In the case where the validator has completed its validation period, we can no // longer stake and should move our status directly to completed and return the stake. if (validator.status == ValidatorStatus.Completed) { - return _completeEndDelegation(delegationID); + return _endDelegation(delegationID); } // Unpack the Warp message @@ -583,73 +604,6 @@ abstract contract PoSValidatorManager is }); } - /** - * @notice See {IPoSValidatorManager-initializeEndDelegation}. - */ - function initializeEndDelegation( - bytes32 delegationID, - bool includeUptimeProof, - uint32 messageIndex - ) external { - _initializeEndDelegationWithCheck( - delegationID, includeUptimeProof, messageIndex, address(0) - ); - } - - /** - * @notice See {IPoSValidatorManager-initializeEndDelegation}. - */ - function initializeEndDelegation( - bytes32 delegationID, - bool includeUptimeProof, - uint32 messageIndex, - address rewardRecipient - ) external { - _initializeEndDelegationWithCheck( - delegationID, includeUptimeProof, messageIndex, rewardRecipient - ); - } - - function _initializeEndDelegationWithCheck( - bytes32 delegationID, - bool includeUptimeProof, - uint32 messageIndex, - address rewardRecipient - ) internal { - if ( - !_initializeEndDelegation( - delegationID, includeUptimeProof, messageIndex, rewardRecipient - ) - ) { - revert DelegatorIneligibleForRewards(delegationID); - } - } - - /** - * @notice See {IPoSValidatorManager-forceInitializeEndDelegation}. - */ - function forceInitializeEndDelegation( - bytes32 delegationID, - bool includeUptimeProof, - uint32 messageIndex - ) external { - // Ignore the return value here to force end delegation, regardless of possible missed rewards - _initializeEndDelegation(delegationID, includeUptimeProof, messageIndex, address(0)); - } - - /** - * @notice See {IPoSValidatorManager-forceInitializeEndDelegation}. - */ - function forceInitializeEndDelegation( - bytes32 delegationID, - bool includeUptimeProof, - uint32 messageIndex, - address rewardRecipient - ) external { - // Ignore the return value here to force end delegation, regardless of possible missed rewards - _initializeEndDelegation(delegationID, includeUptimeProof, messageIndex, rewardRecipient); - } - /** * @dev Helper function that initializes the end of a PoS delegation period. * Returns false if it is possible for the delegator to claim rewards, but it is not eligible. @@ -716,7 +670,7 @@ abstract contract PoSValidatorManager is return (reward > 0); } else if (validator.status == ValidatorStatus.Completed) { _calculateAndSetDelegationReward(delegator, rewardRecipient, delegationID); - _completeEndDelegation(delegationID); + _endDelegation(delegationID); // If the validator has completed, then no further uptimes may be submitted, so we always // end the delegation. return true; @@ -803,10 +757,10 @@ abstract contract PoSValidatorManager is /** * @notice See {IPoSValidatorManager-completeEndDelegation}. */ - function completeEndDelegation( + function _completeEndDelegation( bytes32 delegationID, uint32 messageIndex - ) external nonReentrant { + ) internal nonReentrant { PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); Delegator memory delegator = $._delegatorStakes[delegationID]; @@ -836,10 +790,10 @@ abstract contract PoSValidatorManager is } } - _completeEndDelegation(delegationID); + _endDelegation(delegationID); } - function _completeEndDelegation(bytes32 delegationID) internal { + function _endDelegation(bytes32 delegationID) internal { PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); Delegator memory delegator = $._delegatorStakes[delegationID]; diff --git a/contracts/validator-manager/interfaces/IACP99SecurityModule.sol b/contracts/validator-manager/interfaces/IACP99SecurityModule.sol index d5073e034..afc32ed56 100644 --- a/contracts/validator-manager/interfaces/IACP99SecurityModule.sol +++ b/contracts/validator-manager/interfaces/IACP99SecurityModule.sol @@ -6,7 +6,6 @@ pragma solidity 0.8.25; interface IACP99SecurityModule { - // Called by the ValidatorManager on initializeRegisterValidator function handleInitializeValidatorRegistration( bytes32 validationID, uint64 weight, @@ -19,8 +18,7 @@ interface IACP99SecurityModule { function handleCompleteEndValidation(bytes32 validationID) external; - // Called by the ValidatorManager on initializeSetValidatorWeight - function handleInitializeValidatorWeightChange() external; + function handleInitializeValidatorWeightChange(bytes32 validationID, uint64 weight, bytes calldata args) external; - function handleCompleteValidatorWeightChange() external; + function handleCompleteValidatorWeightChange(bytes32 validationID, bytes calldata args) external; } \ No newline at end of file diff --git a/contracts/validator-manager/interfaces/IPoSValidatorManager.sol b/contracts/validator-manager/interfaces/IPoSValidatorManager.sol index 80f03975b..5bb80ff55 100644 --- a/contracts/validator-manager/interfaces/IPoSValidatorManager.sol +++ b/contracts/validator-manager/interfaces/IPoSValidatorManager.sol @@ -134,82 +134,6 @@ interface IPoSValidatorManager is IValidatorManager { */ function submitUptimeProof(bytes32 validationID, uint32 messageIndex) external; - /** - * @notice Completes the delegator registration process by submitting an acknowledgement of the registration of a - * validationID from the P-Chain. After this function is called, the validator's weight is updated in the contract state. - * Any P-Chain acknowledgement with a nonce greater than or equal to the nonce used to initialize registration of the - * delegator is valid, as long as that nonce has been sent by the contract. For the purposes of computing delegation rewards, - * the delegation is considered active after this function is completed. - * Note: Only the specified delegation will be marked as registered, even if the validator weight update - * message implicitly includes multiple weight changes. - * @param delegationID The ID of the delegation being registered. - * @param messageIndex The index of the Warp message to be received providing the acknowledgement. - */ - function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) external; - - /** - * @notice Begins the process of removing a delegator from a validation period, and reverts if the delegation is not eligible for rewards. - * The delegator must have been previously registered with the given validationID. For the purposes of computing delegation rewards, - * the delegation period is considered ended when this function is called. Uses the supplied uptime proof to calculate rewards. - * If none is provided in the call, the latest known uptime will be used. Reverts if the uptime is not eligible for rewards. - * Note: This function can only be called by the address that registered the delegation. - * Note: Reverts if the uptime is not eligible for rewards. - * @param delegationID The ID of the delegation being removed. - * @param includeUptimeProof Whether or not an uptime proof is provided for the validation period. - * If the validator has completed its validation period, it has already provided an uptime proof, so {includeUptimeProof} - * will be ignored and can be set to false. If the validator has not completed its validation period and no uptime proof - * is provided, the latest known uptime will be used. - * @param messageIndex If {includeUptimeProof} is true, the index of the Warp message to be received providing the - * uptime proof. - */ - function initializeEndDelegation( - bytes32 delegationID, - bool includeUptimeProof, - uint32 messageIndex - ) external; - - /** - * @notice See {IPoSValidatorManager-initializeEndDelegation} for details of the first three parameters - * @param recipientAddress The address to receive the rewards. - */ - function initializeEndDelegation( - bytes32 delegationID, - bool includeUptimeProof, - uint32 messageIndex, - address recipientAddress - ) external; - - /** - * @notice Begins the process of removing a delegator from a validation period, but does not revert if the delegation is not eligible for rewards. - * The delegator must have been previously registered with the given validationID. For the purposes of computing delegation rewards, - * the delegation period is considered ended when this function is called. Uses the supplied uptime proof to calculate rewards. - * If none is provided in the call, the latest known uptime will be used. Reverts if the uptime is not eligible for rewards. - * Note: This function can only be called by the address that registered the delegation. - * @param delegationID The ID of the delegation being removed. - * @param includeUptimeProof Whether or not an uptime proof is provided for the validation period. - * If the validator has completed its validation period, it has already provided an uptime proof, so {includeUptimeProof} - * will be ignored and can be set to false. If the validator has not completed its validation period and no uptime proof - * is provided, the latest known uptime will be used. - * @param messageIndex If {includeUptimeProof} is true, the index of the Warp message to be received providing the - * uptime proof. - */ - function forceInitializeEndDelegation( - bytes32 delegationID, - bool includeUptimeProof, - uint32 messageIndex - ) external; - - /** - * @notice See {IPoSValidatorManager-forceInitializeEndDelegation} for details of the first three parameters - * @param recipientAddress The address to receive the rewards. - */ - function forceInitializeEndDelegation( - bytes32 delegationID, - bool includeUptimeProof, - uint32 messageIndex, - address recipientAddress - ) external; - /** * @notice Resubmits a delegator registration or delegator end message to be sent to the P-Chain. * Only necessary if the original message can't be delivered due to validator churn. @@ -217,19 +141,6 @@ interface IPoSValidatorManager is IValidatorManager { */ function resendUpdateDelegation(bytes32 delegationID) external; - /** - * @notice Completes the process of ending a delegation by receiving an acknowledgement from the P-Chain. - * After this function is called, the validator's weight is updated in the contract state. - * Any P-Chain acknowledgement with a nonce greater than or equal to the nonce used to initialize the end of the - * delegator's delegation is valid, as long as that nonce has been sent by the contract. This is because the validator - * weight change pertaining to the delegation ending is included in any subsequent validator weight update messages. - * Note: Only the specified delegation will be marked as completed, even if the validator weight update - * message implicitly includes multiple weight changes. - * @param delegationID The ID of the delegation being removed. - * @param messageIndex The index of the Warp message to be received providing the acknowledgement. - */ - function completeEndDelegation(bytes32 delegationID, uint32 messageIndex) external; - /** * @notice Withdraws the delegation fees from completed delegations to the owner of the validator. * @param validationID The ID of the validation period being ended.