diff --git a/.changeset/small-seas-arrive.md b/.changeset/small-seas-arrive.md new file mode 100644 index 000000000..78b441862 --- /dev/null +++ b/.changeset/small-seas-arrive.md @@ -0,0 +1,5 @@ +--- +'@sphinx-labs/plugins': patch +--- + +Stop requiring the user to override the `run()` function in their script. diff --git a/.gitignore b/.gitignore index f17995933..fbf6f4aba 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ tsconfig.tsbuildinfo # vim *.sw* + +# env +.env diff --git a/docs/cli-existing-project.md b/docs/cli-existing-project.md index 781efbe40..a0deed010 100644 --- a/docs/cli-existing-project.md +++ b/docs/cli-existing-project.md @@ -124,7 +124,7 @@ The entry point of your deployment script must be a `run()` function; it cannot Then, add a `sphinx` modifier to your `run` function: ```sol -function run() sphinx public override { +function run() sphinx public { ... } ``` diff --git a/docs/writing-scripts.md b/docs/writing-scripts.md index cbd3f557c..257925a42 100644 --- a/docs/writing-scripts.md +++ b/docs/writing-scripts.md @@ -25,7 +25,7 @@ address safe = sphinxSafe(); The entry point for your deployment must always be a `run()` function that has a `sphinx` modifier: ```sol -function run() public sphinx override { +function run() public sphinx { ... } ``` diff --git a/packages/plugins/contracts/foundry/Sphinx.sol b/packages/plugins/contracts/foundry/Sphinx.sol index 0a7093819..3f53aebff 100644 --- a/packages/plugins/contracts/foundry/Sphinx.sol +++ b/packages/plugins/contracts/foundry/Sphinx.sol @@ -163,9 +163,14 @@ abstract contract Sphinx { deploymentInfo.requireSuccess = true; isCollecting = true; - vm.startBroadcast(safe); - run(); - vm.stopBroadcast(); + + // Delegatecall the `run()` function on this contract to collect the transactions. This + // pattern gives us flexibility to support function names other than `run()` in the future. + (bool success, ) = address(this).delegatecall(abi.encodeWithSignature("run()")); + // Throw an error if the deployment script fails. The error message in the user's script is + // displayed by Foundry's stack trace, so it'd be redundant to include the data returned by + // the delegatecall in our error message. + require(success, "Sphinx: Deployment script failed."); // Set the labels. We do this after running the user's script because the user may assign // labels in their deployment. We use a for-loop instead of directly assigning the labels to @@ -243,11 +248,13 @@ abstract contract Sphinx { if (isCollecting) { // Execute the user's 'run()' function. + vm.startBroadcast(sphinxSafe()); _; + vm.stopBroadcast(); } else { // Prank the Gnosis Safe then execute the user's `run()` function. We prank the Gnosis // Safe to replicate the deployment process on live networks. - vm.startPrank(address(sphinxSafe())); + vm.startPrank(sphinxSafe()); _; vm.stopPrank(); } @@ -257,8 +264,6 @@ abstract contract Sphinx { sphinxModifierEnabled = false; } - function run() public virtual; - /** * @notice Get the address of the SphinxModule. Before calling this function, the * `sphinxConfig.owners` array and `sphinxConfig.threshold` must be set. diff --git a/packages/plugins/contracts/test/script/Cases.s.sol b/packages/plugins/contracts/test/script/Cases.s.sol index c18d71baf..4f16dde7c 100644 --- a/packages/plugins/contracts/test/script/Cases.s.sol +++ b/packages/plugins/contracts/test/script/Cases.s.sol @@ -22,7 +22,7 @@ contract Simple is Script, Sphinx { sphinxConfig.orgId = "test-org-id"; } - function run() public override sphinx { + function run() public sphinx { // Deploy with Create2 Fallback fallbackCreate2 = new Fallback{ salt: 0 }(-1); // Perform low level call to fallback function diff --git a/packages/plugins/contracts/test/script/Empty.s.sol b/packages/plugins/contracts/test/script/Empty.s.sol index 7bba889e4..d3120b9be 100644 --- a/packages/plugins/contracts/test/script/Empty.s.sol +++ b/packages/plugins/contracts/test/script/Empty.s.sol @@ -16,5 +16,5 @@ contract Empty is Script, Sphinx { sphinxConfig.orgId = "test-org-id"; } - function run() public override sphinx {} + function run() public sphinx {} } diff --git a/packages/plugins/contracts/test/script/Large.s.sol b/packages/plugins/contracts/test/script/Large.s.sol index b61118681..2a16aa4c4 100644 --- a/packages/plugins/contracts/test/script/Large.s.sol +++ b/packages/plugins/contracts/test/script/Large.s.sol @@ -16,7 +16,7 @@ contract Simple is Script, Sphinx { sphinxConfig.orgId = "test-org-id"; } - function run() public override sphinx { + function run() public sphinx { new MyLargeContract{ salt: bytes32(uint(0)) }(); new MyLargeContract{ salt: bytes32(uint(1)) }(); new MyLargeContract{ salt: bytes32(uint(2)) }(); diff --git a/packages/plugins/contracts/test/script/PartiallyEmpty.s.sol b/packages/plugins/contracts/test/script/PartiallyEmpty.s.sol index 90638b0f1..726517837 100644 --- a/packages/plugins/contracts/test/script/PartiallyEmpty.s.sol +++ b/packages/plugins/contracts/test/script/PartiallyEmpty.s.sol @@ -16,7 +16,7 @@ contract PartiallyEmpty is Script, Sphinx { sphinxConfig.orgId = "test-org-id"; } - function run() public override sphinx { + function run() public sphinx { // Deploy a contract on Ethereum and don't deploy anything on Optimism. if (block.chainid == 1) { new MyContract2{ salt: 0 }(); diff --git a/packages/plugins/contracts/test/script/RevertDuringSimulation.s.sol b/packages/plugins/contracts/test/script/RevertDuringSimulation.s.sol index 8e9ceb425..040ca5f75 100644 --- a/packages/plugins/contracts/test/script/RevertDuringSimulation.s.sol +++ b/packages/plugins/contracts/test/script/RevertDuringSimulation.s.sol @@ -17,7 +17,7 @@ contract RevertDuringSimulation_Script is Script, Sphinx { sphinxConfig.orgId = "test-org-id"; } - function run() public override sphinx { + function run() public sphinx { RevertDuringSimulation reverter = new RevertDuringSimulation{ salt: 0 }(sphinxModule()); reverter.revertDuringSimulation(); } diff --git a/packages/plugins/contracts/test/script/Simple.s.sol b/packages/plugins/contracts/test/script/Simple.s.sol index 35ada96d0..1f5ead61b 100644 --- a/packages/plugins/contracts/test/script/Simple.s.sol +++ b/packages/plugins/contracts/test/script/Simple.s.sol @@ -17,7 +17,7 @@ contract Simple1 is Script, Sphinx { sphinxConfig.orgId = "test-org-id"; } - function run() public override sphinx { + function run() public sphinx { MyContract2 myContract; Network network = getSphinxNetwork(block.chainid); if (network == Network.ethereum || network == Network.sepolia) { @@ -39,7 +39,7 @@ contract Simple2 is Script, Sphinx { sphinxConfig.orgId = "test-org-id"; } - function run() public override sphinx { + function run() public sphinx { new MyContract2{ salt: bytes32(uint(2)) }(); } } diff --git a/packages/plugins/script/Sample.s.sol b/packages/plugins/script/Sample.s.sol index 0f6c99c10..b28583838 100644 --- a/packages/plugins/script/Sample.s.sol +++ b/packages/plugins/script/Sample.s.sol @@ -20,7 +20,7 @@ contract Sample is Sphinx { sphinxConfig.saltNonce = 0; } - function run() public override sphinx { + function run() public sphinx { new MyContract1{ salt: bytes32(uint(1)) }( -1, 2, diff --git a/packages/plugins/src/sample-project/sample-contracts.ts b/packages/plugins/src/sample-project/sample-contracts.ts index 11a1c5c50..4a4cb62d0 100644 --- a/packages/plugins/src/sample-project/sample-contracts.ts +++ b/packages/plugins/src/sample-project/sample-contracts.ts @@ -54,7 +54,7 @@ contract HelloSphinxScript is Sphinx { ]; } - function run() public override sphinx { + function run() public sphinx { helloSphinx = new HelloSphinx{ salt: bytes32(0) }("Hi", 2); helloSphinx.add(8); }