Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce zeus templates #790

Merged
merged 58 commits into from
Nov 1, 2024
Merged

feat: introduce zeus templates #790

merged 58 commits into from
Nov 1, 2024

Conversation

nadir-akhtar
Copy link
Contributor

@nadir-akhtar nadir-akhtar commented Oct 2, 2024

The PR adds script/Release_Template.sol, a template file providing abstract contracts for a variety of scripting use cases. A release script can inherit and override relevant functions with lightweight and straightforward syntax. Below are the contexts for using each script:

  • EOABuilder: An EOA performing a deploy, returning a Deployment object.
  • MultisigBuilder: A multisig performing some direct action (e.g. sending tokens, acting as a role on a contract), returning a Safe MetaTransactionData object.
    • Note that every MultisigBuilder script transforms calls into MultiSendCallOnly calls, meaning any number of calls (not accounting for gas) can be batched into one transaction by a multisig.
  • OpsTimelockBuilder: A specialized nested multisig action performing a queue() and execute()
    • queue() refers to queueing a transaction in the Timelock and execute() refers to forwarding that transaction after some delay to the Executor Multisig. You can see more details on the EigenLayer admin structure here.

Furthermore, script/releases/v0.1-eigenpod/ contains an example set of scripts inheriting and implementing functions for each aforementioned abstract contract. These scripts are purely for demonstration.

  • DeployEigenPod.s.sol: Deploys a single contract, EigenPod.
  • UpgradeEigenPod.s.sol: Sends a dummy call to the Timelock, plus an upgrade to the eigenPod to some pending implementation.
  • UpgradeViaTimelock.s.sol: Queues up a transaction in the Timelock, then later allows for the same transaction to be executed.

=======================================

To run this locally, try the following commands.

Deploy

forge script DeployEigenPodAndManager -s "deploy(string memory)" "script/configs/zipzoop.json"

Example Output

$ forge script DeployEigenPodAndManager -s "deploy(string memory)" "script/configs/zipzoop.json"
[⠊] Compiling...
No files changed, compilation skipped
Script ran successfully.
Gas used: 12901634

== Return ==
0: struct Deployment[] [Deployment({ name: "EigenPodManager", deployedTo: 0x90193C961A926261B756D1E5bb255e67ff9498A1 }), Deployment({ name: "EigenPod", deployedTo: 0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496 })]

== Logs ==
  Reading from config file: script/configs/zipzoop.json

Execute

forge script UpgradeEigenPod.s.sol -s "execute(string memory)" "script/configs/zipzoop.json"

Example Output

$ forge script UpgradeEigenPod.s.sol -s "execute(string memory)" 
"script/configs/zipzoop.json"
[⠊] Compiling...
[⠘] Compiling 1 files with Solc 0.8.12
[⠃] Solc 0.8.12 finished in 4.92s
...
Script ran successfully.
Gas used: 6812603

== Return ==
0: struct Transaction Transaction({ to: 0x40A2aCCbd92BCA938b02010E17A5b8929b49130D, value: 0, data: 0x8d80ff0a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000212000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e40825f38f0000000000000000000000001bef05c7303d44e0e2fcd2a19d993eded4c51b5b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bef05c7303d44e0e2fcd2a19d993eded4c51b5b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008499a88ec4000000000000000000000000b8d8952f572e67b11e43bc21250967772fa883ff00000000000000000000000010eba780ccd9e5e9ffbe529c25046c076be91048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, op: 1 })

Queue

forge script UpgradeEigenPodAndManager -s "queue(string memory)" "script/configs/zipzoop.json"

Example Output

$ forge script UpgradeEigenPodAndManager -s "queue(string memory)" "script/configs/zipzoop.json"
[⠊] Compiling...
No files changed, compilation skipped
Script ran successfully.
Gas used: 6870245

== Return ==
0: struct Transaction Transaction({ to: 0x0000000000000000000000000000000000000000, value: 0, data: 0x3a66f901000000000000000000000000da29bb71669f46f2a779b4b62f03644a84ee3479000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004246a76120200000000000000000000000040a2accbd92bca938b02010e17a5b8929b49130d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002248d80ff0a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001d2001bef05c7303d44e0e2fcd2a19d993eded4c51b5b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000b8d8952f572e67b11e43bc21250967772fa883ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000641794bb3c000000000000000000000000da29bb71669f46f2a779b4b62f03644a84ee34790000000000000000000000009ab2feaf0465f0ed51fc2b663ef228b418c9dad10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000092cc4a800a1513e85c481dddf3a06c6921211eac000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000243659cfe60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, op: 1 })

== Logs ==
  Reading from config file: script/configs/zipzoop.json

Execute after Queue

forge script UpgradeEigenPodAndManager -s "execute(string memory)" "script/configs/zipzoop.json"

Example Output

$ forge script UpgradeEigenPodAndManager -s "execute(string memory)" "script/configs/zipzoop.json"
[⠊] Compiling...
No files changed, compilation skipped
Script ran successfully.
Gas used: 7531664

== Return ==
0: struct Transaction Transaction({ to: 0x40A2aCCbd92BCA938b02010E17A5b8929b49130D, value: 0, data: 0x8d80ff0a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000532000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004840825f38f000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004246a76120200000000000000000000000040a2accbd92bca938b02010e17a5b8929b49130d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000002248d80ff0a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001d2001bef05c7303d44e0e2fcd2a19d993eded4c51b5b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000b8d8952f572e67b11e43bc21250967772fa883ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000641794bb3c000000000000000000000000da29bb71669f46f2a779b4b62f03644a84ee34790000000000000000000000009ab2feaf0465f0ed51fc2b663ef228b418c9dad10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000092cc4a800a1513e85c481dddf3a06c6921211eac000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000243659cfe6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b8d8952f572e67b11e43bc21250967772fa883ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004715018a60000000000000000000000000000, op: 1 })

== Logs ==
  Reading from config file: script/configs/zipzoop.json

@nadir-akhtar nadir-akhtar changed the base branch from dev to alex/deploy-refactor October 2, 2024 19:59
Copy link

github-actions bot commented Oct 3, 2024

Reading tracefile ./lcov.info.pruned
                                             |Lines      |Functions|Branches  
Filename                                       |Rate    Num|Rate  Num|Rate   Num
================================================================================
[src/contracts/]
core/AVSDirectory.sol                          |85.2%    27|88.9%   9|    -    0
core/DelegationManager.sol                     |96.5%   198|92.3%  39|    -    0
core/RewardsCoordinator.sol                    |93.0%   128|84.8%  33|    -    0
core/StrategyManager.sol                       |97.6%    83| 100%  24|    -    0
libraries/BeaconChainProofs.sol                | 100%    22| 100%  11|    -    0
libraries/BytesLib.sol                         | 0.0%   156| 0.0%  14|    -    0
libraries/EIP1271SignatureUtils.sol            | 100%     3| 100%   1|    -    0
libraries/Endian.sol                           | 100%     2| 100%   1|    -    0
libraries/Merkle.sol                           | 100%    38| 100%   5|    -    0
libraries/StructuredLinkedList.sol             | 0.0%    45| 0.0%  19|    -    0
permissions/Pausable.sol                       |95.7%    23|90.9%  11|    -    0
permissions/PauserRegistry.sol                 | 100%    12| 100%   6|    -    0
pods/EigenPod.sol                              | 100%   122|96.2%  26|    -    0
pods/EigenPodManager.sol                       | 100%    75|92.9%  14|    -    0
strategies/EigenStrategy.sol                   | 0.0%    10| 0.0%   5|    -    0
strategies/StrategyBase.sol                    |90.9%    44|78.9%  19|    -    0
strategies/StrategyBaseTVLLimits.sol           | 100%    12| 100%   6|    -    0
strategies/StrategyFactory.sol                 | 100%    35| 100%   9|    -    0
token/BackingEigen.sol                         |83.3%    30|69.2%  13|    -    0
token/Eigen.sol                                |45.0%    40|61.5%  13|    -    0
utils/UpgradeableSignatureCheckingUtils.sol    | 0.0%     6| 0.0%   4|    -    0
================================================================================
                                       Total:|75.6%  1111|76.2% 282|    -    0

@nadir-akhtar nadir-akhtar marked this pull request as ready for review October 4, 2024 18:22

vm.stopBroadcast();

return _deployments;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need to return this if it's in a state variable the parent method has access to?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. I prefer explicitly returning up values rather than implicitly modifying state variables.
  2. I actually meant to have this not be in the parent contract 😅 and instead have every contract inheriting EOADeployer define their own _deployments array local to their own contract to avoid 1).

Will update this in the templates branch and this PR

Comment on lines 52 to 55
function setUp() public {
(Addresses memory addrs, Environment memory env, Params memory params) = _readConfigFile("script/configs/zipzoop.json");
_deploy(addrs, env, params);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this for testing purposes? (if so, that's fine - just wondering!)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep. Though one big concern with this is that it actually modifies the state variable to call _deploy() twice even when not running the tests specifically -- wondering if it makes more sense to separate out tests into a different file, or to simply not use setUp()


MultisigCall[] internal _executorCalls;

function queue(Addresses memory addrs, Environment memory env, Params memory params) public override returns (MultisigCall[] memory) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Weird that this method in particular is public rather than the internal pattern the other two scripts use

Copy link
Collaborator

Choose a reason for hiding this comment

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

ah, i see now why it's public, used in script 3.

eesh, that feels like a weird pattern!

Copy link
Collaborator

Choose a reason for hiding this comment

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

2 main reasons:

  1. this is the only time we do this pattern (deploy a script and call it from another script)
  2. deploys/calls like this should be minimized because then you have to be careful how/when you use start/stop broadcast

Copy link
Collaborator

Choose a reason for hiding this comment

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

would much rather make this an inheritance relationship somehow

Comment on lines 30 to 48
_multisigCalls.append({
to: addrs.timelock,
value: 0,
data: abi.encodeWithSelector(
ITimelock.executeTransaction.selector,
executorCalldata
)
});

// after queued transaction, renounce ownership from eigenPodManager
_multisigCalls.append({
to: addrs.eigenPodManager.proxy,
value: 0,
data: abi.encodeWithSelector(
EigenPodManager(addrs.eigenPodManager.proxy).renounceOwnership.selector
)
});

return _multisigCalls;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Kind of a strange mix:

  • when we write the queue script, we don't worry about the ops flow and the fact that we'll be calling queueTransaction is abstracted away
  • when we write the execute, we do worry about the ops flow and explicitly call executeTransaction

This distinction doesn't feel apparent given the structure of the code/templates.

@nadir-akhtar nadir-akhtar changed the base branch from alex/deploy-refactor to dev October 31, 2024 22:11
@wadealexc wadealexc changed the title Nadir/deploy refactor feat: introduce zeus templates Nov 1, 2024
Copy link
Collaborator

@wadealexc wadealexc left a comment

Choose a reason for hiding this comment

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

LGTM!

@nadir-akhtar nadir-akhtar merged commit 957eb2d into dev Nov 1, 2024
16 of 18 checks passed
@nadir-akhtar nadir-akhtar deleted the nadir/deploy-refactor branch November 1, 2024 17:49
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.

3 participants