Merge branch 'main' into fix/dont-pop-slash-on-failure

This commit is contained in:
Gonza Montiel 2026-01-22 18:22:33 -03:00 committed by GitHub
commit 3eea9ec305
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 665 additions and 622 deletions

View file

@ -1 +1 @@
b205f962ab9e41824528f616e8363ad2f541831a
4100628445dfb9e17fa167eb425d16bcad0ebc5f

File diff suppressed because one or more lines are too long

View file

@ -30,8 +30,6 @@
]
# Specifies the exact version of Solidity to use, overriding auto-detection.
solc_version = '0.8.28'
# If enabled, treats Solidity compiler warnings as errors, preventing artifact generation if warnings are present.
deny_warnings = false
# If set to true, changes compilation pipeline to go through the new IR optimizer.
via_ir = false
# Whether or not to enable the Solidity optimizer.
@ -115,4 +113,11 @@
anvil = "http://localhost:8545"
# [etherscan]
# mainnet = { key = "${ETHERSCAN_API_KEY}" }
# mainnet = { key = "${ETHERSCAN_API_KEY}" }
[lint]
# Global lint suppressions for naming conventions
exclude_lints = [
"mixed-case-function", # Keep AVS/EL/ERC naming conventions
"mixed-case-variable", # Keep __GAP, ethPOSDeposit, _metadataURI naming
]

View file

@ -13,7 +13,6 @@ import {Gateway} from "snowbridge/src/Gateway.sol";
import {IGatewayV2} from "snowbridge/src/v2/IGateway.sol";
import {GatewayProxy} from "snowbridge/src/GatewayProxy.sol";
import {AgentExecutor} from "snowbridge/src/AgentExecutor.sol";
import {Agent} from "snowbridge/src/Agent.sol";
import {Initializer} from "snowbridge/src/Initializer.sol";
import {OperatingMode} from "snowbridge/src/types/Common.sol";
import {ud60x18} from "snowbridge/lib/prb-math/src/UD60x18.sol";
@ -21,9 +20,6 @@ import {BeefyClient} from "snowbridge/src/BeefyClient.sol";
// OpenZeppelin imports
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import {
TransparentUpgradeableProxy
} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
// EigenLayer imports
import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol";

View file

@ -10,19 +10,6 @@ import {IGatewayV2} from "snowbridge/src/v2/IGateway.sol";
// Logging import
import {Logging} from "../utils/Logging.sol";
import {Accounts} from "../utils/Accounts.sol";
import {ValidatorsUtils} from "../utils/ValidatorsUtils.sol";
// Snowbridge imports
import {Gateway} from "snowbridge/src/Gateway.sol";
import {IGatewayV2} from "snowbridge/src/v2/IGateway.sol";
import {GatewayProxy} from "snowbridge/src/GatewayProxy.sol";
import {AgentExecutor} from "snowbridge/src/AgentExecutor.sol";
import {Agent} from "snowbridge/src/Agent.sol";
import {Initializer} from "snowbridge/src/Initializer.sol";
import {OperatingMode} from "snowbridge/src/types/Common.sol";
import {ud60x18} from "snowbridge/lib/prb-math/src/UD60x18.sol";
import {BeefyClient} from "snowbridge/src/BeefyClient.sol";
// Additional imports specific to local deployment
import {
@ -49,12 +36,8 @@ import {
PermissionController
} from "eigenlayer-contracts/src/contracts/permissions/PermissionController.sol";
import {
IAllocationManagerTypes
} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
import {IETHPOSDeposit} from "eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol";
import {
IRewardsCoordinator,
IRewardsCoordinatorTypes
} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol";
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";

View file

@ -5,8 +5,11 @@ import {EmptyContract} from "eigenlayer-contracts/src/test/mocks/EmptyContract.s
import {Config} from "./Config.sol";
import {Script} from "forge-std/Script.sol";
import {TestUtils} from "../../test/utils/TestUtils.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
contract DeployParams is Script, Config {
using SafeCast for uint256;
function getSnowbridgeConfig() public view returns (SnowbridgeConfig memory) {
SnowbridgeConfig memory config;
@ -20,7 +23,7 @@ contract DeployParams is Script, Config {
vm.parseJsonUint(configJson, ".snowbridge.randaoCommitExpiration");
config.minNumRequiredSignatures =
vm.parseJsonUint(configJson, ".snowbridge.minNumRequiredSignatures");
config.startBlock = uint64(vm.parseJsonUint(configJson, ".snowbridge.startBlock"));
config.startBlock = vm.parseJsonUint(configJson, ".snowbridge.startBlock").toUint64();
config.rewardsMessageOrigin =
vm.parseJsonBytes32(configJson, ".snowbridge.rewardsMessageOrigin");
@ -56,7 +59,7 @@ contract DeployParams is Script, Config {
}
config.rewardsInitiator = vm.parseJsonAddress(configJson, ".avs.rewardsInitiator");
config.vetoCommitteeMember = vm.parseJsonAddress(configJson, ".avs.vetoCommitteeMember");
config.vetoWindowBlocks = uint32(vm.parseJsonUint(configJson, ".avs.vetoWindowBlocks"));
config.vetoWindowBlocks = vm.parseJsonUint(configJson, ".avs.vetoWindowBlocks").toUint32();
config.validatorsStrategies =
vm.parseJsonAddressArray(configJson, ".avs.validatorsStrategies");
@ -76,15 +79,17 @@ contract DeployParams is Script, Config {
config.unpauserAddress = vm.parseJsonAddress(configJson, ".eigenLayer.unpauser");
config.rewardsUpdater = vm.parseJsonAddress(configJson, ".eigenLayer.rewardsUpdater");
config.calculationIntervalSeconds =
uint32(vm.parseJsonUint(configJson, ".eigenLayer.calculationIntervalSeconds"));
vm.parseJsonUint(configJson, ".eigenLayer.calculationIntervalSeconds").toUint32();
config.maxRewardsDuration =
uint32(vm.parseJsonUint(configJson, ".eigenLayer.maxRewardsDuration"));
vm.parseJsonUint(configJson, ".eigenLayer.maxRewardsDuration").toUint32();
config.maxRetroactiveLength =
uint32(vm.parseJsonUint(configJson, ".eigenLayer.maxRetroactiveLength"));
config.maxFutureLength = uint32(vm.parseJsonUint(configJson, ".eigenLayer.maxFutureLength"));
vm.parseJsonUint(configJson, ".eigenLayer.maxRetroactiveLength").toUint32();
config.maxFutureLength =
vm.parseJsonUint(configJson, ".eigenLayer.maxFutureLength").toUint32();
config.genesisRewardsTimestamp =
uint32(vm.parseJsonUint(configJson, ".eigenLayer.genesisRewardsTimestamp"));
config.activationDelay = uint32(vm.parseJsonUint(configJson, ".eigenLayer.activationDelay"));
vm.parseJsonUint(configJson, ".eigenLayer.genesisRewardsTimestamp").toUint32();
config.activationDelay =
vm.parseJsonUint(configJson, ".eigenLayer.activationDelay").toUint32();
config.globalCommissionBips =
uint16(vm.parseJsonUint(configJson, ".eigenLayer.globalCommissionBips"));
config.executorMultisig = vm.parseJsonAddress(configJson, ".eigenLayer.executorMultisig");
@ -95,7 +100,7 @@ contract DeployParams is Script, Config {
try vm.parseJsonUint(configJson, ".eigenLayer.minWithdrawalDelayBlocks") returns (
uint256 val
) {
config.minWithdrawalDelayBlocks = uint32(val);
config.minWithdrawalDelayBlocks = val.toUint32();
} catch {
config.minWithdrawalDelayBlocks = 7 days / 12 seconds; // Default: 1 week in blocks at 12s per block
}
@ -103,7 +108,7 @@ contract DeployParams is Script, Config {
try vm.parseJsonUint(configJson, ".eigenLayer.delegationWithdrawalDelayBlocks") returns (
uint256 val
) {
config.delegationWithdrawalDelayBlocks = uint32(val);
config.delegationWithdrawalDelayBlocks = val.toUint32();
} catch {
config.delegationWithdrawalDelayBlocks = 7 days / 12 seconds; // Default: 1 week
}
@ -149,7 +154,7 @@ contract DeployParams is Script, Config {
}
try vm.parseJsonUint(configJson, ".eigenLayer.deallocationDelay") returns (uint256 val) {
config.deallocationDelay = uint32(val);
config.deallocationDelay = val.toUint32();
} catch {
config.deallocationDelay = 7 days; // Default: 1 week
}
@ -157,7 +162,7 @@ contract DeployParams is Script, Config {
try vm.parseJsonUint(configJson, ".eigenLayer.allocationConfigurationDelay") returns (
uint256 val
) {
config.allocationConfigurationDelay = uint32(val);
config.allocationConfigurationDelay = val.toUint32();
} catch {
config.allocationConfigurationDelay = 1 days; // Default: 1 day
}
@ -165,7 +170,7 @@ contract DeployParams is Script, Config {
try vm.parseJsonUint(configJson, ".eigenLayer.beaconChainGenesisTimestamp") returns (
uint256 val
) {
config.beaconChainGenesisTimestamp = uint64(val);
config.beaconChainGenesisTimestamp = val.toUint64();
} catch {
config.beaconChainGenesisTimestamp = 1616508000; // Mainnet default
}

View file

@ -18,7 +18,6 @@ import {AVSDirectory} from "eigenlayer-contracts/src/contracts/core/AVSDirectory
import {DelegationManager} from "eigenlayer-contracts/src/contracts/core/DelegationManager.sol";
import {RewardsCoordinator} from "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol";
import {StrategyManager} from "eigenlayer-contracts/src/contracts/core/StrategyManager.sol";
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";
import {
PermissionController
} from "eigenlayer-contracts/src/contracts/permissions/PermissionController.sol";
@ -61,7 +60,7 @@ contract DeployTestnet is DeployBase {
return networkName;
}
function _getDeploymentMode() internal view override returns (string memory) {
function _getDeploymentMode() internal pure override returns (string memory) {
return "HOODI_TESTNET";
}

View file

@ -2,7 +2,6 @@
pragma solidity ^0.8.27;
import {SignUpOperatorBase} from "./SignUpOperatorBase.s.sol";
import {DataHavenServiceManager} from "../../src/DataHavenServiceManager.sol";
/**
* @title SignUpValidator

View file

@ -12,9 +12,7 @@ import {
import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol";
import {DelegationManager} from "eigenlayer-contracts/src/contracts/core/DelegationManager.sol";
import {StrategyManager} from "eigenlayer-contracts/src/contracts/core/StrategyManager.sol";
import {AVSDirectory} from "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol";
import {EigenPodManager} from "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol";
import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
import {EigenPod} from "eigenlayer-contracts/src/contracts/pods/EigenPod.sol";
import {
StrategyBaseTVLLimits

View file

@ -45,10 +45,10 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
// ============ Immutables ============
/// @notice The EigenLayer AllocationManager contract
IAllocationManager internal immutable _allocationManager;
IAllocationManager internal immutable _ALLOCATION_MANAGER;
/// @notice The EigenLayer RewardsCoordinator contract
IRewardsCoordinator internal immutable _rewardsCoordinator;
IRewardsCoordinator internal immutable _REWARDS_COORDINATOR;
// ============ State Variables ============
@ -72,35 +72,49 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
/// @notice Restricts function to the rewards initiator
modifier onlyRewardsInitiator() {
require(msg.sender == rewardsInitiator, OnlyRewardsInitiator());
_checkRewardsInitiator();
_;
}
/// @notice Restricts function to registered validators
modifier onlyValidator() {
OperatorSet memory operatorSet = OperatorSet({avs: address(this), id: VALIDATORS_SET_ID});
require(
_allocationManager.isMemberOfOperatorSet(msg.sender, operatorSet),
CallerIsNotValidator()
);
_checkValidator();
_;
}
/// @notice Restricts function to the EigenLayer AllocationManager
modifier onlyAllocationManager() {
require(msg.sender == address(_allocationManager), OnlyAllocationManager());
_checkAllocationManager();
_;
}
function _checkRewardsInitiator() internal view {
require(msg.sender == rewardsInitiator, OnlyRewardsInitiator());
}
function _checkValidator() internal view {
OperatorSet memory operatorSet = OperatorSet({avs: address(this), id: VALIDATORS_SET_ID});
require(
_ALLOCATION_MANAGER.isMemberOfOperatorSet(msg.sender, operatorSet),
CallerIsNotValidator()
);
}
function _checkAllocationManager() internal view {
require(msg.sender == address(_ALLOCATION_MANAGER), OnlyAllocationManager());
}
// ============ Constructor ============
/// @notice Sets the immutable EigenLayer contract references
/// @param __rewardsCoordinator The EigenLayer RewardsCoordinator contract
/// @param __allocationManager The EigenLayer AllocationManager contract
/// @param rewardsCoordinator_ The EigenLayer RewardsCoordinator contract
/// @param allocationManager_ The EigenLayer AllocationManager contract
constructor(
IRewardsCoordinator __rewardsCoordinator,
IAllocationManager __allocationManager
IRewardsCoordinator rewardsCoordinator_,
IAllocationManager allocationManager_
) {
_rewardsCoordinator = __rewardsCoordinator;
_allocationManager = __allocationManager;
_REWARDS_COORDINATOR = rewardsCoordinator_;
_ALLOCATION_MANAGER = allocationManager_;
_disableInitializers();
}
@ -121,7 +135,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
emit RewardsInitiatorSet(address(0), _rewardsInitiator);
// Register the DataHaven service in the AllocationManager.
_allocationManager.updateAVSMetadataURI(address(this), DATAHAVEN_AVS_METADATA);
_ALLOCATION_MANAGER.updateAVSMetadataURI(address(this), DATAHAVEN_AVS_METADATA);
// Create the operator set for the DataHaven service.
IAllocationManagerTypes.CreateSetParams[] memory operatorSets =
@ -129,7 +143,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
operatorSets[0] = IAllocationManagerTypes.CreateSetParams({
operatorSetId: VALIDATORS_SET_ID, strategies: validatorsStrategies
});
_allocationManager.createOperatorSets(address(this), operatorSets);
_ALLOCATION_MANAGER.createOperatorSets(address(this), operatorSets);
// Set the Snowbridge Gateway address.
_snowbridgeGateway = IGatewayV2(_snowbridgeGatewayAddress);
@ -149,7 +163,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
/// @inheritdoc IDataHavenServiceManager
function buildNewValidatorSetMessage() public view returns (bytes memory) {
OperatorSet memory operatorSet = OperatorSet({avs: address(this), id: VALIDATORS_SET_ID});
address[] memory currentValidatorSet = _allocationManager.getMembers(operatorSet);
address[] memory currentValidatorSet = _ALLOCATION_MANAGER.getMembers(operatorSet);
// Allocate max size, then resize after filtering
address[] memory newValidatorSet = new address[](currentValidatorSet.length);
@ -207,10 +221,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
require(operatorSetIds.length == 1, CantRegisterToMultipleOperatorSets());
require(operatorSetIds[0] == VALIDATORS_SET_ID, InvalidOperatorSetId());
require(validatorsAllowlist[operator], OperatorNotInAllowlist());
require(data.length == 20, InvalidSolochainAddressLength());
address solochainAddress = address(bytes20(data));
require(solochainAddress != address(0), ZeroAddress());
validatorEthAddressToSolochainAddress[operator] = solochainAddress;
validatorEthAddressToSolochainAddress[operator] = _toAddress(data);
emit OperatorRegistered(operator, operatorSetIds[0]);
}
@ -259,14 +270,14 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
/// @inheritdoc IDataHavenServiceManager
function validatorsSupportedStrategies() external view returns (IStrategy[] memory) {
OperatorSet memory operatorSet = OperatorSet({avs: address(this), id: VALIDATORS_SET_ID});
return _allocationManager.getStrategiesInOperatorSet(operatorSet);
return _ALLOCATION_MANAGER.getStrategiesInOperatorSet(operatorSet);
}
/// @inheritdoc IDataHavenServiceManager
function removeStrategiesFromValidatorsSupportedStrategies(
IStrategy[] calldata _strategies
) external onlyOwner {
_allocationManager.removeStrategiesFromOperatorSet(
_ALLOCATION_MANAGER.removeStrategiesFromOperatorSet(
address(this), VALIDATORS_SET_ID, _strategies
);
}
@ -275,7 +286,9 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
function addStrategiesToValidatorsSupportedStrategies(
IStrategy[] calldata _strategies
) external onlyOwner {
_allocationManager.addStrategiesToOperatorSet(address(this), VALIDATORS_SET_ID, _strategies);
_ALLOCATION_MANAGER.addStrategiesToOperatorSet(
address(this), VALIDATORS_SET_ID, _strategies
);
}
// ============ Rewards Functions ============
@ -289,14 +302,14 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
totalAmount += submission.operatorRewards[i].amount;
}
submission.token.safeIncreaseAllowance(address(_rewardsCoordinator), totalAmount);
submission.token.safeIncreaseAllowance(address(_REWARDS_COORDINATOR), totalAmount);
IRewardsCoordinatorTypes.OperatorDirectedRewardsSubmission[] memory submissions =
new IRewardsCoordinatorTypes.OperatorDirectedRewardsSubmission[](1);
submissions[0] = submission;
OperatorSet memory operatorSet = OperatorSet({avs: address(this), id: VALIDATORS_SET_ID});
_rewardsCoordinator.createOperatorDirectedOperatorSetRewardsSubmission(
_REWARDS_COORDINATOR.createOperatorDirectedOperatorSetRewardsSubmission(
operatorSet, submissions
);
@ -319,7 +332,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
function updateAVSMetadataURI(
string memory _metadataURI
) external onlyOwner {
_allocationManager.updateAVSMetadataURI(address(this), _metadataURI);
_ALLOCATION_MANAGER.updateAVSMetadataURI(address(this), _metadataURI);
}
/// @inheritdoc IDataHavenServiceManager
@ -331,7 +344,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
IAllocationManagerTypes.DeregisterParams({
operator: operator, avs: address(this), operatorSetIds: operatorSetIds
});
_allocationManager.deregisterFromOperatorSets(params);
_ALLOCATION_MANAGER.deregisterFromOperatorSets(params);
}
// ============ Slashing Submitter Functions ============
@ -343,8 +356,6 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
function slashValidatorsOperator(
SlashingRequest[] calldata slashings
) external onlyRewardsInitiator {
OperatorSet memory operatorSet = OperatorSet({avs: address(this), id: VALIDATORS_SET_ID});
for (uint256 i = 0; i < slashings.length; i++) {
IAllocationManagerTypes.SlashingParams memory slashingParams =
IAllocationManagerTypes.SlashingParams({
@ -355,7 +366,7 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
description: slashings[i].description
});
_allocationManager.slashOperator(address(this), slashingParams);
_ALLOCATION_MANAGER.slashOperator(address(this), slashingParams);
}
emit SlashingComplete();
@ -364,27 +375,17 @@ contract DataHavenServiceManager is OwnableUpgradeable, IAVSRegistrar, IDataHave
// ============ Internal Functions ============
/**
* @notice Creates the initial operator set for DataHaven in the AllocationManager.
* @dev This function should be called during initialisation to set up the required operator set.
* @notice Safely converts a 20-byte array to an address
* @param data The bytes to convert (must be exactly 20 bytes)
* @return result The address representation of the bytes
*/
function _createDataHavenOperatorSets(
IStrategy[] memory validatorsStrategies
) internal {
IAllocationManagerTypes.CreateSetParams[] memory operatorSets =
new IAllocationManagerTypes.CreateSetParams[](1);
operatorSets[0] = IAllocationManagerTypes.CreateSetParams({
operatorSetId: VALIDATORS_SET_ID, strategies: validatorsStrategies
});
_allocationManager.createOperatorSets(address(this), operatorSets);
}
/**
* @notice Internal function to set the rewards initiator
* @param _rewardsInitiator The new rewards initiator address
*/
function _setRewardsInitiator(
address _rewardsInitiator
) internal {
rewardsInitiator = _rewardsInitiator;
function _toAddress(
bytes memory data
) private pure returns (address result) {
require(data.length == 20, "Invalid address length");
assembly {
result := shr(96, mload(add(data, 32)))
}
require(result != address(0), ZeroAddress());
}
}

View file

@ -3,27 +3,19 @@ pragma solidity ^0.8.13;
/* solhint-disable func-name-mixedcase */
import {Test, console} from "forge-std/Test.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {
TransparentUpgradeableProxy
} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";
import {
IRewardsCoordinator,
IRewardsCoordinatorTypes
} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol";
import {AVSDeployer} from "./utils/AVSDeployer.sol";
import {ERC20FixedSupply} from "./utils/ERC20FixedSupply.sol";
import {DataHavenServiceManager} from "../src/DataHavenServiceManager.sol";
import {
IDataHavenServiceManager,
IDataHavenServiceManagerEvents,
IDataHavenServiceManagerErrors
} from "../src/interfaces/IDataHavenServiceManager.sol";
import {IDataHavenServiceManagerEvents} from "../src/interfaces/IDataHavenServiceManager.sol";
contract RewardsSubmitterTest is AVSDeployer {
using SafeERC20 for IERC20;
// Test addresses
address public snowbridgeAgent = address(uint160(uint256(keccak256("snowbridgeAgent"))));
address public operator1 = address(uint160(uint256(keccak256("operator1"))));
@ -46,7 +38,7 @@ contract RewardsSubmitterTest is AVSDeployer {
serviceManager.setRewardsInitiator(snowbridgeAgent);
// Fund the service manager with reward tokens
rewardToken.transfer(address(serviceManager), 100000e18);
IERC20(address(rewardToken)).safeTransfer(address(serviceManager), 100000e18);
}
// Helper function to build a submission
@ -228,7 +220,7 @@ contract RewardsSubmitterTest is AVSDeployer {
// Deploy a different token
ERC20FixedSupply otherToken =
new ERC20FixedSupply("Other", "OTHER", 1000000e18, address(this));
otherToken.transfer(address(serviceManager), 100000e18);
IERC20(address(otherToken)).safeTransfer(address(serviceManager), 100000e18);
// Build submission with different token
IRewardsCoordinatorTypes.StrategyAndMultiplier[] memory strategiesAndMultipliers =

View file

@ -8,7 +8,6 @@ import {Payload, Message, MessageKind, Asset} from "snowbridge/src/v2/Types.sol"
import {OperatorSet} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol";
import {SnowbridgeAndAVSDeployer} from "./utils/SnowbridgeAndAVSDeployer.sol";
import "forge-std/Test.sol";
contract SnowbridgeIntegrationTest is SnowbridgeAndAVSDeployer {
function setUp() public {

View file

@ -3,7 +3,6 @@ pragma solidity ^0.8.27;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol";
import {
IRewardsCoordinator
} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol";

View file

@ -1,22 +1,18 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import {
TransparentUpgradeableProxy,
ITransparentUpgradeableProxy
} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {PauserRegistry} from "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol";
import {
IAllocationManagerTypes
} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";
import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol";
import {AVSDirectory} from "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol";
import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol";
import {RewardsCoordinator} from "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol";
import {
PermissionController
} from "eigenlayer-contracts/src/contracts/permissions/PermissionController.sol";
import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol";
import {
IRewardsCoordinator,
@ -36,9 +32,11 @@ import {PermissionControllerMock} from "../mocks/PermissionControllerMock.sol";
import {SnowbridgeGatewayMock} from "../mocks/SnowbridgeGatewayMock.sol";
import {DelegationManager} from "eigenlayer-contracts/src/contracts/core/DelegationManager.sol";
import "forge-std/Test.sol";
import {Test, console, Vm} from "forge-std/Test.sol";
contract AVSDeployer is Test {
using SafeCast for uint256;
Vm public cheats = Vm(VM_ADDRESS);
ProxyAdmin public proxyAdmin;
@ -50,6 +48,7 @@ contract AVSDeployer is Test {
DataHavenServiceManager public serviceManager;
DataHavenServiceManager public serviceManagerImplementation;
// Truncation is intentional - deriving a deterministic mock address from hash
address public vetoCommitteeMember =
address(uint160(uint256(keccak256("vetoCommitteeMember"))));
uint32 public vetoWindowBlocks = 100; // 100 blocks veto window for tests
@ -383,7 +382,7 @@ contract AVSDeployer is Test {
address start,
uint256 inc
) internal pure returns (address) {
return address(uint160(uint256(uint160(start) + inc)));
return address((uint256(uint160(start)) + inc).toUint160());
}
function _incrementBytes32(

View file

@ -16,10 +16,9 @@ import {TestUtils} from "./TestUtils.sol";
import {
IAllocationManagerTypes
} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";
import {ValidatorsUtils} from "../../script/utils/ValidatorsUtils.sol";
import "forge-std/Test.sol";
import {console} from "forge-std/Test.sol";
contract SnowbridgeAndAVSDeployer is AVSDeployer {
// Snowbridge contracts
@ -58,7 +57,9 @@ contract SnowbridgeAndAVSDeployer is AVSDeployer {
uint256 public constant MIN_NUM_REQUIRED_SIGNATURES = 2;
uint64 public constant START_BLOCK = 1;
bytes32 public constant REWARDS_MESSAGE_ORIGIN = bytes32(0);
bytes32 public constant WRONG_MESSAGE_ORIGIN = bytes32("wrong origin");
// "wrong origin" as bytes32 (hex-encoded, right-padded with zeros)
bytes32 public constant WRONG_MESSAGE_ORIGIN =
0x77726f6e67206f726967696e0000000000000000000000000000000000000000;
function _deployMockAllContracts() internal {
_deployMockSnowbridge();

View file

@ -1,11 +1,15 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.27;
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
/**
* @title TestUtils
* @notice Utility functions for testing DataHaven contracts
*/
library TestUtils {
using SafeCast for uint256;
/**
* @notice Generates mock validator addresses for testing
* @param count Number of validators to generate
@ -18,7 +22,7 @@ library TestUtils {
) internal pure returns (address[] memory) {
address[] memory validators = new address[](count);
for (uint256 i = 0; i < count; i++) {
validators[i] = address(uint160(uint256(bytes32(startIndex + i + 1))));
validators[i] = address((startIndex + i + 1).toUint160());
}
return validators;
}

View file

@ -2028,12 +2028,12 @@ export const dataHavenServiceManagerAbi = [
type: 'constructor',
inputs: [
{
name: '__rewardsCoordinator',
name: 'rewardsCoordinator_',
internalType: 'contract IRewardsCoordinator',
type: 'address',
},
{
name: '__allocationManager',
name: 'allocationManager_',
internalType: 'contract IAllocationManager',
type: 'address',
},