Skip to content

Commit

Permalink
squash
Browse files Browse the repository at this point in the history
  • Loading branch information
gpsanant committed Sep 16, 2024
1 parent e5b375b commit c0773d3
Show file tree
Hide file tree
Showing 17 changed files with 1,630 additions and 421 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
[submodule "lib/openzeppelin-contracts-upgradeable-v4.9.0"]
path = lib/openzeppelin-contracts-upgradeable-v4.9.0
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/risc0-ethereum"]
path = lib/risc0-ethereum
url = https://github.com/risc0/risc0-ethereum
1 change: 1 addition & 0 deletions lib/risc0-ethereum
Submodule risc0-ethereum added at 239954
3 changes: 2 additions & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
@openzeppelin-v4.9.0/=lib/openzeppelin-contracts-v4.9.0/
@openzeppelin-upgrades-v4.9.0/=lib/openzeppelin-contracts-upgradeable-v4.9.0/
ds-test/=lib/ds-test/src/
forge-std/=lib/forge-std/src/
forge-std/=lib/forge-std/src/
@risc0-ethereum/=lib/risc0-ethereum/contracts/src
12 changes: 6 additions & 6 deletions script/configs/devnet/deploy_from_scratch.holesky.config.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"maintainer": "samlaf@eigenlabs.org",
"multisig_addresses": {
"operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
"communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
"pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
"executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
"timelock": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479"
"operationsMultisig": "0x1981d656d61D6be37f50fD78f6Fd7627Fd2ae597",
"communityMultisig": "0x1981d656d61D6be37f50fD78f6Fd7627Fd2ae597",
"pauserMultisig": "0x1981d656d61D6be37f50fD78f6Fd7627Fd2ae597",
"executorMultisig": "0x1981d656d61D6be37f50fD78f6Fd7627Fd2ae597",
"timelock": "0x1981d656d61D6be37f50fD78f6Fd7627Fd2ae597"
},
"strategies": [
{
Expand Down Expand Up @@ -44,7 +44,7 @@
"MAX_RETROACTIVE_LENGTH": 7776000,
"MAX_FUTURE_LENGTH": 2592000,
"GENESIS_REWARDS_TIMESTAMP": 1710979200,
"rewards_updater_address": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
"rewards_updater_address": "0x1981d656d61D6be37f50fD78f6Fd7627Fd2ae597",
"activation_delay": 7200,
"calculation_interval_seconds": 604800,
"global_operator_commission_bips": 1000,
Expand Down
4 changes: 2 additions & 2 deletions script/deploy/devnet/operatorSets/DeployStrategies.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ contract DeployStrategies is ExistingDeploymentParser {
executorMultisig,
address(baseStrategyImplementation)
);
uint256 batches = 1;
uint256 batchSize = 100;
uint256 batches = 3;
uint256 batchSize = 10;

IStrategy[] memory strategies = new IStrategy[](batchSize * batches);
bool[] memory falses = new bool[](batchSize);
Expand Down
255 changes: 255 additions & 0 deletions script/deploy/devnet/operatorSets/PopulateSRC.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.12;

import "../../../../src/contracts/core/StakeRootCompendium.sol";
import "../../../utils/ExistingDeploymentParser.sol";
import "forge-std/Test.sol";
import "forge-std/Script.sol";


contract PopulateSRC is Script, Test, ExistingDeploymentParser {
uint32 constant NUM_OPSETS = 1;
uint32 constant NUM_OPERATORS_PER_OPSET = 250;
uint32 constant NUM_STRATS_PER_OPSET = 1;
uint256 constant TOKEN_AMOUNT_PER_OPERATOR = 1 ether;


function run() public {
_parseDeployedContracts("script/output/devnet/M2_from_scratch_deployment_data.json");
// other cast default. private key: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
address proxyAdmin = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8;

vm.startBroadcast();
uint32 proofInterval = 1 hours;
IStakeRootCompendium stakeRootCompendiumImplementation = new StakeRootCompendium({
_delegationManager: delegationManager,
_avsDirectory: avsDirectory,
_maxTotalCharge: 100 ether,
_minBalanceThreshold: 0 ether,
_minProofsDuration: 20,
_verifier: address(0),
_imageId: bytes32(0)
});
StakeRootCompendium stakeRootCompendium = StakeRootCompendium(payable(new TransparentUpgradeableProxy(
address(stakeRootCompendiumImplementation),
proxyAdmin,
"" // TODO: initialize
)));
IStakeRootCompendium.Proof memory proof;
stakeRootCompendium.verifyStakeRoot(uint32(block.timestamp - (block.timestamp % proofInterval)), bytes32(0), address(0), 0, proof);
vm.stopBroadcast();

emit log_named_address("stakeRootCompendium", address(stakeRootCompendium));

address[] memory allStrategies = _parseDeployedStrategies("script/output/devnet/deployed_strategies.json");

// list of strategies for each operatorSet
IStrategy[][] memory strategies = new IStrategy[][](NUM_OPSETS);
for (uint256 i = 0; i < strategies.length; ++i) {
strategies[i] = new IStrategy[](NUM_STRATS_PER_OPSET);
for (uint256 j = 0; j < strategies[i].length; ++j) {
// fill in the strategies array
strategies[i][j] = IStrategy(allStrategies[i * strategies[i].length + j]);
}
}

vm.broadcast();
OperatorFactory operatorFactory = new OperatorFactory(delegationManager, strategyManager, avsDirectory);
address[][] memory operators = new address[][](strategies.length);
for (uint i = 0; i < operators.length; i++) {
// todo: send operators[i].length*1 ether of strategy token to operatorfactory
// //transfer enough tokens for every operator in the operator set for all the strategies in the operator set

for (uint j = 0; j < strategies[i].length; j++) {
IERC20 token = strategies[i][j].underlyingToken();
vm.startBroadcast();
token.approve(msg.sender, type(uint256).max);
token.transfer(address(operatorFactory), NUM_OPERATORS_PER_OPSET*TOKEN_AMOUNT_PER_OPERATOR);
vm.stopBroadcast();
}

vm.startBroadcast();
operators[i] = operatorFactory.createManyOperators(NUM_OPERATORS_PER_OPSET);
for (uint j = 0; j < strategies[i].length; j++) {
operatorFactory.depositForOperators(strategies[i][j], operators[i], TOKEN_AMOUNT_PER_OPERATOR);
}
vm.stopBroadcast();
}

uint64 magnitudeForOperators = 0.1 ether;
vm.startBroadcast();
AVS avs = new AVS(avsDirectory, stakeRootCompendium);
payable(address(avs)).transfer(2 * stakeRootCompendium.MIN_BALANCE_THRESHOLD() * strategies.length);

for (uint i = 0; i < strategies.length; i++) {
avs.createOperatorSetAndRegisterOperators(uint32(i), strategies[i], operators[i]);
IAVSDirectory.OperatorSet memory operatorSet = IAVSDirectory.OperatorSet({
avs: address(avs),
operatorSetId: uint32(i)
});
for (uint j = 0; j < strategies[i].length; j++) {
operatorFactory.allocateForOperators(strategies[i][j], operatorSet, operators[i], magnitudeForOperators);
}
}
vm.stopBroadcast();

/// WRITE TO JSON

// string memory output_path = "script/output/devnet/populate_src/";
// FsMetadata[] memory metadata = vm.fsMetadata(output_path);
// for (uint256 i = 0; i < entries.length; ++i) {
// vm.removeFile(entries[i].path);
// }
for (uint256 i = 0; i < operators.length; ++i) {
address[] memory strategyAddresses = new address[](strategies[i].length);
for (uint256 j = 0; j < strategies[i].length; ++j) {
strategyAddresses[j] = address(strategies[i][j]);
}

string memory parent_object = "success";
vm.serializeAddress(parent_object, "stakeRootCompendium", address(stakeRootCompendium));
vm.serializeAddress(parent_object, "avs", address(avs));
vm.serializeAddress(parent_object, "operators", operators[i]);
vm.serializeAddress(parent_object, "strategies", strategyAddresses);
string memory finalJson = vm.serializeString("success", "success", parent_object);
vm.writeJson(finalJson, string.concat("script/output/devnet/populate_src/opset_", string.concat(vm.toString(i), ".json")));
}
}
}

contract AVS {
IAVSDirectory avsDirectory;
IStakeRootCompendium stakeRootCompendium;

// creates an operator set for each list of strategies
constructor(IAVSDirectory _avsDirectory, IStakeRootCompendium _stakeRootCompendium) {
avsDirectory = _avsDirectory;
stakeRootCompendium = _stakeRootCompendium;
avsDirectory.becomeOperatorSetAVS();
}

function createOperatorSetAndRegisterOperators(uint32 operatorSetId, IStrategy[] memory strategies, address[] memory operators) external {
// create operator sets and become an AVS
uint32[] memory operatorSetIdsToCreate = new uint32[](1);
operatorSetIdsToCreate[0] = operatorSetId;
if(!avsDirectory.isOperatorSet(address(this), operatorSetId)) {
avsDirectory.createOperatorSets(operatorSetIdsToCreate);

stakeRootCompendium.deposit{value: 2 * stakeRootCompendium.MIN_BALANCE_THRESHOLD()}(IAVSDirectory.OperatorSet({
avs: address(this),
operatorSetId: operatorSetId
}));
}

// register operators to operator sets
for (uint256 i = 0; i < operators.length; ++i) {
avsDirectory.registerOperatorToOperatorSets(
operators[i],
operatorSetIdsToCreate,
ISignatureUtils.SignatureWithSaltAndExpiry({
signature: hex"",
salt: keccak256(abi.encodePacked(address(this), operatorSetIdsToCreate)),
expiry: type(uint256).max
})
);
}

// loop through strategies in batches of NUM_STRATS_PER_OPERATOR for each operator set
IStakeRootCompendium.StrategyAndMultiplier[] memory strategiesAndMultipliers = new IStakeRootCompendium.StrategyAndMultiplier[](strategies.length);
for (uint256 i = 0; i < strategiesAndMultipliers.length; ++i) {
strategiesAndMultipliers[i] = IStakeRootCompendium.StrategyAndMultiplier({
strategy: strategies[i],
multiplier: 1 ether
});
}
stakeRootCompendium.addOrModifyStrategiesAndMultipliers(operatorSetId, strategiesAndMultipliers);
stakeRootCompendium.setOperatorSetExtraData(operatorSetId, keccak256(abi.encodePacked(operatorSetId)));
for (uint256 i = 0; i < operators.length; ++i) {
stakeRootCompendium.setOperatorExtraData(operatorSetId, operators[i], keccak256(abi.encodePacked(operators[i])));
}
}

receive() external payable {}
}


contract OperatorFactory is Test {
IDelegationManager delegationManager;
IStrategyManager strategyManager;
IAVSDirectory avsDirectory;
constructor(IDelegationManager _delegationManager, IStrategyManager _strategyManager, IAVSDirectory _avsDirectory) {
delegationManager = _delegationManager;
strategyManager = _strategyManager;
avsDirectory = _avsDirectory;
}

function createManyOperators(uint256 numOperatorsPerOpset) public returns(address[] memory) {
address[] memory operators = new address[](numOperatorsPerOpset);
for (uint256 i = 0; i < operators.length; ++i) {
operators[i] = address(new Operator(delegationManager, avsDirectory));
}
return operators;
}

function depositForOperators(IStrategy strategy, address[] memory operators, uint256 tokenAmountPerOperator) public {
IERC20 token = strategy.underlyingToken();
token.approve(address(strategyManager), type(uint256).max);

for (uint256 i = 0; i < operators.length; ++i) {
strategyManager.depositIntoStrategyWithSignature(strategy, token, tokenAmountPerOperator, operators[i], type(uint256).max, hex"");
}
}

function allocateForOperators(IStrategy strategy, IAVSDirectory.OperatorSet calldata operatorSet, address[] memory operators, uint64 magnitudeForOperators) public {
uint64 expectedTotalMagnitude = ShareScalingLib.INITIAL_TOTAL_MAGNITUDE;

IAVSDirectory.OperatorSet[] memory operatorSets = new IAVSDirectory.OperatorSet[](1);
operatorSets[0] = operatorSet;

uint64[] memory magnitudes = new uint64[](1);
magnitudes[0] = magnitudeForOperators;

IAVSDirectory.MagnitudeAllocation[] memory allocations = new IAVSDirectory.MagnitudeAllocation[](1);
allocations[0] = IAVSDirectory.MagnitudeAllocation({
strategy: strategy,
expectedTotalMagnitude: expectedTotalMagnitude,
operatorSets: operatorSets,
magnitudes: magnitudes
});

ISignatureUtils.SignatureWithSaltAndExpiry memory signature = ISignatureUtils.SignatureWithSaltAndExpiry({
signature: hex"",
salt: keccak256(abi.encode(allocations)),
expiry: type(uint256).max
});

for (uint256 i = 0; i < operators.length; ++i) {
avsDirectory.modifyAllocations(
operators[i],
allocations,
signature
);
}
}
}

contract Operator is IERC1271 {
constructor(IDelegationManager delegationManager, IAVSDirectory avsDirectory) {
// register as operator
IDelegationManager.OperatorDetails memory operatorDetails = IDelegationManager.OperatorDetails({
__deprecated_earningsReceiver: address(this),
delegationApprover: address(0),
stakerOptOutWindowBlocks: 0
});
delegationManager.registerAsOperator(
operatorDetails,
0,
""
);
}

// sign everything
function isValidSignature(bytes32, bytes memory) external pure returns (bytes4 magicValue) {
return EIP1271SignatureUtils.EIP1271_MAGICVALUE;
}
}
48 changes: 48 additions & 0 deletions script/deploy/devnet/operatorSets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Setting up a test environment

If you already have a state with strategies deployed, continue to (Step 2)[#step-2].

## Step 1: Deploy the strategies

In the first terminal

```
anvil --dump-state state.json --gas-limit 18446744073709551615
```

In the second terminal, deploy the core contracts

```
forge script script/deploy/devnet/Deploy_From_Scratch.s.sol --rpc-url localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast --skip-simulation --sig "run(string memory configFile)" -- deploy_from_scratch.anvil.config.json
```

After configuring `DeployStrategies.s.sol` with the number of strategies you want to deploy,
```
forge script script/deploy/devnet/operatorSets/DeployStrategies.s.sol:DeployStrategies --rpc-url localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast --skip-simulation --gas-limit 18446744073709551615
```

Stop the anvil chain and retain the state

## Step 2: Populate the AVSDirectory and StakeRootCompendium

Start the anvil chain with the state

```
anvil --load-state state.json --gas-limit 18446744073709551615
```

First, in order to run a new script you need to add a block to the chain. Simply do that with at transfer:

```
cast send --rpc-url localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --value=0ether 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb9226
```

Then run the script, after configuring `PopulateSRC.sol` with the number of opsets and the number of operators per opset,

```
rm script/output/devnet/populate_src/*
forge script script/deploy/devnet/operatorSets/PopulateSRC.sol:PopulateSRC --rpc-url localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --skip-simulation --broadcast --gas-limit 18446744073709551615
```

Then move on to proving
Loading

0 comments on commit c0773d3

Please sign in to comment.