From 45f0b16d9f9044e7e1426343861f49d1617932f0 Mon Sep 17 00:00:00 2001 From: Siddharth2207 Date: Thu, 16 Jul 2026 16:37:02 +0530 Subject: [PATCH 1/4] Deploy DiaWords deterministically via Zoltu CREATE2 Replace nonce-dependent `new DiaWords()` in the deploy script with a pinned Zoltu deployment record and tests that lock address and codehash invariants. Co-authored-by: Cursor --- script/Deploy.sol | 13 ++++++- src/lib/deploy/LibDiaWordsDeploy.sol | 28 +++++++++++++++ test/src/lib/deploy/LibDiaWordsDeploy.t.sol | 39 +++++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/lib/deploy/LibDiaWordsDeploy.sol create mode 100644 test/src/lib/deploy/LibDiaWordsDeploy.t.sol diff --git a/script/Deploy.sol b/script/Deploy.sol index 37c0b0d..2c58004 100644 --- a/script/Deploy.sol +++ b/script/Deploy.sol @@ -6,6 +6,8 @@ import {Script} from "forge-std-1.16.1/src/Script.sol"; import {DiaWords} from "../src/concrete/DiaWords.sol"; import {IMetaBoardV1_2} from "rain-metadata-0.1.0/src/interface/unstable/IMetaBoardV1_2.sol"; import {LibDescribedByMeta} from "rain-metadata-0.1.0/src/lib/LibDescribedByMeta.sol"; +import {LibRainDeploy} from "rain-deploy-0.1.2/src/lib/LibRainDeploy.sol"; +import {LibDiaWordsDeploy} from "../src/lib/deploy/LibDiaWordsDeploy.sol"; /// @dev Deterministic MetaBoard address deployed via Zoltu factory. /// https://github.com/rainlanguage/rain.metadata @@ -18,7 +20,16 @@ contract Deploy is Script { IMetaBoardV1_2 metaboard = IMetaBoardV1_2(METABOARD_ADDRESS); vm.startBroadcast(deployerPrivateKey); - DiaWords subParser = new DiaWords(); + + address deployed = LibRainDeploy.deployZoltu(LibDiaWordsDeploy.creationCode()); + if (deployed != LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS) { + revert LibRainDeploy.UnexpectedDeployedAddress(LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS, deployed); + } + if (deployed.codehash != LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH) { + revert LibRainDeploy.UnexpectedDeployedCodeHash(LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH, deployed.codehash); + } + + DiaWords subParser = DiaWords(deployed); LibDescribedByMeta.emitForDescribedAddress(metaboard, subParser, subParserDescribedByMeta); vm.stopBroadcast(); diff --git a/src/lib/deploy/LibDiaWordsDeploy.sol b/src/lib/deploy/LibDiaWordsDeploy.sol new file mode 100644 index 0000000..16612d3 --- /dev/null +++ b/src/lib/deploy/LibDiaWordsDeploy.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: LicenseRef-DCL-1.0 +// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd +pragma solidity ^0.8.25; + +import {DiaWords} from "../../concrete/DiaWords.sol"; +import {LibRainDeploy} from "rain-deploy-0.1.2/src/lib/LibRainDeploy.sol"; + +/// @title LibDiaWordsDeploy +/// @notice Deterministic DiaWords deployment record for Zoltu CREATE2 deploys. +library LibDiaWordsDeploy { + /// @dev Zoltu-derived deployment address for the current DiaWords creation code. + address constant DIA_WORDS_DEPLOYED_ADDRESS = 0xE30408dE1D707C003f282A774ed6aC77F096Ea29; + + /// @dev Runtime codehash for `DIA_WORDS_DEPLOYED_ADDRESS`. + bytes32 constant DIA_WORDS_DEPLOYED_CODEHASH = 0xea126daaa957cc166271a64204d95b94c50e72244a564f7317358ae71c0450e0; + + /// @notice Returns the canonical DiaWords creation code for Zoltu deployment. + function creationCode() internal pure returns (bytes memory code) { + return type(DiaWords).creationCode; + } + + /// @notice Predicts the Zoltu CREATE2 address for the given creation code. + function zoltuAddress(bytes memory initCode) internal pure returns (address predicted) { + bytes32 initCodeHash = keccak256(initCode); + bytes32 digest = keccak256(abi.encodePacked(bytes1(0xff), LibRainDeploy.ZOLTU_FACTORY, bytes32(0), initCodeHash)); + predicted = address(uint160(uint256(digest))); + } +} diff --git a/test/src/lib/deploy/LibDiaWordsDeploy.t.sol b/test/src/lib/deploy/LibDiaWordsDeploy.t.sol new file mode 100644 index 0000000..3f6ea9b --- /dev/null +++ b/test/src/lib/deploy/LibDiaWordsDeploy.t.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: LicenseRef-DCL-1.0 +// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd +pragma solidity =0.8.25; + +import {Test} from "forge-std-1.16.1/src/Test.sol"; +import {DiaWords} from "src/concrete/DiaWords.sol"; +import {LibRainDeploy} from "rain-deploy-0.1.2/src/lib/LibRainDeploy.sol"; +import {LibDiaWordsDeploy} from "src/lib/deploy/LibDiaWordsDeploy.sol"; + +contract LibDiaWordsDeployTest is Test { + function setUp() external { + LibRainDeploy.etchZoltuFactory(vm); + } + + function testPinnedAddressMatchesZoltuDerivation() external pure { + assertEq( + LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS, + LibDiaWordsDeploy.zoltuAddress(LibDiaWordsDeploy.creationCode()) + ); + } + + function testPinnedCodehashMatchesRuntimeBytecode() external { + LibRainDeploy.deployZoltu(LibDiaWordsDeploy.creationCode()); + assertEq( + LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS.codehash, + LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH + ); + } + + function testZoltuDeployMatchesPinnedRecord() external { + address deployed = LibRainDeploy.deployZoltu(LibDiaWordsDeploy.creationCode()); + assertEq(deployed, LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS); + assertEq(deployed.codehash, LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH); + } + + function testCreationCodeMatchesCompiledContract() external pure { + assertEq(type(DiaWords).creationCode, LibDiaWordsDeploy.creationCode()); + } +} From 7a6e425bf57ee8de9b69ca4bcc549c673bae4ae5 Mon Sep 17 00:00:00 2001 From: Siddharth2207 Date: Thu, 16 Jul 2026 16:55:37 +0530 Subject: [PATCH 2/4] Fix CI: slither too-many-digits and forge fmt on Deploy.sol Keep type(DiaWords).creationCode in script/tests only so slither does not analyze the embedded bytecode literal in src/lib/deploy. Co-authored-by: Cursor --- script/Deploy.sol | 6 ++++-- src/lib/deploy/LibDiaWordsDeploy.sol | 9 ++------- test/src/lib/deploy/LibDiaWordsDeploy.t.sol | 16 ++++------------ 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/script/Deploy.sol b/script/Deploy.sol index 2c58004..f0a9db5 100644 --- a/script/Deploy.sol +++ b/script/Deploy.sol @@ -21,12 +21,14 @@ contract Deploy is Script { vm.startBroadcast(deployerPrivateKey); - address deployed = LibRainDeploy.deployZoltu(LibDiaWordsDeploy.creationCode()); + address deployed = LibRainDeploy.deployZoltu(type(DiaWords).creationCode); if (deployed != LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS) { revert LibRainDeploy.UnexpectedDeployedAddress(LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS, deployed); } if (deployed.codehash != LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH) { - revert LibRainDeploy.UnexpectedDeployedCodeHash(LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH, deployed.codehash); + revert LibRainDeploy.UnexpectedDeployedCodeHash( + LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH, deployed.codehash + ); } DiaWords subParser = DiaWords(deployed); diff --git a/src/lib/deploy/LibDiaWordsDeploy.sol b/src/lib/deploy/LibDiaWordsDeploy.sol index 16612d3..ddecc72 100644 --- a/src/lib/deploy/LibDiaWordsDeploy.sol +++ b/src/lib/deploy/LibDiaWordsDeploy.sol @@ -2,7 +2,6 @@ // SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd pragma solidity ^0.8.25; -import {DiaWords} from "../../concrete/DiaWords.sol"; import {LibRainDeploy} from "rain-deploy-0.1.2/src/lib/LibRainDeploy.sol"; /// @title LibDiaWordsDeploy @@ -14,15 +13,11 @@ library LibDiaWordsDeploy { /// @dev Runtime codehash for `DIA_WORDS_DEPLOYED_ADDRESS`. bytes32 constant DIA_WORDS_DEPLOYED_CODEHASH = 0xea126daaa957cc166271a64204d95b94c50e72244a564f7317358ae71c0450e0; - /// @notice Returns the canonical DiaWords creation code for Zoltu deployment. - function creationCode() internal pure returns (bytes memory code) { - return type(DiaWords).creationCode; - } - /// @notice Predicts the Zoltu CREATE2 address for the given creation code. function zoltuAddress(bytes memory initCode) internal pure returns (address predicted) { bytes32 initCodeHash = keccak256(initCode); - bytes32 digest = keccak256(abi.encodePacked(bytes1(0xff), LibRainDeploy.ZOLTU_FACTORY, bytes32(0), initCodeHash)); + bytes32 digest = + keccak256(abi.encodePacked(bytes1(0xff), LibRainDeploy.ZOLTU_FACTORY, bytes32(0), initCodeHash)); predicted = address(uint160(uint256(digest))); } } diff --git a/test/src/lib/deploy/LibDiaWordsDeploy.t.sol b/test/src/lib/deploy/LibDiaWordsDeploy.t.sol index 3f6ea9b..4816293 100644 --- a/test/src/lib/deploy/LibDiaWordsDeploy.t.sol +++ b/test/src/lib/deploy/LibDiaWordsDeploy.t.sol @@ -14,26 +14,18 @@ contract LibDiaWordsDeployTest is Test { function testPinnedAddressMatchesZoltuDerivation() external pure { assertEq( - LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS, - LibDiaWordsDeploy.zoltuAddress(LibDiaWordsDeploy.creationCode()) + LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS, LibDiaWordsDeploy.zoltuAddress(type(DiaWords).creationCode) ); } function testPinnedCodehashMatchesRuntimeBytecode() external { - LibRainDeploy.deployZoltu(LibDiaWordsDeploy.creationCode()); - assertEq( - LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS.codehash, - LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH - ); + LibRainDeploy.deployZoltu(type(DiaWords).creationCode); + assertEq(LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS.codehash, LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH); } function testZoltuDeployMatchesPinnedRecord() external { - address deployed = LibRainDeploy.deployZoltu(LibDiaWordsDeploy.creationCode()); + address deployed = LibRainDeploy.deployZoltu(type(DiaWords).creationCode); assertEq(deployed, LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_ADDRESS); assertEq(deployed.codehash, LibDiaWordsDeploy.DIA_WORDS_DEPLOYED_CODEHASH); } - - function testCreationCodeMatchesCompiledContract() external pure { - assertEq(type(DiaWords).creationCode, LibDiaWordsDeploy.creationCode()); - } } From 2cd5ff66a958befc76b4d46d11d1d5572b4d17fa Mon Sep 17 00:00:00 2001 From: Siddharth2207 Date: Fri, 17 Jul 2026 14:04:04 +0530 Subject: [PATCH 3/4] Update DiaWords Zoltu deployment pins to match current bytecode. Restores LibDiaWordsDeploy address and codehash after upstream stack rebases. Co-authored-by: Cursor --- src/lib/deploy/LibDiaWordsDeploy.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/deploy/LibDiaWordsDeploy.sol b/src/lib/deploy/LibDiaWordsDeploy.sol index ddecc72..26603f7 100644 --- a/src/lib/deploy/LibDiaWordsDeploy.sol +++ b/src/lib/deploy/LibDiaWordsDeploy.sol @@ -8,10 +8,10 @@ import {LibRainDeploy} from "rain-deploy-0.1.2/src/lib/LibRainDeploy.sol"; /// @notice Deterministic DiaWords deployment record for Zoltu CREATE2 deploys. library LibDiaWordsDeploy { /// @dev Zoltu-derived deployment address for the current DiaWords creation code. - address constant DIA_WORDS_DEPLOYED_ADDRESS = 0xE30408dE1D707C003f282A774ed6aC77F096Ea29; + address constant DIA_WORDS_DEPLOYED_ADDRESS = 0xe68ACF7BEaf6A9Ae3C906Da37377884fF018DEC0; /// @dev Runtime codehash for `DIA_WORDS_DEPLOYED_ADDRESS`. - bytes32 constant DIA_WORDS_DEPLOYED_CODEHASH = 0xea126daaa957cc166271a64204d95b94c50e72244a564f7317358ae71c0450e0; + bytes32 constant DIA_WORDS_DEPLOYED_CODEHASH = 0x45c77463bf9ace585f25994f250671b3d2254c7e29c7f44f6e3de41e0dcddcc3; /// @notice Predicts the Zoltu CREATE2 address for the given creation code. function zoltuAddress(bytes memory initCode) internal pure returns (address predicted) { From d486c1be982b599df2e0d75c8bb2fcbb05a1e313 Mon Sep 17 00:00:00 2001 From: Siddharth2207 Date: Fri, 17 Jul 2026 15:13:39 +0530 Subject: [PATCH 4/4] Update DiaWords Zoltu pins after full stack rebase. Bytecode changed with merged validation and codegen PRs; refresh address and codehash. Co-authored-by: Cursor --- src/lib/deploy/LibDiaWordsDeploy.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/deploy/LibDiaWordsDeploy.sol b/src/lib/deploy/LibDiaWordsDeploy.sol index 26603f7..36ead13 100644 --- a/src/lib/deploy/LibDiaWordsDeploy.sol +++ b/src/lib/deploy/LibDiaWordsDeploy.sol @@ -8,10 +8,10 @@ import {LibRainDeploy} from "rain-deploy-0.1.2/src/lib/LibRainDeploy.sol"; /// @notice Deterministic DiaWords deployment record for Zoltu CREATE2 deploys. library LibDiaWordsDeploy { /// @dev Zoltu-derived deployment address for the current DiaWords creation code. - address constant DIA_WORDS_DEPLOYED_ADDRESS = 0xe68ACF7BEaf6A9Ae3C906Da37377884fF018DEC0; + address constant DIA_WORDS_DEPLOYED_ADDRESS = 0x64288bBA6FC86506f0aF001545eBCF23544B8389; /// @dev Runtime codehash for `DIA_WORDS_DEPLOYED_ADDRESS`. - bytes32 constant DIA_WORDS_DEPLOYED_CODEHASH = 0x45c77463bf9ace585f25994f250671b3d2254c7e29c7f44f6e3de41e0dcddcc3; + bytes32 constant DIA_WORDS_DEPLOYED_CODEHASH = 0xf0b030be8140c85d41825a53dfc0c27ba42cf4959e34b8322963d191fb36b493; /// @notice Predicts the Zoltu CREATE2 address for the given creation code. function zoltuAddress(bytes memory initCode) internal pure returns (address predicted) {