diff --git a/src/eigenlayer-avs/EigenLayerMiddleware.sol b/src/eigenlayer-avs/EigenLayerMiddleware.sol index e154b29..5a7d419 100644 --- a/src/eigenlayer-avs/EigenLayerMiddleware.sol +++ b/src/eigenlayer-avs/EigenLayerMiddleware.sol @@ -93,6 +93,22 @@ contract EigenLayerMiddleware is /// @notice Thrown when a function requiring the rewards handler is called but it's not set error RewardsHandlerNotSet(); + event RewardsInitiatorSet(address indexed oldInitiator, address indexed newInitiator); + event ValidatorsRegistered( + address indexed operator, bytes32 indexed registrationRoot + ); + event ValidatorsUnregistered( + address indexed operator, bytes32 indexed registrationRoot + ); + event DelegationsBatchSet( + address indexed operator, bytes32 indexed registrationRoot, uint256 count + ); + event SlasherOptedIn( + address indexed operator, + bytes32 indexed registrationRoot, + address indexed delegatee + ); + // ============================================================================================== // ================================= MODIFIERS ================================================= // ============================================================================================== @@ -236,9 +252,12 @@ contract EigenLayerMiddleware is EigenLayerMiddlewareLib .OperatorIsNotYetRegisteredInValidatorOperatorSet(); } - return EigenLayerMiddlewareLib.registerValidators( + bytes32 registrationRoot = EigenLayerMiddlewareLib.registerValidators( REGISTRY, registrations, REGISTRATION_MIN_COLLATERAL ); + + emit ValidatorsRegistered(msg.sender, registrationRoot); + return registrationRoot; } /// @notice Executes slashing for an operator through the EigenLayer allocation manager @@ -272,6 +291,8 @@ contract EigenLayerMiddleware is delete operatorDelegations[msg.sender][registrationRoot]; operatorRegistrationRoots[msg.sender].remove(registrationRoot); EigenLayerMiddlewareLib.unregisterValidators(REGISTRY, registrationRoot); + + emit ValidatorsUnregistered(msg.sender, registrationRoot); } /// @notice Updates delegations for validators under a registration root @@ -295,6 +316,8 @@ contract EigenLayerMiddleware is pubkeys, delegations ); + + emit DelegationsBatchSet(msg.sender, registrationRoot, pubkeys.length); } /// @notice Creates an operator set with the given strategies @@ -385,6 +408,8 @@ contract EigenLayerMiddleware is address(msg.sender), params ); + + emit SlasherOptedIn(msg.sender, registrationRoot, delegateeAddress); } /// @notice Processes a reward claim from the rewards merkle tree @@ -677,7 +702,9 @@ contract EigenLayerMiddleware is /// @notice Internal function to set the rewards initiator /// @param newRewardsInitiator Address of the new rewards initiator function _setRewardsInitiator(address newRewardsInitiator) internal { + address oldInitiator = REWARD_INITIATOR; REWARD_INITIATOR = newRewardsInitiator; + emit RewardsInitiatorSet(oldInitiator, newRewardsInitiator); } /// @notice Constructs delegation parameters diff --git a/src/interfaces/ITaiyiRegistryCoordinator.sol b/src/interfaces/ITaiyiRegistryCoordinator.sol index 400bc53..98881a4 100644 --- a/src/interfaces/ITaiyiRegistryCoordinator.sol +++ b/src/interfaces/ITaiyiRegistryCoordinator.sol @@ -98,20 +98,6 @@ interface ITaiyiRegistryCoordinator { RestakingProtocol restakingProtocol, address newMiddleware ); - /// @notice Emitted when an allocation query is performed - /// @param operator The operator queried - /// @param operatorSetId The operator set ID - /// @param strategy The strategy address - /// @param amount The allocation amount - /// @param reason A description of the allocation status - event OperatorAllocationQuery( - address indexed operator, - uint96 indexed operatorSetId, - address indexed strategy, - uint256 amount, - string reason - ); - /// @notice Emitted when an operator's socket is updated /// @param operatorId The operator's unique identifier /// @param socket The new socket value diff --git a/src/operator-registries/TaiyiRegistryCoordinator.sol b/src/operator-registries/TaiyiRegistryCoordinator.sol index 72ddc53..db9b720 100644 --- a/src/operator-registries/TaiyiRegistryCoordinator.sol +++ b/src/operator-registries/TaiyiRegistryCoordinator.sol @@ -69,6 +69,28 @@ contract TaiyiRegistryCoordinator is using SafeCast96To32Lib for uint96[]; using SafeCast96To32Lib for uint32[]; + // ============================================================================================== + // ================================= EVENTS ================================================= + // ============================================================================================== + event OperatorRegistered( + address indexed operator, bytes32 indexed operatorId, uint32[] linglongSubsetIds + ); + event OperatorDeregistered( + address indexed operator, bytes32 indexed operatorId, uint32[] linglongSubsetIds + ); + event OperatorStatusChanged( + address indexed operator, OperatorStatus previousStatus, OperatorStatus newStatus + ); + event LinglongSubsetCreated(uint32 indexed linglongSubsetId, uint256 minStake); + event OperatorAddedToSubset( + address indexed operator, uint32 indexed linglongSubsetId + ); + event OperatorRemovedFromSubset( + address indexed operator, uint32 indexed linglongSubsetId + ); + event SocketRegistryUpdated(address indexed oldRegistry, address indexed newRegistry); + event PubkeyRegistryUpdated(address indexed oldRegistry, address indexed newRegistry); + // ============================================================================================== // ================================= MODIFIERS ================================================= // ============================================================================================== @@ -215,6 +237,7 @@ contract TaiyiRegistryCoordinator is onlyMiddleware { _linglongSubsets.createLinglongSubset(linglongSubsetId, minStake); + emit LinglongSubsetCreated(linglongSubsetId, minStake); } // ============================================================================================== @@ -225,14 +248,18 @@ contract TaiyiRegistryCoordinator is /// @param _socketRegistry New socket registry address function updateSocketRegistry(address _socketRegistry) external onlyOwner { require(_socketRegistry != address(0), "Socket registry cannot be zero address"); + address oldRegistry = address(socketRegistry); socketRegistry = ISocketRegistry(_socketRegistry); + emit SocketRegistryUpdated(oldRegistry, _socketRegistry); } /// @notice Updates the pubkey registry address /// @param _pubkeyRegistry New pubkey registry address function updatePubkeyRegistry(address _pubkeyRegistry) external onlyOwner { require(_pubkeyRegistry != address(0), "Pubkey registry cannot be zero address"); + address oldRegistry = address(pubkeyRegistry); pubkeyRegistry = IPubkeyRegistry(_pubkeyRegistry); + emit PubkeyRegistryUpdated(oldRegistry, _pubkeyRegistry); } /// @notice Sets the protocol type for a middleware address @@ -465,39 +492,19 @@ contract TaiyiRegistryCoordinator is address strategyAddress = address(strategy); if (collateralTokens.length == 0) { - emit OperatorAllocationQuery( - operator, linglongSubsetId, address(strategy), 0, "No collaterals found" - ); return 0; } for (uint256 i = 0; i < collateralTokens.length; i++) { if (collateralTokens[i] == strategyAddress) { if (stakedAmounts[i] > 0) { - emit OperatorAllocationQuery( - operator, - linglongSubsetId, - address(strategy), - stakedAmounts[i], - "Allocation found" - ); return stakedAmounts[i]; } else { - emit OperatorAllocationQuery( - operator, - linglongSubsetId, - address(strategy), - 0, - "Zero allocation" - ); return 0; } } } - emit OperatorAllocationQuery( - operator, linglongSubsetId, address(strategy), 0, "Strategy not found" - ); return 0; } @@ -519,17 +526,6 @@ contract TaiyiRegistryCoordinator is OperatorSet({ avs: eigenLayerMiddleware, id: linglongSubsetId }); IAllocationManagerTypes.Allocation memory allocation = allocationManager.getAllocation(operator, operatorSet, strategy); - - emit OperatorAllocationQuery( - operator, - linglongSubsetId, - address(strategy), - allocation.currentMagnitude, - allocation.effectBlock >= block.number - ? "Confirmed allocation" - : "Unconfirmed allocation" - ); - return allocation.currentMagnitude; } @@ -672,6 +668,7 @@ contract TaiyiRegistryCoordinator is internal { OperatorInfo storage operatorInfo = _operatorInfo[operator]; + OperatorStatus previousStatus = operatorInfo.status; bool operatorRegisteredBefore = _operatorInfo[operator].status == OperatorStatus.REGISTERED; @@ -708,6 +705,14 @@ contract TaiyiRegistryCoordinator is } _linglongSubsets.addOperatorToLinglongSubsets(_linglongSubsetIds, operator); + + // Emit registration event + emit OperatorRegistered(operator, operatorId, _linglongSubsetIds); + + // Emit events for each subset the operator was added to + for (uint256 i = 0; i < _linglongSubsetIds.length; i++) { + emit OperatorAddedToSubset(operator, _linglongSubsetIds[i]); + } } /// @notice Deregisters an operator from the EigenLayer protocol @@ -723,6 +728,9 @@ contract TaiyiRegistryCoordinator is OperatorInfo storage operatorInfo = _operatorInfo[operator]; require(operatorInfo.status == OperatorStatus.REGISTERED, OperatorNotRegistered()); + OperatorStatus previousStatus = operatorInfo.status; + bytes32 operatorId = operatorInfo.operatorId; + for (uint256 i = 0; i < _linglongSubsetIds.length; i++) { require( OperatorSubsetLib.isEigenlayerProtocolID(_linglongSubsetIds[i]), @@ -731,6 +739,12 @@ contract TaiyiRegistryCoordinator is } _linglongSubsets.removeOperatorFromLinglongSubsets(_linglongSubsetIds, operator); + + // Emit events for each subset the operator was removed from + for (uint256 i = 0; i < _linglongSubsetIds.length; i++) { + emit OperatorRemovedFromSubset(operator, _linglongSubsetIds[i]); + } + // Check if the operator is still in any Linglong subset bool stillInAnySubset = false; uint256[] memory allSubsetIds = _linglongSubsets.linglongSubsetIds.values(); @@ -745,7 +759,12 @@ contract TaiyiRegistryCoordinator is // Only set status to DEREGISTERED if not in any subset if (!stillInAnySubset) { operatorInfo.status = OperatorStatus.DEREGISTERED; + emit OperatorStatusChanged( + operator, previousStatus, OperatorStatus.DEREGISTERED + ); } + + emit OperatorDeregistered(operator, operatorId, _linglongSubsetIds); } /// @notice Registers an operator for the Symbiotic protocol @@ -758,11 +777,14 @@ contract TaiyiRegistryCoordinator is internal { OperatorInfo storage operatorInfo = _operatorInfo[operator]; + OperatorStatus previousStatus = operatorInfo.status; require( operatorInfo.status != OperatorStatus.REGISTERED, OperatorAlreadyRegistered() ); _operatorInfo[operator].status = OperatorStatus.REGISTERED; + emit OperatorStatusChanged(operator, previousStatus, OperatorStatus.REGISTERED); + for (uint256 i = 0; i < linglongSubsetIds.length; i++) { require( OperatorSubsetLib.isSymbioticProtocolID(linglongSubsetIds[i]), @@ -771,6 +793,14 @@ contract TaiyiRegistryCoordinator is } _linglongSubsets.addOperatorToLinglongSubsets(linglongSubsetIds, operator); + + // Emit registration event + emit OperatorRegistered(operator, operatorInfo.operatorId, linglongSubsetIds); + + // Emit events for each subset the operator was added to + for (uint256 i = 0; i < linglongSubsetIds.length; i++) { + emit OperatorAddedToSubset(operator, linglongSubsetIds[i]); + } } /// @notice Deregisters an operator from the Symbiotic protocol @@ -779,12 +809,20 @@ contract TaiyiRegistryCoordinator is OperatorInfo storage operatorInfo = _operatorInfo[operator]; require(operatorInfo.status == OperatorStatus.REGISTERED, OperatorNotRegistered()); + OperatorStatus previousStatus = operatorInfo.status; + bytes32 operatorId = operatorInfo.operatorId; + uint32[] memory linglongSubsetIds = new uint32[](2); linglongSubsetIds[0] = OperatorSubsetLib.SYMBIOTIC_VALIDATOR_SUBSET_ID; linglongSubsetIds[1] = OperatorSubsetLib.SYMBIOTIC_UNDERWRITER_SUBSET_ID; _linglongSubsets.removeOperatorFromLinglongSubsets(linglongSubsetIds, operator); + // Emit events for each subset the operator was removed from + for (uint256 i = 0; i < linglongSubsetIds.length; i++) { + emit OperatorRemovedFromSubset(operator, linglongSubsetIds[i]); + } + // Check if the operator is still in any Linglong subset bool stillInAnySubset = false; uint256[] memory allSubsetIds = _linglongSubsets.linglongSubsetIds.values(); @@ -799,7 +837,12 @@ contract TaiyiRegistryCoordinator is // Only set status to DEREGISTERED if not in any subset if (!stillInAnySubset) { operatorInfo.status = OperatorStatus.DEREGISTERED; + emit OperatorStatusChanged( + operator, previousStatus, OperatorStatus.DEREGISTERED + ); } + + emit OperatorDeregistered(operator, operatorId, linglongSubsetIds); } /// @notice Checks the initial EigenLayer stake for an operator diff --git a/src/taiyi/TaiyiCore.sol b/src/taiyi/TaiyiCore.sol index 4b33d07..529c64f 100644 --- a/src/taiyi/TaiyiCore.sol +++ b/src/taiyi/TaiyiCore.sol @@ -39,7 +39,9 @@ contract TaiyiCore is event Exhausted(address indexed preconfer, uint256 amount); event TipCollected(uint256 amount, bytes32 preconfRequestHash); - event TransactionExecutionFailed(address to, uint256 value); + event PreconfRequestExecuted(bytes32 indexed preconfRequestHash, uint256 tipAmount); + event TipReceived(bytes32 indexed preconfRequestHash, uint256 amount); + event EthSponsored(address indexed recipient, uint256 amount); /////////////////////////////////////////////////////////////// /// CONSTRUCTOR @@ -150,6 +152,7 @@ contract TaiyiCore is for (uint256 i = 0; i < recipients.length; i++) { (bool success,) = recipients[i].call{ value: amounts[i] }(""); require(success, "ETH transfer failed"); + emit EthSponsored(recipients[i], amounts[i]); } } @@ -206,6 +209,7 @@ contract TaiyiCore is /// @param preconfRequestHash The hash of the PreconfRequest function _handlePayment(uint256 amount, bytes32 preconfRequestHash) internal { preconferTips[preconfRequestHash] += amount; + emit TipReceived(preconfRequestHash, amount); } /// @notice Processes and validates a tip payment for a preconfirmation request @@ -223,11 +227,13 @@ contract TaiyiCore is _validatePreconfRequestBType(preconfRequestBType); uint256 amount = payout(preconfRequestBType.blockspaceAllocation, true); - _handlePayment(amount, preconfRequestBType.getPreconfRequestBTypeHash()); + bytes32 requestHash = preconfRequestBType.getPreconfRequestBTypeHash(); + _handlePayment(amount, requestHash); - preconfRequestStatus[preconfRequestBType.getPreconfRequestBTypeHash()] = - PreconfRequestStatus.Executed; - inclusionStatusMap[preconfRequestBType.getPreconfRequestBTypeHash()] = true; + preconfRequestStatus[requestHash] = PreconfRequestStatus.Executed; + inclusionStatusMap[requestHash] = true; + + emit PreconfRequestExecuted(requestHash, amount); } /// @notice Exhausts a preconfirmation request by burning gas and handling payment diff --git a/src/taiyi/TaiyiEscrow.sol b/src/taiyi/TaiyiEscrow.sol index a46b90a..b6fd416 100644 --- a/src/taiyi/TaiyiEscrow.sol +++ b/src/taiyi/TaiyiEscrow.sol @@ -111,5 +111,6 @@ abstract contract TaiyiEscrow is : blockspaceAllocation.deposit; require(balances[blockspaceAllocation.sender] >= amount, "Insufficient balance"); balances[blockspaceAllocation.sender] -= amount; + emit PaymentMade(blockspaceAllocation.sender, amount, isAfterExec); } }