From 9bab6d3b66ec6c869a43564597f835291e3be5a0 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 23 Jan 2024 22:20:23 +0000 Subject: [PATCH 1/6] Use type code creation to deploy forge connectors --- src/forge/Registry.sol | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/forge/Registry.sol b/src/forge/Registry.sol index 67bc0b2..f148bba 100644 --- a/src/forge/Registry.sol +++ b/src/forge/Registry.sol @@ -3,6 +3,8 @@ pragma solidity ^0.8.8; import "../suavelib/Suave.sol"; +import "./Connector.sol"; +import "./ConfidentialInputs.sol"; interface registryVM { function etch(address, bytes calldata) external; @@ -12,15 +14,8 @@ library Registry { registryVM constant vm = registryVM(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); function enableLib(address addr) public { - // code for Wrapper - bytes memory code = - hex"608060405234801561001057600080fd5b506004361061002b5760003560e01c8063671ff786146100a1575b6040516bffffffffffffffffffffffff193060601b1660208201526000906100959060340160408051808303601f19018152602036601f8101829004820285018201909352828452909291600091819084018382808284376000920191909152506100ca92505050565b90508081518060208301f35b6100b46100af366004610487565b61025e565b6040516100c19190610557565b60405180910390f35b606060006100d78461025e565b905060006100e48461025e565b60408051600480825260a0820190925291925060009190816020015b60608152602001906001900390816101005790505090506040518060400160405280600a8152602001690e6eac2ecca5acecae8d60b31b8152508160008151811061014d5761014d610571565b602002602001018190525060405180604001604052806005815260200164666f72676560d81b8152508160018151811061018957610189610571565b602002602001018190525082816002815181106101a8576101a8610571565b602002602001018190525081816003815181106101c7576101c7610571565b6020908102919091010152604051638916046760e01b8152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063891604679061020c908590600401610587565b600060405180830381865afa158015610229573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261025191908101906105eb565b9450505050505b92915050565b60606000825160026102709190610678565b67ffffffffffffffff81111561028857610288610418565b6040519080825280601f01601f1916602001820160405280156102b2576020820181803683370190505b5060408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015290915060005b84518110156103ee578182518683815181106102fe576102fe610571565b0160200151610310919060f81c6106a5565b8151811061032057610320610571565b01602001516001600160f81b0319168361033b836002610678565b8151811061034b5761034b610571565b60200101906001600160f81b031916908160001a90535081825186838151811061037757610377610571565b0160200151610389919060f81c6106b9565b8151811061039957610399610571565b01602001516001600160f81b031916836103b4836002610678565b6103bf9060016106cd565b815181106103cf576103cf610571565b60200101906001600160f81b031916908160001a9053506001016102e0565b508160405160200161040091906106e0565b60405160208183030381529060405292505050919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561045757610457610418565b604052919050565b600067ffffffffffffffff82111561047957610479610418565b50601f01601f191660200190565b60006020828403121561049957600080fd5b813567ffffffffffffffff8111156104b057600080fd5b8201601f810184136104c157600080fd5b80356104d46104cf8261045f565b61042e565b8181528560208385010111156104e957600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b8381101561052257818101518382015260200161050a565b50506000910152565b60008151808452610543816020860160208601610507565b601f01601f19169290920160200192915050565b60208152600061056a602083018461052b565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156105de57603f198886030184526105cc85835161052b565b945092850192908501906001016105b0565b5092979650505050505050565b6000602082840312156105fd57600080fd5b815167ffffffffffffffff81111561061457600080fd5b8201601f8101841361062557600080fd5b80516106336104cf8261045f565b81815285602083850101111561064857600080fd5b610659826020830160208601610507565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761025857610258610662565b634e487b7160e01b600052601260045260246000fd5b6000826106b4576106b461068f565b500490565b6000826106c8576106c861068f565b500690565b8082018082111561025857610258610662565b61060f60f31b8152600082516106fd816002850160208701610507565b919091016002019291505056fea164736f6c6343000817000a"; - vm.etch(addr, code); - - // enable is confidential wrapper - bytes memory confidentialCode = - hex"608060405234801561001057600080fd5b50600436106100365760003560e01c8063844f563414610125578063cb9b7f3f1461013a575b600080805461004490610170565b905067ffffffffffffffff81111561005e5761005e6101aa565b6040519080825280601f01601f191660200182016040528015610088576020820181803683370190505b50905060005b6000805461009b90610170565b905081101561011a5760008181546100b290610170565b81106100c0576100c06101c0565b8154600116156100df5790600052602060002090602091828204019190065b9054901a600160f81b028282815181106100fb576100fb6101c0565b60200101906001600160f81b031916908160001a90535060010161008e565b508081518060208301f35b6101386101333660046101d6565b610142565b005b610138610152565b600061014e82826102d8565b5050565b604080516020810190915260008082529061016d90826102d8565b50565b600181811c9082168061018457607f821691505b6020821081036101a457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6000602082840312156101e857600080fd5b813567ffffffffffffffff8082111561020057600080fd5b818401915084601f83011261021457600080fd5b813581811115610226576102266101aa565b604051601f8201601f19908116603f0116810190838211818310171561024e5761024e6101aa565b8160405282815287602084870101111561026757600080fd5b826020860160208301376000928101602001929092525095945050505050565b601f8211156102d3576000816000526020600020601f850160051c810160208610156102b05750805b601f850160051c820191505b818110156102cf578281556001016102bc565b5050505b505050565b815167ffffffffffffffff8111156102f2576102f26101aa565b610306816103008454610170565b84610287565b602080601f83116001811461033b57600084156103235750858301515b600019600386901b1c1916600185901b1785556102cf565b600085815260208120601f198616915b8281101561036a5788860151825594840194600190910190840161034b565b50858210156103885787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000817000a"; - vm.etch(Suave.CONFIDENTIAL_INPUTS, confidentialCode); + // code for Forge proxy connector + deployCode(addr, type(Connector).creationCode); } function enable() public { @@ -41,5 +36,17 @@ library Registry { enableLib(Suave.SIMULATE_TRANSACTION); enableLib(Suave.SUBMIT_BUNDLE_JSON_RPC); enableLib(Suave.SUBMIT_ETH_BLOCK_TO_RELAY); + + // enable is confidential wrapper + deployCode(Suave.CONFIDENTIAL_INPUTS, type(ConfidentialInputsWrapper).creationCode); + } + + address constant dummyAddr = 0x1111000000000000000000000000000000000000; + + function deployCode(address where, bytes memory creationCode) internal { + vm.etch(dummyAddr, creationCode); + (, bytes memory runtimeBytecode) = dummyAddr.call(""); + + vm.etch(where, runtimeBytecode); } } From c31316d7042427b6329132d7aff2c163326cdaf0 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 23 Jan 2024 22:21:38 +0000 Subject: [PATCH 2/6] Fix more --- src/forge/Registry.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/forge/Registry.sol b/src/forge/Registry.sol index f148bba..e7a5a80 100644 --- a/src/forge/Registry.sol +++ b/src/forge/Registry.sol @@ -41,10 +41,8 @@ library Registry { deployCode(Suave.CONFIDENTIAL_INPUTS, type(ConfidentialInputsWrapper).creationCode); } - address constant dummyAddr = 0x1111000000000000000000000000000000000000; - function deployCode(address where, bytes memory creationCode) internal { - vm.etch(dummyAddr, creationCode); + vm.etch(where, creationCode); (, bytes memory runtimeBytecode) = dummyAddr.call(""); vm.etch(where, runtimeBytecode); From 17da41fb802af57f23648f6dc11d3ababce320e8 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 23 Jan 2024 22:23:02 +0000 Subject: [PATCH 3/6] Fix more --- src/forge/Registry.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/forge/Registry.sol b/src/forge/Registry.sol index e7a5a80..753ff6f 100644 --- a/src/forge/Registry.sol +++ b/src/forge/Registry.sol @@ -43,7 +43,7 @@ library Registry { function deployCode(address where, bytes memory creationCode) internal { vm.etch(where, creationCode); - (, bytes memory runtimeBytecode) = dummyAddr.call(""); + (, bytes memory runtimeBytecode) = where.call(""); vm.etch(where, runtimeBytecode); } From 74321607f433f026839525a7a6e1009282e6e1e0 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 23 Jan 2024 22:24:53 +0000 Subject: [PATCH 4/6] More stuff --- src/forge/Registry.sol | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/forge/Registry.sol b/src/forge/Registry.sol index 753ff6f..39ce7c5 100644 --- a/src/forge/Registry.sol +++ b/src/forge/Registry.sol @@ -15,7 +15,7 @@ library Registry { function enableLib(address addr) public { // code for Forge proxy connector - deployCode(addr, type(Connector).creationCode); + vm.etch(addr, type(Connector).runtimeCode); } function enable() public { @@ -38,13 +38,6 @@ library Registry { enableLib(Suave.SUBMIT_ETH_BLOCK_TO_RELAY); // enable is confidential wrapper - deployCode(Suave.CONFIDENTIAL_INPUTS, type(ConfidentialInputsWrapper).creationCode); - } - - function deployCode(address where, bytes memory creationCode) internal { - vm.etch(where, creationCode); - (, bytes memory runtimeBytecode) = where.call(""); - - vm.etch(where, runtimeBytecode); + vm.etch(Suave.CONFIDENTIAL_INPUTS, type(ConfidentialInputsWrapper).runtimeCode); } } From fae5c4e57a29d0270a726919181b9734acc3e22b Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 23 Jan 2024 23:11:17 +0000 Subject: [PATCH 5/6] Modify the tool --- src/forge/Connector.sol | 10 +-- src/forge/Registry.sol | 23 ++----- src/forge/SuaveAddrs.sol | 31 +++++++++ tools/forge-gen/foundry.toml | 4 -- tools/forge-gen/main.go | 122 ++++------------------------------- 5 files changed, 51 insertions(+), 139 deletions(-) create mode 100644 src/forge/SuaveAddrs.sol delete mode 100644 tools/forge-gen/foundry.toml diff --git a/src/forge/Connector.sol b/src/forge/Connector.sol index b2be8d5..45f0c99 100644 --- a/src/forge/Connector.sol +++ b/src/forge/Connector.sol @@ -1,14 +1,10 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.8; -interface connectorVM { - function ffi(string[] calldata commandInput) external view returns (bytes memory result); -} - -contract Connector { - connectorVM constant vm = connectorVM(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); +import "forge-std/Test.sol"; - function forgeIt(bytes memory addr, bytes memory data) internal view returns (bytes memory) { +contract Connector is Test { + function forgeIt(bytes memory addr, bytes memory data) internal returns (bytes memory) { string memory addrHex = iToHex(addr); string memory dataHex = iToHex(data); diff --git a/src/forge/Registry.sol b/src/forge/Registry.sol index 39ce7c5..71419c8 100644 --- a/src/forge/Registry.sol +++ b/src/forge/Registry.sol @@ -5,6 +5,7 @@ pragma solidity ^0.8.8; import "../suavelib/Suave.sol"; import "./Connector.sol"; import "./ConfidentialInputs.sol"; +import "./SuaveAddrs.sol"; interface registryVM { function etch(address, bytes calldata) external; @@ -19,23 +20,11 @@ library Registry { } function enable() public { - enableLib(Suave.IS_CONFIDENTIAL_ADDR); - enableLib(Suave.BUILD_ETH_BLOCK); - enableLib(Suave.CONFIDENTIAL_RETRIEVE); - enableLib(Suave.CONFIDENTIAL_STORE); - enableLib(Suave.DO_HTTPREQUEST); - enableLib(Suave.ETHCALL); - enableLib(Suave.EXTRACT_HINT); - enableLib(Suave.FETCH_DATA_RECORDS); - enableLib(Suave.FILL_MEV_SHARE_BUNDLE); - enableLib(Suave.NEW_BUILDER); - enableLib(Suave.NEW_DATA_RECORD); - enableLib(Suave.SIGN_ETH_TRANSACTION); - enableLib(Suave.SIGN_MESSAGE); - enableLib(Suave.SIMULATE_BUNDLE); - enableLib(Suave.SIMULATE_TRANSACTION); - enableLib(Suave.SUBMIT_BUNDLE_JSON_RPC); - enableLib(Suave.SUBMIT_ETH_BLOCK_TO_RELAY); + // enable all suave libraries + address[] memory addrList = SuaveAddrs.getSuaveAddrs(); + for (uint256 i = 0; i < addrList.length; i++) { + enableLib(addrList[i]); + } // enable is confidential wrapper vm.etch(Suave.CONFIDENTIAL_INPUTS, type(ConfidentialInputsWrapper).runtimeCode); diff --git a/src/forge/SuaveAddrs.sol b/src/forge/SuaveAddrs.sol new file mode 100644 index 0000000..0ddf95c --- /dev/null +++ b/src/forge/SuaveAddrs.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: UNLICENSED +// DO NOT edit this file. Code generated by forge-gen. +pragma solidity ^0.8.8; + +import "../suavelib/Suave.sol"; + +library SuaveAddrs { + function getSuaveAddrs() external pure returns (address[] memory) { + address[] memory addrList = new address[](17); + + addrList[0] = Suave.IS_CONFIDENTIAL_ADDR; + addrList[1] = Suave.BUILD_ETH_BLOCK; + addrList[2] = Suave.CONFIDENTIAL_RETRIEVE; + addrList[3] = Suave.CONFIDENTIAL_STORE; + addrList[4] = Suave.DO_HTTPREQUEST; + addrList[5] = Suave.ETHCALL; + addrList[6] = Suave.EXTRACT_HINT; + addrList[7] = Suave.FETCH_DATA_RECORDS; + addrList[8] = Suave.FILL_MEV_SHARE_BUNDLE; + addrList[9] = Suave.NEW_BUILDER; + addrList[10] = Suave.NEW_DATA_RECORD; + addrList[11] = Suave.SIGN_ETH_TRANSACTION; + addrList[12] = Suave.SIGN_MESSAGE; + addrList[13] = Suave.SIMULATE_BUNDLE; + addrList[14] = Suave.SIMULATE_TRANSACTION; + addrList[15] = Suave.SUBMIT_BUNDLE_JSON_RPC; + addrList[16] = Suave.SUBMIT_ETH_BLOCK_TO_RELAY; + + return addrList; + } +} diff --git a/tools/forge-gen/foundry.toml b/tools/forge-gen/foundry.toml deleted file mode 100644 index a0ecbf9..0000000 --- a/tools/forge-gen/foundry.toml +++ /dev/null @@ -1,4 +0,0 @@ -[profile.default] -src="src-forge-test" -solc_version = "0.8.23" -bytecode_hash = "none" \ No newline at end of file diff --git a/tools/forge-gen/main.go b/tools/forge-gen/main.go index 6566bc0..c1eea36 100644 --- a/tools/forge-gen/main.go +++ b/tools/forge-gen/main.go @@ -2,7 +2,6 @@ package main import ( "bytes" - "encoding/json" "flag" "fmt" "html/template" @@ -20,19 +19,13 @@ func main() { flag.BoolVar(&applyFlag, "apply", false, "write to file") flag.Parse() - bytecode, err := getForgeConnectorBytecode() - if err != nil { - fmt.Printf("failed to get forge wrapper bytecode: %v\n", err) - os.Exit(1) - } - precompileNames, err := getPrecompileNames() if err != nil { fmt.Printf("failed to get precompile names: %v\n", err) os.Exit(1) } - if err := applyTemplate(bytecode, precompileNames); err != nil { + if err := applyTemplate(precompileNames); err != nil { fmt.Printf("failed to apply template: %v\n", err) os.Exit(1) } @@ -44,40 +37,24 @@ pragma solidity ^0.8.8; import "../suavelib/Suave.sol"; -interface registryVM { - function etch(address, bytes calldata) external; -} - -library Registry { - registryVM constant vm = registryVM(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - function enableLib(address addr) public { - // code for Wrapper - bytes memory code = - hex"{{.Bytecodes.Connector}}"; - vm.etch(addr, code); - - // enable is confidential wrapper - bytes memory confidentialCode = - hex"{{.Bytecodes.Confidential}}"; - vm.etch(Suave.CONFIDENTIAL_INPUTS, confidentialCode); - } - - function enable() public { - {{range .PrecompileNames}} - enableLib(Suave.{{.}}); +library SuaveAddrs { + function getSuaveAddrs() external pure returns (address[] memory) { + address[] memory addrList = new address[]({{ len .PrecompileNames }}); + {{range $indx, $elem := .PrecompileNames}} + addrList[{{ $indx }}] = Suave.{{ $elem}}; {{- end}} - } + + return addrList; + } }` -func applyTemplate(bytecodes *forgeWrapperBytecodes, precompileNames []string) error { +func applyTemplate(precompileNames []string) error { t, err := template.New("template").Parse(templateFile) if err != nil { return err } input := map[string]interface{}{ - "Bytecodes": bytecodes, "PrecompileNames": precompileNames, } @@ -92,7 +69,7 @@ func applyTemplate(bytecodes *forgeWrapperBytecodes, precompileNames []string) e } if applyFlag { - if err := os.WriteFile(resolvePath("../../src/forge/Registry.sol"), []byte(str), 0644); err != nil { + if err := os.WriteFile(resolvePath("../../src/forge/SuaveAddrs.sol"), []byte(str), 0644); err != nil { return err } } else { @@ -101,69 +78,6 @@ func applyTemplate(bytecodes *forgeWrapperBytecodes, precompileNames []string) e return nil } -type forgeWrapperBytecodes struct { - Connector string - Confidential string -} - -func getForgeConnectorBytecode() (*forgeWrapperBytecodes, error) { - mirror := func(from, to string) error { - connectorSrc, err := os.ReadFile(resolvePath(from)) - if err != nil { - return err - } - if err := writeFile(resolvePath(to), connectorSrc); err != nil { - return err - } - return nil - } - - // mirror the Connector.sol contract to ./src - if err := mirror("../../src/forge/Connector.sol", "./src-forge-test/Connector.sol"); err != nil { - return nil, err - } - // mirror the is confidential solver - if err := mirror("../../src/forge/ConfidentialInputs.sol", "./src-forge-test/ConfidentialInputs.sol"); err != nil { - return nil, err - } - - // compile the Connector contract with forge and the local configuration - if _, err := execForgeCommand([]string{"build", "--config-path", resolvePath("./foundry.toml")}, ""); err != nil { - return nil, err - } - - decodeBytecode := func(name string) (string, error) { - abiContent, err := os.ReadFile(resolvePath(name)) - if err != nil { - return "", err - } - - var abiArtifact struct { - DeployedBytecode struct { - Object string - } - } - if err := json.Unmarshal(abiContent, &abiArtifact); err != nil { - return "", err - } - - bytecode := abiArtifact.DeployedBytecode.Object[2:] - return bytecode, nil - } - - res := &forgeWrapperBytecodes{} - var err error - - if res.Connector, err = decodeBytecode("./out/Connector.sol/Connector.json"); err != nil { - return nil, err - } - if res.Confidential, err = decodeBytecode("./out/ConfidentialInputs.sol/ConfidentialInputsWrapper.json"); err != nil { - return nil, err - } - - return res, nil -} - func getPrecompileNames() ([]string, error) { content, err := os.ReadFile("./src/suavelib/Suave.sol") if err != nil { @@ -222,20 +136,6 @@ func execForgeCommand(args []string, stdin string) (string, error) { return outBuf.String(), nil } -// writeFile creates the parent directory if not found -// and then writes the file to the path. -func writeFile(path string, content []byte) error { - dir := filepath.Dir(path) - if err := os.MkdirAll(dir, 0755); err != nil { - return err - } - - if err := os.WriteFile(path, content, 0644); err != nil { - return err - } - return nil -} - func resolvePath(path string) string { // Get the caller's file path. _, filename, _, _ := runtime.Caller(1) From 8c666decd38b6eef6b806afb9faabb8ea977dd4d Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 23 Jan 2024 23:25:53 +0000 Subject: [PATCH 6/6] Simplify more --- src/forge/Registry.sol | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/forge/Registry.sol b/src/forge/Registry.sol index 71419c8..b82a092 100644 --- a/src/forge/Registry.sol +++ b/src/forge/Registry.sol @@ -14,16 +14,12 @@ interface registryVM { library Registry { registryVM constant vm = registryVM(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - function enableLib(address addr) public { - // code for Forge proxy connector - vm.etch(addr, type(Connector).runtimeCode); - } - function enable() public { // enable all suave libraries address[] memory addrList = SuaveAddrs.getSuaveAddrs(); for (uint256 i = 0; i < addrList.length; i++) { - enableLib(addrList[i]); + // code for Forge proxy connector + vm.etch(addrList[i], type(Connector).runtimeCode); } // enable is confidential wrapper