diff --git a/.gitignore b/.gitignore index 1cb5839..12aa7a2 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ lcov.info !.yarn/versions lib/* + +scc-report.* +scm-report.* diff --git a/.solhint.json b/.solhint.json index cbd8d7a..8e53812 100644 --- a/.solhint.json +++ b/.solhint.json @@ -6,13 +6,13 @@ "compiler-version": ["error", "0.8.28"], "no-inline-assembly": "off", "no-unused-import": "error", - "func-named-parameters": "error", + "func-named-parameters": ["warn", 5], "func-visibility": ["error", { "ignoreConstructors": true }], "reason-string": ["warn", { "maxLength": 64 }], "immutable-vars-naming": ["error", { "immutablesAsConstants": true }], "var-name-mixedcase": "warn", "func-name-mixedcase": "warn", - "foundry-test-functions": ["warn", ["setUp"]], + "foundry-test-functions": ["off", ["setUp"]], "no-global-import": "error", "ordering": "warn", "gas-calldata-parameters": "error", diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz index 90db52a..d2fd580 100644 Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ diff --git a/artifacts/holesky/deploy-holesky.json b/artifacts/holesky/deploy-holesky.json index 689e742..83b7286 100644 --- a/artifacts/holesky/deploy-holesky.json +++ b/artifacts/holesky/deploy-holesky.json @@ -1,7 +1,7 @@ { "CCCP": "0x5e30e8958a4361ac7a7C4FcE978FF18f70E915a2", - "CCCPImpl": "0x73CCA4DD9E58Fa3aBCA22d55ee81AE613d958980", + "CCCPImpl": "0x7c178B9B797C6ea6776A784C22A0f95a79385c9b", "ChainId": 17000, "DeployParams": "0x00000000000000000000000028fab2059c713a7f9d8c86db49f9bb0e96af1ef8636f6d6d756e6974792d6f6e636861696e2d7631000000000000000000000000000000000000000000000000401fd888b5e41113b7c0c47725a742bbc3a083ef000000000000000000000000401fd888b5e41113b7c0c47725a742bbc3a083ef00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000f4240", "LidoLocator": "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" -} \ No newline at end of file +} diff --git a/artifacts/holesky/transactions.json b/artifacts/holesky/transactions.json index 0749a62..3445f4a 100644 --- a/artifacts/holesky/transactions.json +++ b/artifacts/holesky/transactions.json @@ -42,6 +42,48 @@ }, "additionalContracts": [], "isFixedGasLimit": false + }, + { + "hash": "0x138cad03fbe5a1d4f10a6765b4328249858670248d32bb3f8fbbde49ac17a339", + "transactionType": "CREATE", + "contractName": "CCCP", + "contractAddress": "0x7c178b9b797c6ea6776a784c22a0f95a79385c9b", + "function": null, + "arguments": [ + "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8", + "0x636f6d6d756e6974792d6f6e636861696e2d7631000000000000000000000000" + ], + "transaction": { + "from": "0x401fd888b5e41113b7c0c47725a742bbc3a083ef", + "gas": "0x386e1c", + "value": "0x0", + "input": "0x610100604052348015610010575f5ffd5b506040516134e03803806134e083398101604081905261002f91610245565b6040517f6c69646f2e636363702e73746f726167652e436f6e66696753746f7261676500602082015260ff1990600190603f01604051602081830303815290604052805190602001205f1c610084919061027c565b60405160200161009691815260200190565b60408051601f198184030181529082905280516020918201209290921660805260ff19916001916100fb91017f6c69646f2e636363702e73746f726167652e4f70657261746f7253746174657381526653746f7261676560c81b602082015260270190565b604051602081830303815290604052805190602001205f1c61011d919061027c565b60405160200161012f91815260200190565b60408051601f1981840301815291905280516020909101201660a0526001600160a01b03821661017257604051630f05a38b60e41b815260040160405180910390fd5b6001600160a01b03821660c05260e081905261018c610193565b50506102a1565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156101e35760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146102425780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f5f60408385031215610256575f5ffd5b82516001600160a01b038116811461026c575f5ffd5b6020939093015192949293505050565b8181038181111561029b57634e487b7160e01b5f52601160045260245ffd5b92915050565b60805160a05160c05160e0516131d461030c5f395f611d0c01525f818161049801526123e801525f81816113b401528181611459015281816114b4015281816116d70152611ef501525f81816110670152818161188201528181611b42015261230f01526131d45ff3fe608060405234801561000f575f5ffd5b50600436106101d1575f3560e01c80638aa10435116100fe578063ba6bc8d51161009e578063d547741f1161006e578063d547741f1461046d578063d6dc6ae714610480578063dbba4b4814610493578063fc3372f5146104ba575f5ffd5b8063ba6bc8d514610404578063c3f909d414610417578063ca15c87314610452578063d4eec5a614610465575f5ffd5b8063a217fddf116100d9578063a217fddf146103b6578063a3246ad3146103bd578063a3714e07146103dd578063ad32563d146103f0575f5ffd5b80638aa10435146103585780639010d07c1461037857806391d14854146103a3575f5ffd5b8063389ed267116101745780635c975abb116101445780635c975abb1461031357806370bc09f61461032a5780638456cb591461033d578063893d004e14610345575f5ffd5b8063389ed267146102ae5780633c074eb3146102d55780633f4ba83a146102e85780635865c60c146102f0575f5ffd5b80632de03aa1116101af5780632de03aa11461024e5780632de0920c146102755780632f2ff15d1461028857806336568abe1461029b575f5ffd5b806301ffc9a7146101d557806313e09453146101fd578063248a9ca314610212575b5f5ffd5b6101e86101e3366004612646565b6104cd565b60405190151581526020015b60405180910390f35b61021061020b366004612695565b6104f7565b005b610240610220366004612702565b5f9081525f5160206131885f395f51905f52602052604090206001015490565b6040519081526020016101f4565b6102407f2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c781565b610210610283366004612729565b6106ba565b6102106102963660046127f1565b61094a565b6102106102a93660046127f1565b610980565b6102407f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d81565b6102106102e336600461281f565b6109b8565b610210610a43565b6103036102fe36600461284b565b610a78565b6040516101f4949392919061289e565b5f5160206131a85f395f51905f525460ff166101e8565b61021061033836600461295b565b610aa8565b610210610ad2565b6102106103533660046129b4565b610b04565b610360610bf2565b6040516001600160401b0390911681526020016101f4565b61038b6103863660046129fc565b610c29565b6040516001600160a01b0390911681526020016101f4565b6101e86103b13660046127f1565b610c56565b6102405f81565b6103d06103cb366004612702565b610c8c565b6040516101f49190612a1c565b6103036103eb36600461281f565b610cbc565b6102405f5160206131685f395f51905f5281565b610210610412366004612a67565b610cee565b61041f610dfe565b604080516001600160401b03958616815293851660208501529184169183019190915290911660608201526080016101f4565b610240610460366004612702565b610e18565b610210610e3c565b61021061047b3660046127f1565b610f17565b61021061048e36600461281f565b610f47565b61038b7f000000000000000000000000000000000000000000000000000000000000000081565b6102106104c8366004612a90565b611011565b5f6001600160e01b03198216635a05180f60e01b14806104f157506104f182611103565b92915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f8115801561053b5750825b90505f826001600160401b031660011480156105565750303b155b905081158015610564575080155b156105825760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156105ac57845460ff60401b1916600160401b1785555b6001600160a01b038a166105d3576040516319467aa760e11b815260040160405180910390fd5b6105db611137565b6105e3611149565b6105ed5f8b611151565b506106055f5160206131685f395f51905f528b611151565b506106307f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d8b611151565b5061065b7f2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c78b611151565b5061066889898989611193565b83156106ae57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050565b6106c26111f8565b6106ca61258c565b6001600160a01b0386166106f157604051634434240960e11b815260040160405180910390fd5b6106fc818989611228565b80606001516001600160a01b0316336001600160a01b031614610732576040516349ad9b0960e11b815260040160405180910390fd5b8060a0015161075457604051631a8660cb60e01b815260040160405180910390fd5b6001600160401b038716604089901b62ffffff60401b16175f6107768261123c565b90505f610782826112a2565b8051909150156107a5576040516342ee68b560e01b815260040160405180910390fd5b80604001516107c7576040516328a5715760e21b815260040160405180910390fd5b6107d1838a6113a2565b6040516001600160a01b038a1681526001600160401b038b169062ffffff8d16907fb5a535addaaf9c7dbe0b8728def4b0e19391fe6471ac14e0a2c22d8ee83a4ebc9060200160405180910390a3610857836040518060600160405280436001600160401b031681526020015f6001600160401b031681526020015f15158152506114e0565b61086384848a8a611541565b604080516020601f8801819004810282018301835281018781526108a69286929182918b908b90819085018382808284375f9201919091525050509152506115bb565b896001600160401b03168b62ffffff167f8ae0affaa3c6c49aee34fd262b42a1ed56bf92a700857bddf013a00a99bff4ef88886040516108e7929190612acd565b60405180910390a36040516001600160a01b038a1681526001600160401b038b169062ffffff8d16907f742aa8302eca1011d41495047d2d195954b0f91a24ac18e221a1788507e42d7d9060200160405180910390a35050505050505050505050565b5f8281525f5160206131885f395f51905f526020526040902060010154610970816115da565b61097a8383611151565b50505050565b6001600160a01b03811633146109a95760405163334bd91960e11b815260040160405180910390fd5b6109b382826115e4565b505050565b5f5160206131685f395f51905f526109cf816115da565b5f6109da848461161d565b90505f6109e68261123c565b9050806040015115610a02575f6040820152610a0282826114e0565b6040516001600160401b0385169062ffffff8716907f2b140fd22a9c33bfd560c6a50d8f4f235e6d85feeb1629b97b62b488f3c95004905f90a35050505050565b7f2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7610a6d816115da565b610a75611666565b50565b5f5f5f610a836125c0565b5f610a8d866116c5565b9050610a9881611725565b9450945094509450509193509193565b5f5160206131685f395f51905f52610abf816115da565b610acb85858585611193565b5050505050565b7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d610afc816115da565b610a756117c7565b610b0c6111f8565b6001600160a01b038116610b3357604051634434240960e11b815260040160405180910390fd5b610b3b61258c565b610b46818585611228565b80606001516001600160a01b0316336001600160a01b031614610b7c576040516349ad9b0960e11b815260040160405180910390fd5b610b9d62ffffff60401b604086901b166001600160401b03851617836113a2565b6040516001600160a01b03831681526001600160401b0384169062ffffff8616907fb5a535addaaf9c7dbe0b8728def4b0e19391fe6471ac14e0a2c22d8ee83a4ebc906020015b60405180910390a350505050565b5f610c247ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00546001600160401b031690565b905090565b5f8281525f5160206131485f395f51905f52602081905260408220610c4e908461180f565b949350505050565b5f9182525f5160206131885f395f51905f52602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f8181525f5160206131485f395f51905f526020819052604090912060609190610cb59061181a565b9392505050565b5f5f5f610cc76125c0565b5f610cd2878761161d565b9050610cdd81611725565b929a91995097509095509350505050565b610cf66111f8565b5f610d00336116c5565b90505f610d14610d0f8361123c565b6112a2565b8051909150610d3657604051631a8660cb60e01b815260040160405180910390fd5b5f610d4083611826565b9050805f01516001600160401b0316856001600160401b03161180610d7a575080602001516001600160401b0316846001600160401b0316105b80610db1575080516001600160401b038681169116148015610db1575080602001516001600160401b0316846001600160401b0316145b15610dcf5760405163c7f544bb60e01b815260040160405180910390fd5b610dd761258c565b604084901c84610de8838383611228565b610df483878a8a611541565b5050505050505050565b5f5f5f5f610e0a611874565b935093509350935090919293565b5f8181525f5160206131485f395f51905f52602081905260408220610cb5906118ea565b610e446111f8565b5f610e4e336116c5565b90505f610e5a8261123c565b90505f610e66826112a2565b8051909150610e8857604051631a8660cb60e01b815260040160405180910390fd5b8060600151610eaa57604051630eedec1160e31b815260040160405180910390fd5b6001600160401b0343166020830152610ec383836114e0565b604080515f81529084901c9084906001600160401b0382169062ffffff8416907fd6b972cb40d3e29a33d9ccde1b9db78d12306458943f95974c2856d9093d46849060200160405180910390a35050505050565b5f8281525f5160206131885f395f51905f526020526040902060010154610f3d816115da565b61097a83836115e4565b5f5160206131685f395f51905f52610f5e816115da565b5f610f69848461161d565b90505f610f758261123c565b90505f610f81826112a2565b8051909150610fa357604051631a8660cb60e01b815260040160405180910390fd5b6001600160401b034316602083015260016040830152610fc383836114e0565b604051600181526001600160401b0386169062ffffff8816907fd6b972cb40d3e29a33d9ccde1b9db78d12306458943f95974c2856d9093d46849060200160405180910390a3505050505050565b5f5160206131685f395f51905f52611028816115da565b61103061258c565b61103a81866118f3565b6040805180820182526001600160401b038086168252861515602080840191825262ffffff8a165f9081527f0000000000000000000000000000000000000000000000000000000000000000909152939093209151825493511515600160401b0268ffffffffffffffffff19909416911617919091179055604080516001600160401b0385168152851515602082015262ffffff8716917f55bd0114bd34303292838dd2bc70c974c9eea7858dc4fb3716662d439ec3ae12910160405180910390a25050505050565b5f6001600160e01b03198216637965db0b60e01b14806104f157506301ffc9a760e01b6001600160e01b03198316146104f1565b61113f611989565b6111476119d2565b565b611147611989565b5f5f5160206131485f395f51905f528161116b85856119f2565b90508015610c4e575f85815260208390526040902061118a9085611a93565b50949350505050565b61119f84848484611aa7565b604080516001600160401b0386811682528581166020830152848116828401528316606082015290517f84d25455db084cf777a0a4a00fcc28946b3a2ebc5cc866ef8820ab8571dbdd369181900360800190a150505050565b5f5160206131a85f395f51905f525460ff16156111475760405163d93c066560e01b815260040160405180910390fd5b61123283836118f3565b6109b38382611be4565b604080516060810182525f808252602082018190529181019190915261126182611eef565b60408051606081018252600292909201546001600160401b038082168452600160401b8204166020840152600160801b900460ff1615159082015292915050565b604080516080810182525f808252602082018190529181018290526060810191909152435f806112d0611874565b5050915091505f5f86602001516001600160401b03161180156113135750836001600160401b03168287602001516113089190612b0f565b6001600160401b0316105b90505f5f875f01516001600160401b031611801561132f575081155b90505f8115801561134257508760400151155b90505f828015611370575088516001600160401b03881690611365908890612b0f565b6001600160401b0316105b604080516080810182529415158552941515602085015291151593830193909352151560608201529695505050505050565b6001600160a01b0381165f90815260017f000000000000000000000000000000000000000000000000000000000000000001602052604090205480158015906113eb5750828114155b156114095760405163324e8e5f60e01b815260040160405180910390fd5b5f61141384611eef565b80549091506001600160a01b031680158015906114425750836001600160a01b0316816001600160a01b031614155b15611482576001600160a01b0381165f90815260017f00000000000000000000000000000000000000000000000000000000000000000160205260408120555b50805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03939093169283179055505f9081527f00000000000000000000000000000000000000000000000000000000000000006001016020526040902055565b806114ea83611eef565b8151600291909101805460208401516040909401511515600160801b0260ff60801b196001600160401b03958616600160401b026001600160801b0319909316959094169490941717919091169190911790555050565b61155084608001518383611f1e565b835161155d908383611fa2565b611568838383612043565b604080850151855182516001600160401b03868116825285811660208301529092169262ffffff909116917f9841e87ed1a3c39f013566d8bc2c2119007cfb8c591ccde84c6e012e8891410c9101610be4565b806115c583611eef565b8151600391909101908190610acb9082612bbe565b610a7581336120b1565b5f5f5160206131485f395f51905f52816115fe85856120f2565b90508015610c4e575f85815260208390526040902061118a908561216b565b6001600160401b038116604083901b62ffffff60401b16175f61163f8261217f565b6001600160a01b0316036104f1576040516325ec6c1f60e01b815260040160405180910390fd5b61166e612199565b5f5160206131a85f395f51905f52805460ff191681557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a150565b6001600160a01b0381165f90815260017f0000000000000000000000000000000000000000000000000000000000000000016020526040812054908190036117205760405163fe0a2bb160e01b815260040160405180910390fd5b919050565b5f5f5f6117306125c0565b61173861258c565b604086901c945085935061174d818686611228565b611756866121c8565b91505f61176683604001516112a2565b90505f611775835f0151612304565b915050815f01518015611786575080155b801561179357508260a001515b80156117ae57505f5160206131a85f395f51905f525460ff16155b9450825f01518360400151965096505050509193509193565b6117cf6111f8565b5f5160206131a85f395f51905f52805460ff191660011781557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258336116a7565b5f610cb58383612366565b60605f610cb58361238c565b604080518082019091525f808252602082015261184282611eef565b60408051808201909152600191909101546001600160401b038082168352600160401b90910416602082015292915050565b6040805160808101825260017f000000000000000000000000000000000000000000000000000000000000000001546001600160401b03808216808452600160401b8304821660208501819052600160801b84048316958501869052600160c01b90930490911660609093018390529390929190565b5f6104f1825490565b5f6118fc6123e5565b604051630bc1bb1960e41b815262ffffff841660048201526001600160a01b03919091169063bc1bb190906024015f60405180830381865afa158015611944573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261196b9190810190612d8f565b62ffffff9092168352506020908101516001600160a01b0316910152565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661114757604051631afcd79f60e31b815260040160405180910390fd5b6119da611989565b5f5160206131a85f395f51905f52805460ff19169055565b5f5f5160206131885f395f51905f52611a0b8484610c56565b611a8a575f848152602082815260408083206001600160a01b03871684529091529020805460ff19166001179055611a403390565b6001600160a01b0316836001600160a01b0316857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019150506104f1565b5f9150506104f1565b5f610cb5836001600160a01b038416612466565b816001600160401b03165f03611ad05760405163ad617a0b60e01b815260040160405180910390fd5b806001600160401b03165f03611af857604051628faa1f60e61b815260040160405180910390fd5b6040518060800160405280856001600160401b03168152602001846001600160401b03168152602001836001600160401b03168152602001826001600160401b0316815250611b647f000000000000000000000000000000000000000000000000000000000000000090565b81516001919091018054602084015160408501516060909501516001600160401b03908116600160c01b026001600160c01b03968216600160801b02969096166fffffffffffffffffffffffffffffffff928216600160401b026001600160801b0319909416919095161791909117169190911791909117905550505050565b815162ffffff165f03611c0a57604051634632571560e01b815260040160405180910390fd5b5f82602001516001600160a01b031663a70c70e46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c4b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c6f9190612ec0565b9050806001600160401b0316826001600160401b031610611ca35760405163b9aa612760e01b815260040160405180910390fd5b5f83602001516001600160a01b03166315dae03e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ce4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d089190612ec0565b90507f00000000000000000000000000000000000000000000000000000000000000008103611e46576020840151604051630bc5f72160e31b81526001600160401b03851660048201526001600160a01b03821690635e2fb90890602401602060405180830381865afa158015611d81573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611da59190612ee2565b151560a08601526040516365c14dc760e01b81526001600160401b03851660048201525f906001600160a01b038316906365c14dc7906024016101e060405180830381865afa158015611dfa573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e1e9190612f10565b6101808101516001600160a01b031660608801525163ffffffff1660808701525061097a9050565b6020840151604051632695a60f60e21b81526001600160401b03851660048201525f60248201526001600160a01b03821690639a56983c906044015f60405180830381865afa158015611e9b573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611ec29190810190613039565b6001600160401b031660808b015250506001600160a01b0316606088015250151560a08601525050505050565b5f9081527f00000000000000000000000000000000000000000000000000000000000000006020526040902090565b806001600160401b0316826001600160401b03161115611f515760405163c7f544bb60e01b815260040160405180910390fd5b826001600160401b0316816001600160401b0316101580611f845750826001600160401b0316826001600160401b031610155b156109b357604051637ba485c560e01b815260040160405180910390fd5b5f611fab611874565b50925050505f5f611fbb86612304565b915091508015611fde57604051630dbfe5fd60e31b815260040160405180910390fd5b5f611fe986866130d2565b611ff4906001612b0f565b90505f6001600160401b0384161561200c578361200e565b845b9050806001600160401b0316826001600160401b03161115610df457604051631d1f75fb60e31b815260040160405180910390fd5b6040518060400160405280836001600160401b03168152602001826001600160401b031681525061207384611eef565b815160019190910180546020909301516001600160401b03908116600160401b026001600160801b0319909416921691909117919091179055505050565b6120bb8282610c56565b6120ee5760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440160405180910390fd5b5050565b5f5f5160206131885f395f51905f5261210b8484610c56565b15611a8a575f848152602082815260408083206001600160a01b0387168085529252808320805460ff1916905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a460019150506104f1565b5f610cb5836001600160a01b0384166124b2565b5f61218982611eef565b546001600160a01b031692915050565b5f5160206131a85f395f51905f525460ff1661114757604051638dfc202b60e01b815260040160405180910390fd5b6121d06125c0565b6121d982611eef565b6040805160808101825282546001600160a01b031681528151808301835260018401546001600160401b038082168352600160401b918290048116602080850191909152808501939093528451606080820187526002880154808416835293840490921681850152600160801b90920460ff161515828601528385019190915283519182019093526003840180549294938501928290829061227a90612b42565b80601f01602080910402602001604051908101604052809291908181526020018280546122a690612b42565b80156122f15780601f106122c8576101008083540402835291602001916122f1565b820191905f5260205f20905b8154815290600101906020018083116122d457829003601f168201915b5050509190925250505090525092915050565b62ffffff165f9081527f000000000000000000000000000000000000000000000000000000000000000060209081526040918290208251808401909352546001600160401b038116808452600160401b90910460ff1615159290910182905291565b5f825f01828154811061237b5761237b6130f1565b905f5260205f200154905092915050565b6060815f018054806020026020016040519081016040528092919081815260200182805480156123d957602002820191905f5260205f20905b8154815260200190600101908083116123c5575b50505050509050919050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ef6c064c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612442573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c249190613105565b5f8181526001830160205260408120546124ab57508154600181810184555f8481526020808220909301849055845484825282860190935260409020919091556104f1565b505f6104f1565b5f8181526001830160205260408120548015611a8a575f6124d4600183613120565b85549091505f906124e790600190613120565b9050808214612546575f865f018281548110612505576125056130f1565b905f5260205f200154905080875f018481548110612525576125256130f1565b5f918252602080832090910192909255918252600188019052604090208390555b855486908061255757612557613133565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f9055600193505050506104f1565b6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180608001604052805f6001600160a01b0316815260200161260760405180604001604052805f6001600160401b031681526020015f6001600160401b031681525090565b8152604080516060810182525f80825260208281018290529282015291019081526020016126416040518060200160405280606081525090565b905290565b5f60208284031215612656575f5ffd5b81356001600160e01b031981168114610cb5575f5ffd5b6001600160a01b0381168114610a75575f5ffd5b6001600160401b0381168114610a75575f5ffd5b5f5f5f5f5f60a086880312156126a9575f5ffd5b85356126b48161266d565b945060208601356126c481612681565b935060408601356126d481612681565b925060608601356126e481612681565b915060808601356126f481612681565b809150509295509295909350565b5f60208284031215612712575f5ffd5b5035919050565b62ffffff81168114610a75575f5ffd5b5f5f5f5f5f5f5f60c0888a03121561273f575f5ffd5b873561274a81612719565b9650602088013561275a81612681565b9550604088013561276a8161266d565b9450606088013561277a81612681565b9350608088013561278a81612681565b925060a08801356001600160401b038111156127a4575f5ffd5b8801601f81018a136127b4575f5ffd5b80356001600160401b038111156127c9575f5ffd5b8a60208284010111156127da575f5ffd5b602082019350809250505092959891949750929550565b5f5f60408385031215612802575f5ffd5b8235915060208301356128148161266d565b809150509250929050565b5f5f60408385031215612830575f5ffd5b823561283b81612719565b9150602083013561281481612681565b5f6020828403121561285b575f5ffd5b8135610cb58161266d565b5f81516020845280518060208601528060208301604087015e5f604082870101526040601f19601f8301168601019250505092915050565b62ffffff851681526001600160401b03841660208201528215156040820152608060608201526001600160a01b0382511660808201525f60208301516001600160401b0381511660a08401526001600160401b0360208201511660c08401525060408301516001600160401b0381511660e08401526001600160401b036020820151166101008401526040810151151561012084015250606083015160e0610140840152612950610160840182612866565b979650505050505050565b5f5f5f5f6080858703121561296e575f5ffd5b843561297981612681565b9350602085013561298981612681565b9250604085013561299981612681565b915060608501356129a981612681565b939692955090935050565b5f5f5f606084860312156129c6575f5ffd5b83356129d181612719565b925060208401356129e181612681565b915060408401356129f18161266d565b809150509250925092565b5f5f60408385031215612a0d575f5ffd5b50508035926020909101359150565b602080825282518282018190525f918401906040840190835b81811015612a5c5783516001600160a01b0316835260209384019390920191600101612a35565b509095945050505050565b5f5f60408385031215612a78575f5ffd5b823561283b81612681565b8015158114610a75575f5ffd5b5f5f5f60608486031215612aa2575f5ffd5b8335612aad81612719565b92506020840135612abd81612a83565b915060408401356129f181612681565b60208152816020820152818360408301375f818301604090810191909152601f909201601f19160101919050565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b0381811683821601908111156104f1576104f1612afb565b634e487b7160e01b5f52604160045260245ffd5b600181811c90821680612b5657607f821691505b602082108103612b7457634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156109b357805f5260205f20601f840160051c81016020851015612b9f5750805b601f840160051c820191505b81811015610acb575f8155600101612bab565b81516001600160401b03811115612bd757612bd7612b2e565b612beb81612be58454612b42565b84612b7a565b6020601f821160018114612c1d575f8315612c065750848201515b5f19600385901b1c1916600184901b178455610acb565b5f84815260208120601f198516915b82811015612c4c5787850151825560209485019460019092019101612c2c565b5084821015612c6957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b6040516101a081016001600160401b0381118282101715612c9b57612c9b612b2e565b60405290565b6040516101e081016001600160401b0381118282101715612c9b57612c9b612b2e565b805161172081612719565b80516117208161266d565b805161ffff81168114611720575f5ffd5b805160ff81168114611720575f5ffd5b5f82601f830112612d0a575f5ffd5b81516001600160401b03811115612d2357612d23612b2e565b604051601f8201601f19908116603f011681016001600160401b0381118282101715612d5157612d51612b2e565b604052818152838201602001851015612d68575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b805161172081612681565b5f60208284031215612d9f575f5ffd5b81516001600160401b03811115612db4575f5ffd5b82016101a08185031215612dc6575f5ffd5b612dce612c78565b612dd782612cc4565b8152612de560208301612ccf565b6020820152612df660408301612cda565b6040820152612e0760608301612cda565b6060820152612e1860808301612cda565b6080820152612e2960a08301612ceb565b60a082015260c08201516001600160401b03811115612e46575f5ffd5b612e5286828501612cfb565b60c083015250612e6460e08301612d84565b60e082015261010082810151908201526101208083015190820152612e8c6101408301612cda565b610140820152612e9f6101608301612d84565b610160820152612eb26101808301612d84565b610180820152949350505050565b5f60208284031215612ed0575f5ffd5b5051919050565b805161172081612a83565b5f60208284031215612ef2575f5ffd5b8151610cb581612a83565b805163ffffffff81168114611720575f5ffd5b5f6101e0828403128015612f22575f5ffd5b50612f2b612ca1565b612f3483612efd565b8152612f4260208401612efd565b6020820152612f5360408401612efd565b6040820152612f6460608401612efd565b6060820152612f7560808401612efd565b6080820152612f8660a08401612efd565b60a0820152612f9760c08401612efd565b60c0820152612fa860e08401612ceb565b60e0820152612fba6101008401612efd565b610100820152612fcd6101208401612efd565b610120820152612fe06101408401612ccf565b610140820152612ff36101608401612ccf565b6101608201526130066101808401612ccf565b6101808201526130196101a08401612ccf565b6101a082015261302c6101c08401612ed7565b6101c08201529392505050565b5f5f5f5f5f5f60c0878903121561304e575f5ffd5b865161305981612a83565b60208801519096506001600160401b03811115613074575f5ffd5b61308089828a01612cfb565b95505060408701516130918161266d565b60608801519094506130a281612681565b60808801519093506130b381612681565b60a08801519092506130c481612681565b809150509295509295509295565b6001600160401b0382811682821603908111156104f1576104f1612afb565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215613115575f5ffd5b8151610cb58161266d565b818103818111156104f1576104f1612afb565b634e487b7160e01b5f52603160045260245ffdfec1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e82371705932000794daa56950487582951e8db2fdbcbee68c2223c65641d0aa02a3afc64f9a86f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300a164736f6c634300081c000a00000000000000000000000028fab2059c713a7f9d8c86db49f9bb0e96af1ef8636f6d6d756e6974792d6f6e636861696e2d7631000000000000000000000000", + "nonce": "0x3f", + "chainId": "0x4268" + }, + "additionalContracts": [], + "isFixedGasLimit": false + }, + { + "hash": "0xde2a6f7ad4ba810948e3c1e417e3e6520a8828267a594d759ad12d0802fde233", + "transactionType": "CALL", + "contractName": "OssifiableProxy", + "contractAddress": "0x5e30e8958a4361ac7a7c4fce978ff18f70e915a2", + "function": "proxy__upgradeTo(address)", + "arguments": [ + "0x7c178B9B797C6ea6776A784C22A0f95a79385c9b" + ], + "transaction": { + "from": "0x401fd888b5e41113b7c0c47725a742bbc3a083ef", + "to": "0x5e30e8958a4361ac7a7c4fce978ff18f70e915a2", + "gas": "0xbcc3", + "value": "0x0", + "input": "0x3ebdd0eb0000000000000000000000007c178b9b797c6ea6776a784c22a0f95a79385c9b", + "nonce": "0x42", + "chainId": "0x4268" + }, + "additionalContracts": [], + "isFixedGasLimit": false } ], "receipts": [ @@ -217,6 +259,69 @@ "from": "0x401fd888b5e41113b7c0c47725a742bbc3a083ef", "to": null, "contractAddress": "0x5e30e8958a4361ac7a7c4fce978ff18f70e915a2" + }, + { + "status": "0x1", + "cumulativeGasUsed": "0x1af28aa", + "logs": [ + { + "address": "0x7c178b9b797c6ea6776a784c22a0f95a79385c9b", + "topics": [ + "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" + ], + "data": "0x000000000000000000000000000000000000000000000000ffffffffffffffff", + "blockHash": "0x3dfa399aa60c13bbfbe8f1cc9cd9cde07700ee525ec96fb788a6419a17c6ec28", + "blockNumber": "0x30ece5", + "blockTimestamp": "0x6792c828", + "transactionHash": "0x138cad03fbe5a1d4f10a6765b4328249858670248d32bb3f8fbbde49ac17a339", + "transactionIndex": "0x9", + "logIndex": "0x10d", + "removed": false + } + ], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000010000000000000000000000000004000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0x138cad03fbe5a1d4f10a6765b4328249858670248d32bb3f8fbbde49ac17a339", + "transactionIndex": "0x9", + "blockHash": "0x3dfa399aa60c13bbfbe8f1cc9cd9cde07700ee525ec96fb788a6419a17c6ec28", + "blockNumber": "0x30ece5", + "gasUsed": "0x2b6865", + "effectiveGasPrice": "0xf424f", + "from": "0x401fd888b5e41113b7c0c47725a742bbc3a083ef", + "to": null, + "contractAddress": "0x7c178b9b797c6ea6776a784c22a0f95a79385c9b" + }, + { + "status": "0x1", + "cumulativeGasUsed": "0x1e030d3", + "logs": [ + { + "address": "0x5e30e8958a4361ac7a7c4fce978ff18f70e915a2", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000007c178b9b797c6ea6776a784c22a0f95a79385c9b" + ], + "data": "0x", + "blockHash": "0x3dfa399aa60c13bbfbe8f1cc9cd9cde07700ee525ec96fb788a6419a17c6ec28", + "blockNumber": "0x30ece5", + "blockTimestamp": "0x6792c828", + "transactionHash": "0xde2a6f7ad4ba810948e3c1e417e3e6520a8828267a594d759ad12d0802fde233", + "transactionIndex": "0xd", + "logIndex": "0x114", + "removed": false + } + ], + "logsBloom": "0x00000000000000000040000000000000400000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000020000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0xde2a6f7ad4ba810948e3c1e417e3e6520a8828267a594d759ad12d0802fde233", + "transactionIndex": "0xd", + "blockHash": "0x3dfa399aa60c13bbfbe8f1cc9cd9cde07700ee525ec96fb788a6419a17c6ec28", + "blockNumber": "0x30ece5", + "gasUsed": "0x8112", + "effectiveGasPrice": "0xf424f", + "from": "0x401fd888b5e41113b7c0c47725a742bbc3a083ef", + "to": "0x5e30e8958a4361ac7a7c4fce978ff18f70e915a2", + "contractAddress": null } ], "libraries": [], @@ -225,4 +330,4 @@ "timestamp": 1737475792, "chain": 17000, "commit": "ac812a4" -} \ No newline at end of file +} diff --git a/foundry.toml b/foundry.toml index fc0cdb2..c11bd55 100644 --- a/foundry.toml +++ b/foundry.toml @@ -18,7 +18,7 @@ block_gas_limit = 30_000_000 fuzz = { runs = 256 } gas_reports = [ - "CredibleCommitmentCurationProvider", + "CCCP", "CCCPDataStorage", "OssifiableProxy" ] diff --git a/package.json b/package.json index ff4acc5..856ef9d 100644 --- a/package.json +++ b/package.json @@ -8,17 +8,20 @@ "private": true, "scripts": { "lint:solhint": "solhint './src/**/*.sol'", - "lint:check": "prettier --check **.sol && yarn lint:solhint", - "lint:fix": "prettier --write **.sol", - "generate:diffyscan": "node script/generateDiffyscanContracts.js" + "lint:check": "forge fmt --check && yarn lint:solhint", + "lint:fix": "forge fmt", + "generate:diffyscan": "node script/generateDiffyscanContracts.js", + "scc:report": "scc src --sort names --no-cocomo --exclude-dir interfaces --by-file --format wide > scc-report.txt", + "scm:report": "solidity-code-metrics $(tree -f -i -I '*interfaces*' | grep '^./src.*sol' | xargs ls -d 2>/dev/null) > scm-report.md" }, "devDependencies": { "husky": "^9.1.7", - "lint-staged": "^15.3.0", + "lint-staged": "^15.4.2", "prettier": "^3.4.2", "prettier-plugin-solidity": "^1.4.2", - "solhint": "5.0.4", - "solhint-plugin-lido-csm": "https://github.com/lidofinance/solhint-plugin-lido-csm.git#0.3.3" + "solhint": "5.0.5", + "solhint-plugin-lido-csm": "https://github.com/lidofinance/solhint-plugin-lido-csm.git#0.3.3", + "solidity-code-metrics": "^0.0.28" }, "lint-staged": { "*": "prettier --ignore-unknown --write", diff --git a/script/DeployBase.s.sol b/script/DeployBase.s.sol index e383dcf..cee4679 100644 --- a/script/DeployBase.s.sol +++ b/script/DeployBase.s.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.28; import {Script} from "forge-std/Script.sol"; import {OssifiableProxy} from "../src/lib/proxy/OssifiableProxy.sol"; -import {CredibleCommitmentCurationProvider} from "../src/CredibleCommitmentCurationProvider.sol"; +import {CCCP} from "../src/CCCP.sol"; import {JsonObj, Json} from "./utils/Json.sol"; @@ -28,7 +28,7 @@ abstract contract DeployBase is Script { address internal deployer; uint256 internal pk; - CredibleCommitmentCurationProvider public cccp; + CCCP public cccp; error ChainIdMismatch(uint256 actual, uint256 expected); @@ -51,15 +51,14 @@ abstract contract DeployBase is Script { vm.startBroadcast(pk); { - address cccpImpl = - address(new CredibleCommitmentCurationProvider(config.lidoLocatorAddress, config.csModuleType)); + address cccpImpl = address(new CCCP(config.lidoLocatorAddress, config.csModuleType)); - cccp = CredibleCommitmentCurationProvider( + cccp = CCCP( _deployProxy( config.proxyAdmin, address(cccpImpl), abi.encodeCall( - CredibleCommitmentCurationProvider.initialize, + CCCP.initialize, ( config.committeeAddress, config.optInMinDurationBlocks, diff --git a/src/CredibleCommitmentCurationProvider.sol b/src/CCCP.sol similarity index 74% rename from src/CredibleCommitmentCurationProvider.sol rename to src/CCCP.sol index e814a2d..6b2d4c7 100644 --- a/src/CredibleCommitmentCurationProvider.sol +++ b/src/CCCP.sol @@ -8,15 +8,9 @@ import {AccessControlEnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol"; import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol"; -import { - CCCPDataStorage as DS, - OperatorState, - OperatorOptInOutState, - OperatorKeysRangeState, - OperatorExtraData, - ModuleState, - Config -} from "./lib/CCCPDataStorage.sol"; +import {CCCPOperatorStatesStorage} from "./lib/CCCPOperatorStatesStorage.sol"; +import {CCCPConfigStorage} from "./lib/CCCPConfigStorage.sol"; +import {ICCCP} from "./interfaces/ICCCP.sol"; import {ILidoLocator} from "./interfaces/ILidoLocator.sol"; import {StakingModule, IStakingRouter} from "./interfaces/IStakingRouter.sol"; @@ -24,13 +18,18 @@ import {IStakingModule} from "./interfaces/IStakingModule.sol"; import {CSMNodeOperator, ICSModule} from "./interfaces/ICSModule.sol"; import {ICuratedModule} from "./interfaces/ICuratedModule.sol"; -contract CredibleCommitmentCurationProvider is +/** + * @title CCCP + * @notice CredibleCommitmentCurationProvider contract + */ +contract CCCP is + ICCCP, Initializable, + CCCPConfigStorage, + CCCPOperatorStatesStorage, AccessControlEnumerableUpgradeable, PausableUpgradeable { - using DS for uint256; - struct LidoOperatorCache { uint24 moduleId; address moduleAddress; @@ -52,27 +51,24 @@ contract CredibleCommitmentCurationProvider is bytes32 public constant RESUME_ROLE = keccak256("RESUME_ROLE"); ILidoLocator public immutable LIDO_LOCATOR; - // hardcoded CSModule type, used for the operator's state retrieval + // CSModule type, used for the operator's state retrieval bytes32 internal immutable CS_MODULE_TYPE; event OptInSucceeded(uint256 indexed moduleId, uint256 indexed operatorId, address manager); event OptOutRequested(uint256 indexed moduleId, uint256 indexed operatorId, bool isForced); - event KeyRangeUpdated( - uint256 indexed moduleId, uint256 indexed operatorId, uint256 keysRangeStart, uint256 keysRangeEnd - ); + event ResetForcedOptOut(uint256 indexed moduleId, uint256 indexed operatorId); + + event KeysRangeUpdated(uint256 indexed moduleId, uint256 indexed operatorId, uint256 indexStart, uint256 indexEnd); + event OperatorManagerUpdated(uint256 indexed moduleId, uint256 indexed operatorId, address manager); event RPCUrlUpdated(uint256 indexed moduleId, uint256 indexed operatorId, string rpcURL); - event ModuleStateUpdated(uint256 indexed moduleId, bool isDisabled, uint256 operatorMaxValidators); event ConfigUpdated( uint256 optInMinDurationBlocks, uint256 optOutDelayDurationBlocks, uint256 defaultOperatorMaxValidators, uint256 defaultBlockGasLimit ); - event ResetForcedOptOut(uint256 indexed moduleId, uint256 indexed operatorId); - event OperatorManagerUpdated(uint256 indexed moduleId, uint256 indexed operatorId, address manager); + event ModuleConfigUpdated(uint256 indexed moduleId, uint256 operatorMaxValidators, bool isDisabled); - error OperatorNotRegistered(); - error ManagerNotRegistered(); error RewardAddressMismatch(); error OperatorNotActive(); error ModuleDisabled(); @@ -87,13 +83,10 @@ contract CredibleCommitmentCurationProvider is error ZeroCommitteeAddress(); error ZeroOperatorManagerAddress(); error ZeroLocatorAddress(); - error ZeroDefaultOperatorMaxValidators(); - error ZeroDefaultBlockGasLimit(); constructor(address lidoLocator, bytes32 csModuleType) { if (lidoLocator == address(0)) revert ZeroLocatorAddress(); LIDO_LOCATOR = ILidoLocator(lidoLocator); - CS_MODULE_TYPE = csModuleType; _disableInitializers(); @@ -116,7 +109,7 @@ contract CredibleCommitmentCurationProvider is _grantRole(PAUSE_ROLE, committeeAddress); _grantRole(RESUME_ROLE, committeeAddress); - _setConfig( + _updateConfig( optInMinDurationBlocks, optOutDelayDurationBlocks, defaultOperatorMaxValidators, defaultBlockGasLimit ); } @@ -158,10 +151,10 @@ contract CredibleCommitmentCurationProvider is revert OperatorNotActive(); } - uint256 opKey = DS.__encOpKey(moduleId, operatorId); + uint256 opKey = __encOpKey(moduleId, operatorId); // check if the operator is already has the state - OperatorOptInOutState memory optInOutState = opKey._getOperatorOptInOutState(); + OptInOutState memory optInOutState = _getOperatorOptInOutState(opKey); OperatorOptInOutFlags memory flags = _calcOptInOutFlags(optInOutState); if (flags.isOptedIn) { revert OperatorAlreadyRegistered(); @@ -171,16 +164,16 @@ contract CredibleCommitmentCurationProvider is // save operator state /// @dev also checks if the proposed manager is already registered for different operator - opKey._setOperatorManager(manager); + _setOperatorManager(opKey, manager); emit OperatorManagerUpdated(moduleId, operatorId, manager); - opKey._setOperatorOptInOutState( - OperatorOptInOutState({optInBlock: uint64(block.number), optOutBlock: 0, isOptOutForced: false}) + _setOperatorOptInOutState( + opKey, OptInOutState({optInBlock: uint64(block.number), optOutBlock: 0, isOptOutForced: false}) ); _checkAndUpdateKeysRange(_c, opKey, newKeyIndexRangeStart, newKeyIndexRangeEnd); /// @dev no checks on rpcUrl, so it can be rewritten on repeated opt-in - opKey._setOperatorExtraData(OperatorExtraData({rpcURL: rpcURL})); + _setOperatorExtraData(opKey, ExtraData({rpcURL: rpcURL})); emit RPCUrlUpdated(moduleId, operatorId, rpcURL); emit OptInSucceeded(moduleId, operatorId, manager); @@ -190,7 +183,7 @@ contract CredibleCommitmentCurationProvider is /// @dev should be called by the operator manager address function optOut() external whenNotPaused { uint256 opKey = _getOpKeyByManager(msg.sender); - OperatorOptInOutState memory optInOutState = opKey._getOperatorOptInOutState(); + OptInOutState memory optInOutState = _getOperatorOptInOutState(opKey); OperatorOptInOutFlags memory flags = _calcOptInOutFlags(optInOutState); if (!flags.isOptedIn) { revert OperatorNotActive(); @@ -199,9 +192,9 @@ contract CredibleCommitmentCurationProvider is } optInOutState.optOutBlock = uint64(block.number); - opKey._setOperatorOptInOutState(optInOutState); + _setOperatorOptInOutState(opKey, optInOutState); - (uint24 moduleId, uint64 operatorId) = opKey.__decOpKey(); + (uint24 moduleId, uint64 operatorId) = __decOpKey(opKey); emit OptOutRequested(moduleId, operatorId, false); } @@ -209,7 +202,7 @@ contract CredibleCommitmentCurationProvider is function optOut(uint24 moduleId, uint64 operatorId) external onlyRole(COMMITTEE_ROLE) { uint256 opKey = _getOpKeyById(moduleId, operatorId); - OperatorOptInOutState memory optInOutState = opKey._getOperatorOptInOutState(); + OptInOutState memory optInOutState = _getOperatorOptInOutState(opKey); OperatorOptInOutFlags memory flags = _calcOptInOutFlags(optInOutState); if (!flags.isOptedIn) { revert OperatorNotActive(); @@ -218,7 +211,7 @@ contract CredibleCommitmentCurationProvider is optInOutState.optOutBlock = uint64(block.number); optInOutState.isOptOutForced = true; - opKey._setOperatorOptInOutState(optInOutState); + _setOperatorOptInOutState(opKey, optInOutState); emit OptOutRequested(moduleId, operatorId, true); } @@ -227,20 +220,21 @@ contract CredibleCommitmentCurationProvider is /// @dev should be called by the operator manager address function updateKeysRange(uint64 newKeyIndexRangeStart, uint64 newKeyIndexRangeEnd) external whenNotPaused { uint256 opKey = _getOpKeyByManager(msg.sender); - OperatorOptInOutFlags memory flags = _calcOptInOutFlags(opKey._getOperatorOptInOutState()); + OperatorOptInOutFlags memory flags = _calcOptInOutFlags(_getOperatorOptInOutState(opKey)); if (!flags.isOptedIn) { revert OperatorNotActive(); } - OperatorKeysRangeState memory keysRangeState = opKey._getOperatorKeysRangeState(); + KeysRange memory keysRange = _getOperatorKeysRange(opKey); if ( - newKeyIndexRangeStart > keysRangeState.indexStart || newKeyIndexRangeEnd < keysRangeState.indexEnd - || (newKeyIndexRangeStart == keysRangeState.indexStart && newKeyIndexRangeEnd == keysRangeState.indexEnd) + newKeyIndexRangeStart > keysRange.indexStart || newKeyIndexRangeEnd < keysRange.indexEnd + || (newKeyIndexRangeStart == keysRange.indexStart && newKeyIndexRangeEnd == keysRange.indexEnd) ) { revert KeyIndexMismatch(); } LidoOperatorCache memory _c; - _loadLidoNodeOperator(_c, opKey); + (uint24 moduleId, uint64 operatorId) = __decOpKey(opKey); + _loadLidoNodeOperator(_c, moduleId, operatorId); _checkAndUpdateKeysRange(_c, opKey, newKeyIndexRangeStart, newKeyIndexRangeEnd); } @@ -258,11 +252,8 @@ contract CredibleCommitmentCurationProvider is revert RewardAddressMismatch(); } - uint256 opKey = _getOpKeyById(moduleId, operatorId); - /// @dev also checks if the proposed manager is already registered for different operator - opKey._setOperatorManager(newManager); - + _setOperatorManager(__encOpKey(moduleId, operatorId), newManager); emit OperatorManagerUpdated(moduleId, operatorId, newManager); } @@ -294,13 +285,7 @@ contract CredibleCommitmentCurationProvider is uint64 defaultBlockGasLimit ) { - Config memory cfg = DS._getConfig(); - return ( - cfg.optInMinDurationBlocks, - cfg.optOutDelayDurationBlocks, - cfg.defaultOperatorMaxValidators, - cfg.defaultBlockGasLimit - ); + return _getConfig(); } function getContractVersion() external view returns (uint64) { @@ -309,10 +294,10 @@ contract CredibleCommitmentCurationProvider is function resetForcedOptOut(uint24 moduleId, uint64 operatorId) external onlyRole(COMMITTEE_ROLE) { uint256 opKey = _getOpKeyById(moduleId, operatorId); - OperatorOptInOutState memory optInOutState = opKey._getOperatorOptInOutState(); + OptInOutState memory optInOutState = _getOperatorOptInOutState(opKey); if (optInOutState.isOptOutForced) { optInOutState.isOptOutForced = false; - opKey._setOperatorOptInOutState(optInOutState); + _setOperatorOptInOutState(opKey, optInOutState); } emit ResetForcedOptOut(moduleId, operatorId); } @@ -325,13 +310,13 @@ contract CredibleCommitmentCurationProvider is uint64 defaultOperatorMaxValidators, uint64 defaultBlockGasLimit ) external onlyRole(COMMITTEE_ROLE) { - _setConfig( + _updateConfig( optInMinDurationBlocks, optOutDelayDurationBlocks, defaultOperatorMaxValidators, defaultBlockGasLimit ); } /// @notice Update Disable/enable state and operator's max validators for the module - function setModuleState(uint24 moduleId, bool isDisabled, uint64 operatorMaxValidators) + function setModuleConfig(uint24 moduleId, bool isDisabled, uint64 operatorMaxValidators) external onlyRole(COMMITTEE_ROLE) { @@ -339,35 +324,18 @@ contract CredibleCommitmentCurationProvider is LidoOperatorCache memory _c; _loadLidoModuleData(_c, moduleId); - ModuleState memory state = DS._getModuleState(moduleId); - /// @dev operators in disabled modules are automatically considered as opted-out - state.isDisabled = isDisabled; - /// @dev zero value means use default config - state.maxValidators = operatorMaxValidators; - DS._setModuleState(moduleId, state); - - emit ModuleStateUpdated(moduleId, isDisabled, operatorMaxValidators); + _setModuleConfig(moduleId, operatorMaxValidators, isDisabled); + emit ModuleConfigUpdated(moduleId, operatorMaxValidators, isDisabled); } - function _setConfig( + function _updateConfig( uint64 optInMinDurationBlocks, uint64 optOutDelayDurationBlocks, uint64 defaultOperatorMaxValidators, uint64 defaultBlockGasLimit ) internal { - if (defaultOperatorMaxValidators == 0) { - revert ZeroDefaultOperatorMaxValidators(); - } - if (defaultBlockGasLimit == 0) { - revert ZeroDefaultBlockGasLimit(); - } - DS._setConfig( - Config({ - optInMinDurationBlocks: optInMinDurationBlocks, - optOutDelayDurationBlocks: optOutDelayDurationBlocks, - defaultOperatorMaxValidators: defaultOperatorMaxValidators, - defaultBlockGasLimit: defaultBlockGasLimit - }) + _setConfig( + optInMinDurationBlocks, optOutDelayDurationBlocks, defaultOperatorMaxValidators, defaultBlockGasLimit ); emit ConfigUpdated( optInMinDurationBlocks, optOutDelayDurationBlocks, defaultOperatorMaxValidators, defaultBlockGasLimit @@ -384,11 +352,8 @@ contract CredibleCommitmentCurationProvider is _checkModuleParams(_c.moduleId, newKeyIndexRangeStart, newKeyIndexRangeEnd); // save operator state - opKey._setOperatorKeysRangeState( - OperatorKeysRangeState({indexStart: newKeyIndexRangeStart, indexEnd: newKeyIndexRangeEnd}) - ); - - emit KeyRangeUpdated(_c.moduleId, _c.operatorId, newKeyIndexRangeStart, newKeyIndexRangeEnd); + _setOperatorKeysRange(opKey, newKeyIndexRangeStart, newKeyIndexRangeEnd); + emit KeysRangeUpdated(_c.moduleId, _c.operatorId, newKeyIndexRangeStart, newKeyIndexRangeEnd); } function _getOperator(uint256 opKey) @@ -408,18 +373,18 @@ contract CredibleCommitmentCurationProvider is ) { LidoOperatorCache memory _c; - - _loadLidoNodeOperator(_c, opKey); - state = opKey._getOperatorState(); + (moduleId, operatorId) = __decOpKey(opKey); + _loadLidoNodeOperator(_c, moduleId, operatorId); + state = _getOperatorState(opKey); OperatorOptInOutFlags memory flags = _calcOptInOutFlags(state.optInOutState); - ModuleState memory moduleState = DS._getModuleState(_c.moduleId); + (, bool isDisabled) = _getModuleConfig(_c.moduleId); // operator is enabled: // - if it's s opted in // - if module not disabled // - if operator is active in Lido module // - if the contract is not paused - isEnabled = flags.isOptedIn && !moduleState.isDisabled && _c.isActive && !paused(); + isEnabled = flags.isOptedIn && !isDisabled && _c.isActive && !paused(); return ( _c.moduleId, @@ -428,42 +393,27 @@ contract CredibleCommitmentCurationProvider is // state.optInOutState.optInBlock, // state.optInOutState.optOutBlock, // state.optInOutState.isOptOutForced, - // state.keysRangeState.indexStart, - // state.keysRangeState.indexEnd, + // state.keysRange.indexStart, + // state.keysRange.indexEnd, // state.extraData.rpcURL state ); } function _checkModuleParams(uint24 moduleId, uint64 startIndex, uint64 endIndex) internal view { - Config memory cfg = DS._getConfig(); - ModuleState memory state = DS._getModuleState(moduleId); - if (state.isDisabled) { + (,, uint64 defaultOperatorMaxValidators,) = _getConfig(); + (uint64 moduleMaxValidators, bool isDisabled) = _getModuleConfig(moduleId); + if (isDisabled) { revert ModuleDisabled(); } uint64 totalKeys = endIndex - startIndex + 1; - uint64 maxValidators = state.maxValidators == 0 ? cfg.defaultOperatorMaxValidators : state.maxValidators; + uint64 maxValidators = moduleMaxValidators == 0 ? defaultOperatorMaxValidators : moduleMaxValidators; if (totalKeys > maxValidators) { revert KeysRangeExceedMaxValidators(); } } - /// @dev reverts if the operator not registered - function _getOpKeyById(uint24 moduleId, uint64 operatorId) internal view returns (uint256 opKey) { - opKey = DS.__encOpKey(moduleId, operatorId); - if (opKey._getOperatorManager() == address(0)) { - revert OperatorNotRegistered(); - } - } - - function _getOpKeyByManager(address manager) internal view returns (uint256 opKey) { - opKey = DS._getManagerOpKey(manager); - if (opKey == 0) { - revert ManagerNotRegistered(); - } - } - function _checkKeysRangeIsValid(uint64 totalKeys, uint64 startIndex, uint64 endIndex) internal pure { if (startIndex > endIndex) { revert KeyIndexMismatch(); @@ -474,19 +424,19 @@ contract CredibleCommitmentCurationProvider is } } - function _calcOptInOutFlags(OperatorOptInOutState memory optInOutState) + function _calcOptInOutFlags(OptInOutState memory optInOutState) internal view returns (OperatorOptInOutFlags memory flags) { uint64 blockNumber = uint64(block.number); - Config memory cfg = DS._getConfig(); + (uint64 optInMinDurationBlocks, uint64 optOutDelayDurationBlocks,,) = _getConfig(); bool isOptedOut = - optInOutState.optOutBlock > 0 && optInOutState.optOutBlock + cfg.optOutDelayDurationBlocks < blockNumber; + optInOutState.optOutBlock > 0 && optInOutState.optOutBlock + optOutDelayDurationBlocks < blockNumber; bool isOptedIn = optInOutState.optInBlock > 0 && !isOptedOut; bool optInAllowed = !isOptedIn && !optInOutState.isOptOutForced; - bool optOutAllowed = isOptedIn && optInOutState.optInBlock + cfg.optInMinDurationBlocks < blockNumber; + bool optOutAllowed = isOptedIn && optInOutState.optInBlock + optInMinDurationBlocks < blockNumber; return OperatorOptInOutFlags({ isOptedIn: isOptedIn, @@ -504,11 +454,6 @@ contract CredibleCommitmentCurationProvider is } /// @notice Prepare the cache for the staking module and node operator - function _loadLidoNodeOperator(LidoOperatorCache memory _c, uint256 opKey) internal view { - (uint24 moduleId, uint64 operatorId) = opKey.__decOpKey(); - _loadLidoNodeOperator(_c, moduleId, operatorId); - } - function _loadLidoNodeOperator(LidoOperatorCache memory _c, uint24 moduleId, uint64 operatorId) internal view { _loadLidoModuleData(_c, moduleId); _loadLidoNodeOperatorData(_c, operatorId); diff --git a/src/interfaces/ICCCP.sol b/src/interfaces/ICCCP.sol new file mode 100644 index 0000000..eed3dc9 --- /dev/null +++ b/src/interfaces/ICCCP.sol @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2025 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.28; + +import {ICCCPOperatorStatesStorage} from "./ICCCPOperatorStatesStorage.sol"; + +/** + * @title ICCCP + * @notice Interface for CredibleCommitmentCurationProvider. + */ +interface ICCCP is ICCCPOperatorStatesStorage { + function optIn( + uint24 moduleId, + uint64 operatorId, + address manager, + uint64 newKeyIndexRangeStart, + uint64 newKeyIndexRangeEnd, + string calldata rpcURL + ) external; + function optOut() external; + function updateKeysRange(uint64 newKeyIndexRangeStart, uint64 newKeyIndexRangeEnd) external; + function updateManager(uint24 moduleId, uint64 operatorId, address newManager) external; + + function getOperator(address manager) + external + view + returns (uint24 moduleId, uint64 operatorId, bool isEnabled, OperatorState memory state); + + function getOperator(uint24 _moduleId, uint64 _operatorId) + external + view + returns (uint24 moduleId, uint64 operatorId, bool isEnabled, OperatorState memory state); +} diff --git a/src/interfaces/ICCCPConfigStorage.sol b/src/interfaces/ICCCPConfigStorage.sol new file mode 100644 index 0000000..02d1282 --- /dev/null +++ b/src/interfaces/ICCCPConfigStorage.sol @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2025 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.28; + +/** + * @title ICCCPConfigStorage + * @notice Interface for interacting with the storage and control config params. + */ +interface ICCCPConfigStorage { + struct ModuleConfig { + // hopefully, we won't need more than 2^64 validators + /// @dev zero value means use default config + uint64 maxValidators; + // is module disabled for pre-confs + /// @dev operators in disabled modules are automatically considered as opted-out + bool isDisabled; + } + + struct Config { + // minimum duration of the opt-in period in blocks + uint64 optInMinDurationBlocks; + // delay in blocks before the operator can opt-in again after opt-out + uint64 optOutDelayDurationBlocks; + uint64 defaultOperatorMaxValidators; //todo rename to per op + uint64 defaultBlockGasLimit; + } + + struct ConfigStorage { + // module configs + mapping(uint256 => ModuleConfig) _modules; + // config + Config _config; + } + + error ZeroDefaultOperatorMaxValidators(); + error ZeroDefaultBlockGasLimit(); +} diff --git a/src/interfaces/ICCCPOperatorStatesStorage.sol b/src/interfaces/ICCCPOperatorStatesStorage.sol new file mode 100644 index 0000000..38f2b2a --- /dev/null +++ b/src/interfaces/ICCCPOperatorStatesStorage.sol @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: 2025 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.28; + +/** + * @title IOperatorStatesStorage + * @notice Interface for interacting with the storage and control states of operators. + */ +interface ICCCPOperatorStatesStorage { + /// @notice operator optin/optout state + /// operator can be in several statuses: + // 1. new, not registered: optInBlock = 0, optOutBlock = 0 + // 2. registered: optInBlock > 0, optOutBlock = 0 + // 3. opt-out in progress: optInBlock > 0, optOutBlock > 0, optOutBlock + optOutDelayDurationBlocksDelay >= block.r + // 4. forded opt-out in progress: optInBlock > 0, optOutBlock > 0, isOptOutForced = true, optOutBlock + optOutDelayDurationBlocksDelay >= block.r + // 5. opt-out completed: optInBlock > 0, optOutBlock > 0, isOptOutForced = false, optOutBlock + optOutDelayDurationBlocksDelay < block.r + // 6. forced opt-out completed: optInBlock > 0, optOutBlock > 0, isOptOutForced = true, optOutBlock + optOutDelayDurationBlocksDelay < block.r + + // If isOptOutForced is set, optOutBlock has non-zero value of the block number when the operator was forced to opt out. + // If operator has "forced opt-out completed" status, it can't opt in again until the committee decides to allow it (clear isOptOutForced flag). + struct OptInOutState { + uint64 optInBlock; + uint64 optOutBlock; + bool isOptOutForced; // if the operator is forced to opt out by the committee + } + + struct KeysRange { + uint64 indexStart; + uint64 indexEnd; + } + + struct ExtraData { + string rpcURL; + } + + struct OperatorState { + address manager; + KeysRange keysRange; + OptInOutState optInOutState; + ExtraData extraData; + } + + /** + * @notice Storage structure for operator states data. + * @dev + * @param _operators Mapping opKey (module id + operator id) to operator state + * @param _managers Mapping manager address to opKey + */ + struct OperatorsStatesStorage { + mapping(uint256 => OperatorState) _operators; + mapping(address => uint256) _managers; + } + + error ManagerBelongsToOtherOperator(); + error OperatorNotRegistered(); + error ManagerNotRegistered(); +} diff --git a/src/lib/CCCPConfigStorage.sol b/src/lib/CCCPConfigStorage.sol new file mode 100644 index 0000000..e6549e2 --- /dev/null +++ b/src/lib/CCCPConfigStorage.sol @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: 2025 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.28; + +import {ICCCPConfigStorage} from "../interfaces/ICCCPConfigStorage.sol"; + +abstract contract CCCPConfigStorage is ICCCPConfigStorage { + bytes32 private immutable STORAGE_SLOT_REF; + + constructor() { + STORAGE_SLOT_REF = keccak256( + abi.encode(uint256(keccak256(abi.encodePacked("lido.cccp.storage.ConfigStorage"))) - 1) + ) & ~bytes32(uint256(0xff)); + } + + function _setConfig( + uint64 optInMinDurationBlocks, + uint64 optOutDelayDurationBlocks, + uint64 defaultOperatorMaxValidators, + uint64 defaultBlockGasLimit + ) internal { + if (defaultOperatorMaxValidators == 0) { + revert ZeroDefaultOperatorMaxValidators(); + } + if (defaultBlockGasLimit == 0) { + revert ZeroDefaultBlockGasLimit(); + } + _getConfigStorage()._config = Config({ + optInMinDurationBlocks: optInMinDurationBlocks, + optOutDelayDurationBlocks: optOutDelayDurationBlocks, + defaultOperatorMaxValidators: defaultOperatorMaxValidators, + defaultBlockGasLimit: defaultBlockGasLimit + }); + } + + function _setModuleConfig(uint24 moduleId, uint64 maxValidators, bool isDisabled) internal { + _getConfigStorage()._modules[moduleId] = ModuleConfig({maxValidators: maxValidators, isDisabled: isDisabled}); + } + + function _getConfig() + internal + view + returns ( + uint64 optInMinDurationBlocks, + uint64 optOutDelayDurationBlocks, + uint64 defaultOperatorMaxValidators, + uint64 defaultBlockGasLimit + ) + { + Config memory config = _getConfigStorage()._config; + return ( + config.optInMinDurationBlocks, + config.optOutDelayDurationBlocks, + config.defaultOperatorMaxValidators, + config.defaultBlockGasLimit + ); + } + + function _getModuleConfig(uint24 moduleId) internal view returns (uint64 maxValidators, bool isDisabled) { + ModuleConfig memory moduleConfig = _getConfigStorage()._modules[moduleId]; + return (moduleConfig.maxValidators, moduleConfig.isDisabled); + } + + /** + * @notice Accesses the storage slot for the config's data. + * @return $ A reference to the `ConfigStorage` struct. + * + * @dev This function uses inline assembly to access a predefined storage slot. + */ + function _getConfigStorage() private view returns (ConfigStorage storage $) { + bytes32 slot = STORAGE_SLOT_REF; + assembly { + $.slot := slot + } + } +} diff --git a/src/lib/CCCPDataStorage.sol b/src/lib/CCCPDataStorage.sol deleted file mode 100644 index b505f2b..0000000 --- a/src/lib/CCCPDataStorage.sol +++ /dev/null @@ -1,171 +0,0 @@ -// SPDX-FileCopyrightText: 2025 Lido -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity 0.8.28; - -/// @notice operator optin/optout state -/// operator can be in several statuses: -// 1. new, not registered: optInBlock = 0, optOutBlock = 0 -// 2. registered: optInBlock > 0, optOutBlock = 0 -// 3. opt-out in progress: optInBlock > 0, optOutBlock > 0, optOutBlock + optOutDelayDurationBlocksDelay >= block.r -// 4. forded opt-out in progress: optInBlock > 0, optOutBlock > 0, isOptOutForced = true, optOutBlock + optOutDelayDurationBlocksDelay >= block.r -// 5. opt-out completed: optInBlock > 0, optOutBlock > 0, isOptOutForced = false, optOutBlock + optOutDelayDurationBlocksDelay < block.r -// 6. forced opt-out completed: optInBlock > 0, optOutBlock > 0, isOptOutForced = true, optOutBlock + optOutDelayDurationBlocksDelay < block.r - -// If isOptOutForced is set, optOutBlock has non-zero value of the block number when the operator was forced to opt out. -// If operator has "forced opt-out completed" status, it can't opt in again until the committee decides to allow it (clear isOptOutForced flag). -struct OperatorOptInOutState { - uint64 optInBlock; - uint64 optOutBlock; - bool isOptOutForced; // if the operator is forced to opt out by the committee -} - -struct OperatorKeysRangeState { - uint64 indexStart; - uint64 indexEnd; -} - -struct OperatorExtraData { - string rpcURL; -} - -struct OperatorState { - address manager; - OperatorKeysRangeState keysRangeState; - OperatorOptInOutState optInOutState; - OperatorExtraData extraData; -} - -struct ModuleState { - // is module disabled for pre-confs - bool isDisabled; - // hopefully, we won't need more than 2^64 validators - uint64 maxValidators; -} - -struct Config { - // minimum duration of the opt-in period in blocks - uint64 optInMinDurationBlocks; - // delay in blocks before the operator can opt-in again after opt-out - uint64 optOutDelayDurationBlocks; - uint64 defaultOperatorMaxValidators; //todo rename to per op - uint64 defaultBlockGasLimit; -} - -library CCCPDataStorage { - struct CCCPData { - // opKey (module id + operator id) => operator state - mapping(uint256 => OperatorState) _operators; - // manager address to opKey - mapping(address => uint256) _managers; - // modules state - mapping(uint256 => ModuleState) _modules; - // config - Config _config; - } - - // keccak256(abi.encode(uint256(keccak256("lido.cccp.CCCPData")) - 1)) & ~bytes32(uint256(0xff)) - bytes32 internal constant CCCP_DATA_LOCATION = 0x250c379b4df7db4aa0cebfe63c44e477918a4a35c66c19b68448ebd5517bd100; - - error ManagerBelongsToOtherOperator(); - - function _getStorage() private pure returns (CCCPData storage $) { - assembly { - $.slot := CCCP_DATA_LOCATION - } - } - - function _getOperatorStateStorage(uint256 opKey) private view returns (OperatorState storage) { - return _getStorage()._operators[opKey]; - } - - /// @notice get operator' full state - function _getOperatorState(uint256 opKey) internal view returns (OperatorState memory) { - return _getOperatorStateStorage(opKey); - } - - /// @notice get operator's opt-in/opt-out state - function _getOperatorOptInOutState(uint256 opKey) internal view returns (OperatorOptInOutState memory) { - return _getOperatorStateStorage(opKey).optInOutState; - } - - function _setOperatorOptInOutState(uint256 opKey, OperatorOptInOutState memory state) internal { - _getOperatorStateStorage(opKey).optInOutState = state; - } - - /// @notice get operator's keys range state - function _getOperatorKeysRangeState(uint256 opKey) internal view returns (OperatorKeysRangeState memory) { - return _getOperatorStateStorage(opKey).keysRangeState; - } - - function _setOperatorKeysRangeState(uint256 opKey, OperatorKeysRangeState memory state) internal { - _getOperatorStateStorage(opKey).keysRangeState = state; - } - - /// @notice get operator's extra data - function _getOperatorExtraData(uint256 opKey) internal view returns (OperatorExtraData memory) { - return _getOperatorStateStorage(opKey).extraData; - } - - function _setOperatorExtraData(uint256 opKey, OperatorExtraData memory data) internal { - _getOperatorStateStorage(opKey).extraData = data; - } - - /// @notice get manager address linked to the operator's reward address - function _getOperatorManager(uint256 opKey) internal view returns (address managerAddress) { - return _getOperatorStateStorage(opKey).manager; - } - - /// @dev safe manager address update - function _setOperatorManager(uint256 opKey, address manager) internal { - _checkManager(opKey, manager); - OperatorState storage $ = _getOperatorStateStorage(opKey); - - address oldManager = $.manager; - if (oldManager != address(0) && oldManager != manager) { - delete _getStorage()._managers[oldManager]; - } - $.manager = manager; - _getStorage()._managers[manager] = opKey; - } - - function _getManagerOpKey(address manager) internal view returns (uint256) { - return _getStorage()._managers[manager]; - } - - function _checkManager(uint256 opKey, address manager) internal view { - uint256 managerOpKey = _getManagerOpKey(manager); - // revert if the manager address is linked to the other operator - if (managerOpKey != 0 && managerOpKey != opKey) { - revert ManagerBelongsToOtherOperator(); - } - } - - function __encOpKey(uint24 moduleId, uint64 operatorId) internal pure returns (uint256) { - return uint256(moduleId) << 64 | operatorId; - } - - function __decOpKey(uint256 opKey) internal pure returns (uint24 moduleId, uint64 operatorId) { - return (uint24(opKey >> 64), uint64(opKey)); - } - - /// MODULES DATA - - function _getModuleState(uint24 moduleId) internal view returns (ModuleState memory) { - return _getStorage()._modules[moduleId]; - } - - function _setModuleState(uint24 moduleId, ModuleState memory state) internal { - _getStorage()._modules[moduleId] = state; - } - - /// CONFIG DATA - - function _getConfig() internal view returns (Config memory) { - return _getStorage()._config; - } - - function _setConfig(Config memory config) internal { - _getStorage()._config = config; - } -} diff --git a/src/lib/CCCPOperatorStatesStorage.sol b/src/lib/CCCPOperatorStatesStorage.sol new file mode 100644 index 0000000..1159b5e --- /dev/null +++ b/src/lib/CCCPOperatorStatesStorage.sol @@ -0,0 +1,118 @@ +// SPDX-FileCopyrightText: 2025 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.28; + +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {ICCCPOperatorStatesStorage} from "../interfaces/ICCCPOperatorStatesStorage.sol"; + +abstract contract CCCPOperatorStatesStorage is ICCCPOperatorStatesStorage, Initializable { + bytes32 private immutable STORAGE_SLOT_REF; + + constructor() { + STORAGE_SLOT_REF = keccak256( + abi.encode(uint256(keccak256(abi.encodePacked("lido.cccp.storage.OperatorStatesStorage"))) - 1) + ) & ~bytes32(uint256(0xff)); + } + + function __initializeOperatorStatesStorage() internal onlyInitializing {} + + function _setOperatorOptInOutState(uint256 opKey, OptInOutState memory state) internal { + _getOperatorStateStorage(opKey).optInOutState = state; + } + + function _setOperatorKeysRange(uint256 opKey, uint64 indexStart, uint64 indexEnd) internal { + _getOperatorStateStorage(opKey).keysRange = KeysRange(indexStart, indexEnd); + } + + function _setOperatorExtraData(uint256 opKey, ExtraData memory data) internal { + _getOperatorStateStorage(opKey).extraData = data; + } + + /// @dev safe manager's address update + function _setOperatorManager(uint256 opKey, address manager) internal { + // _checkManagerFree(opKey, manager); + uint256 managerOpKey = _getManagerOpKey(manager); + // revert if the manager address is linked to the other operator + if (managerOpKey != 0 && managerOpKey != opKey) { + revert ManagerBelongsToOtherOperator(); + } + + OperatorState storage $ = _getOperatorStateStorage(opKey); + address oldManager = $.manager; + if (oldManager != address(0) && oldManager != manager) { + delete _getOperatorsStatesStorage()._managers[oldManager]; + } + $.manager = manager; + _getOperatorsStatesStorage()._managers[manager] = opKey; + } + + /// @notice get operator' full state + function _getOperatorState(uint256 opKey) internal view returns (OperatorState memory) { + return _getOperatorStateStorage(opKey); + } + + /// @notice get operator's opt-in/opt-out state + function _getOperatorOptInOutState(uint256 opKey) internal view returns (OptInOutState memory) { + return _getOperatorStateStorage(opKey).optInOutState; + } + + /// @notice get operator's keys range state + function _getOperatorKeysRange(uint256 opKey) internal view returns (KeysRange memory) { + return _getOperatorStateStorage(opKey).keysRange; + } + + /// @notice get operator's extra data + function _getOperatorExtraData(uint256 opKey) internal view returns (ExtraData memory) { + return _getOperatorStateStorage(opKey).extraData; + } + + /// @notice get manager address linked to the operator's reward address + function _getOperatorManager(uint256 opKey) internal view returns (address managerAddress) { + return _getOperatorStateStorage(opKey).manager; + } + + function _getManagerOpKey(address manager) internal view returns (uint256) { + return _getOperatorsStatesStorage()._managers[manager]; + } + + /// @dev reverts if the operator not registered + function _getOpKeyById(uint24 moduleId, uint64 operatorId) internal view returns (uint256 opKey) { + opKey = __encOpKey(moduleId, operatorId); + if (_getOperatorManager(opKey) == address(0)) { + revert OperatorNotRegistered(); + } + } + + function _getOpKeyByManager(address manager) internal view returns (uint256 opKey) { + opKey = _getManagerOpKey(manager); + if (opKey == 0) { + revert ManagerNotRegistered(); + } + } + + function __encOpKey(uint24 moduleId, uint64 operatorId) internal pure returns (uint256) { + return (uint256(moduleId) << 64) | operatorId; + } + + function __decOpKey(uint256 opKey) internal pure returns (uint24 moduleId, uint64 operatorId) { + return (uint24(opKey >> 64), uint64(opKey)); + } + + /** + * @notice Accesses the storage slot for the OperatorState's data. + * @return $ A reference to the `OperatorsStatesStorage` struct. + * + * @dev This function uses inline assembly to access a predefined storage slot. + */ + function _getOperatorsStatesStorage() private view returns (OperatorsStatesStorage storage $) { + bytes32 slot = STORAGE_SLOT_REF; + assembly { + $.slot := slot + } + } + + function _getOperatorStateStorage(uint256 opKey) private view returns (OperatorState storage) { + return _getOperatorsStatesStorage()._operators[opKey]; + } +} diff --git a/test/CCCP.t.sol b/test/CCCP.t.sol index a7016fa..ccd5dc0 100644 --- a/test/CCCP.t.sol +++ b/test/CCCP.t.sol @@ -2,18 +2,16 @@ pragma solidity 0.8.28; import {Test, console} from "forge-std/Test.sol"; -import {CCCPDataStorage as DS, ModuleState, Config} from "../src/lib/CCCPDataStorage.sol"; -import { - CredibleCommitmentCurationProvider as CCCP, OperatorState -} from "../src/CredibleCommitmentCurationProvider.sol"; +import {CCCPConfigStorage, ICCCPConfigStorage} from "../src/lib/CCCPConfigStorage.sol"; +import {CCCPOperatorStatesStorage, ICCCPOperatorStatesStorage} from "../src/lib/CCCPOperatorStatesStorage.sol"; +import {CCCP} from "../src/CCCP.sol"; import {CCCPMock} from "./helpers/mocks/CCCPMock.sol"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; - -import "./helpers/Fixtures.sol"; -import "./helpers/Utilities.sol"; +import {Fixtures} from "./helpers/Fixtures.sol"; +import {Utilities} from "./helpers/Utilities.sol"; import {LidoLocatorMock} from "test/helpers/mocks/LidoLocatorMock.sol"; import {StakingModuleMock} from "test/helpers/mocks/StakingModuleMock.sol"; -import {StakingRouterMock} from "test/helpers/mocks/StakingRouterMock.sol"; +import {StakingRouterMock, IStakingRouter} from "test/helpers/mocks/StakingRouterMock.sol"; import {CuratedModuleMock} from "test/helpers/mocks/CuratedModuleMock.sol"; import {CSModuleMock} from "test/helpers/mocks/CSModuleMock.sol"; @@ -154,7 +152,7 @@ contract CCCPOptIn is CCCPCommon { // opt in on behalf of noCsm1 vm.broadcast(noCsm1); vm.expectEmit(true, true, true, false, address(cccp)); - emit CCCP.KeyRangeUpdated(csmId, noCsm1Id, 2, 4); + emit CCCP.KeysRangeUpdated(csmId, noCsm1Id, 2, 4); vm.expectEmit(true, true, true, false, address(cccp)); emit CCCP.OptInSucceeded(csmId, noCsm1Id, noCsm1Manager); @@ -167,15 +165,15 @@ contract CCCPOptIn is CCCPCommon { rpcURL: "" }); - (uint24 moduleId, uint64 operatorId, bool isEnabled, OperatorState memory state) = + (uint24 moduleId, uint64 operatorId, bool isEnabled, CCCP.OperatorState memory state) = cccp.getOperator(noCsm1Manager); assertEq(moduleId, csmId); assertEq(operatorId, noCsm1Id); assertEq(isEnabled, true); - assertEq(state.keysRangeState.indexStart, 2); - assertEq(state.keysRangeState.indexEnd, 4); + assertEq(state.keysRange.indexStart, 2); + assertEq(state.keysRange.indexEnd, 4); assertEq(state.manager, noCsm1Manager); assertEq(state.optInOutState.optInBlock, block.number); assertEq(state.optInOutState.optOutBlock, 0); @@ -307,7 +305,7 @@ contract CCCPOptIn is CCCPCommon { // optin with same manager vm.broadcast(noCsm1); - vm.expectRevert(DS.ManagerBelongsToOtherOperator.selector); + vm.expectRevert(ICCCPOperatorStatesStorage.ManagerBelongsToOtherOperator.selector); cccp.optIn({ moduleId: csmId, operatorId: noCsm1Id, diff --git a/test/DataStorage.t.sol b/test/DataStorage.t.sol index f2489d0..161bedc 100644 --- a/test/DataStorage.t.sol +++ b/test/DataStorage.t.sol @@ -1,30 +1,21 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.28; -import {Test, console} from "forge-std/Test.sol"; -import {CCCPDataStorage as DS, ModuleState, Config} from "../src/lib/CCCPDataStorage.sol"; +import {Test} from "forge-std/Test.sol"; +import {CCCPConfigStorage} from "../src/lib/CCCPConfigStorage.sol"; -contract ModulesDataStorageTest is Test { - function setUp() public { - // counter.setNumber(0); - } - - function test_StorageLocationConstant() public pure { - bytes32 location = keccak256(abi.encode(uint256(keccak256("lido.cccp.CCCPData")) - 1)) & ~bytes32(uint256(0xff)); - - assertEq(DS.CCCP_DATA_LOCATION, location); - } +contract ModulesDataStorageTest is Test, CCCPConfigStorage { + function setUp() public {} - function test_ModuleState() public { + function test_ModuleConfig() public { uint24 moduleId = 111; uint64 maxValidators = 1111; - ModuleState memory state = ModuleState({isDisabled: true, maxValidators: maxValidators}); - DS._setModuleState(moduleId, state); - ModuleState memory newState = DS._getModuleState(moduleId); + _setModuleConfig(moduleId, maxValidators, true); + (uint64 newMaxValidators, bool newIsDisabled) = _getModuleConfig(moduleId); - assertEq(newState.maxValidators, maxValidators); - assertEq(newState.isDisabled, true); + assertEq(newMaxValidators, maxValidators); + assertEq(newIsDisabled, true); } function test_Config() public { @@ -32,16 +23,20 @@ contract ModulesDataStorageTest is Test { uint64 optOutDelayDurationBlocks = 234; uint64 defaultOperatorMaxValidators = 100; uint64 defaultBlockGasLimit = 1000000; - Config memory cfg = Config( + + _setConfig( optInMinDurationBlocks, optOutDelayDurationBlocks, defaultOperatorMaxValidators, defaultBlockGasLimit ); - - DS._setConfig(cfg); - Config memory newCfg = DS._getConfig(); - - assertEq(newCfg.optInMinDurationBlocks, optInMinDurationBlocks); - assertEq(newCfg.optOutDelayDurationBlocks, optOutDelayDurationBlocks); - assertEq(newCfg.defaultOperatorMaxValidators, defaultOperatorMaxValidators); - assertEq(newCfg.defaultBlockGasLimit, defaultBlockGasLimit); + ( + uint64 newOptInMinDurationBlocks, + uint64 newOptOutDelayDurationBlocks, + uint64 newDefaultOperatorMaxValidators, + uint64 newDefaultBlockGasLimit + ) = _getConfig(); + + assertEq(newOptInMinDurationBlocks, optInMinDurationBlocks); + assertEq(newOptOutDelayDurationBlocks, optOutDelayDurationBlocks); + assertEq(newDefaultOperatorMaxValidators, defaultOperatorMaxValidators); + assertEq(newDefaultBlockGasLimit, defaultBlockGasLimit); } } diff --git a/test/fork/deployment/PostDeployment.t.sol b/test/fork/deployment/PostDeployment.t.sol index fcef458..adbb8e8 100644 --- a/test/fork/deployment/PostDeployment.t.sol +++ b/test/fork/deployment/PostDeployment.t.sol @@ -8,7 +8,7 @@ import {Utilities} from "../../helpers/Utilities.sol"; import {DeploymentFixtures} from "../../helpers/Fixtures.sol"; import {DeployParams} from "../../../script/DeployBase.s.sol"; import {OssifiableProxy} from "../../../src/lib/proxy/OssifiableProxy.sol"; -import {CredibleCommitmentCurationProvider as CCCP} from "../../../src/CredibleCommitmentCurationProvider.sol"; +import {CCCP} from "../../../src/CCCP.sol"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; contract CSModuleDeploymentTest is Test, Utilities, DeploymentFixtures { diff --git a/test/helpers/Fixtures.sol b/test/helpers/Fixtures.sol index 7c39bf9..986ff1a 100644 --- a/test/helpers/Fixtures.sol +++ b/test/helpers/Fixtures.sol @@ -6,7 +6,7 @@ import {StdCheats} from "forge-std/StdCheats.sol"; import {Test} from "forge-std/Test.sol"; import {DeployParams} from "../../script/DeployBase.s.sol"; -import {CredibleCommitmentCurationProvider} from "../../src/CredibleCommitmentCurationProvider.sol"; +import {CCCP} from "../../src/CCCP.sol"; import {ILidoLocator} from "../../src/interfaces/ILidoLocator.sol"; import {IStakingRouter} from "../../src/interfaces/IStakingRouter.sol"; @@ -57,7 +57,7 @@ contract DeploymentFixtures is StdCheats, Test { address lidoLocator; } - CredibleCommitmentCurationProvider public cccp; + CCCP public cccp; ILidoLocator public locator; IStakingRouter public stakingRouter; @@ -73,7 +73,7 @@ contract DeploymentFixtures is StdCheats, Test { DeploymentConfig memory deploymentConfig = parseDeploymentConfig(config); assertEq(deploymentConfig.chainId, block.chainid, "ChainId mismatch"); - cccp = CredibleCommitmentCurationProvider(deploymentConfig.cccp); + cccp = CCCP(deploymentConfig.cccp); locator = ILidoLocator(deploymentConfig.lidoLocator); stakingRouter = IStakingRouter(locator.stakingRouter()); } diff --git a/test/helpers/mocks/CCCPMock.sol b/test/helpers/mocks/CCCPMock.sol index 1787a43..0c4696f 100644 --- a/test/helpers/mocks/CCCPMock.sol +++ b/test/helpers/mocks/CCCPMock.sol @@ -3,12 +3,10 @@ pragma solidity 0.8.28; -import {CredibleCommitmentCurationProvider} from "../../../src/CredibleCommitmentCurationProvider.sol"; +import {CCCP} from "../../../src/CCCP.sol"; -contract CCCPMock is CredibleCommitmentCurationProvider { - constructor(address lidoLocator, bytes32 csModuleType) - CredibleCommitmentCurationProvider(lidoLocator, csModuleType) - {} +contract CCCPMock is CCCP { + constructor(address lidoLocator, bytes32 csModuleType) CCCP(lidoLocator, csModuleType) {} function __test__getCSModuleType() external view returns (bytes32) { return CS_MODULE_TYPE; diff --git a/yarn.lock b/yarn.lock index d14b954..d59a7ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,27 @@ __metadata: languageName: node linkType: hard +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd + languageName: node + linkType: hard + "@pnpm/config.env-replace@npm:^1.1.0": version: 1.1.0 resolution: "@pnpm/config.env-replace@npm:1.1.0" @@ -57,6 +78,15 @@ __metadata: languageName: node linkType: hard +"@solidity-parser/parser@npm:^0.16.1": + version: 0.16.2 + resolution: "@solidity-parser/parser@npm:0.16.2" + dependencies: + antlr4ts: "npm:^0.5.0-alpha.4" + checksum: 10c0/f0612b36f9a25def75188b44ce06d7cb286b4f843c54b3f0e8836bdd48438663aafea7839890d54f9ccdbc6fa2c1e1247cae2ab734713463e21e4bd656e526a7 + languageName: node + linkType: hard + "@solidity-parser/parser@npm:^0.18.0": version: 0.18.0 resolution: "@solidity-parser/parser@npm:0.18.0" @@ -143,7 +173,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.2.1": +"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": version: 6.2.1 resolution: "ansi-styles@npm:6.2.1" checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c @@ -157,6 +187,15 @@ __metadata: languageName: node linkType: hard +"antlr4ts@npm:^0.5.0-alpha.4": + version: 0.5.0-dev + resolution: "antlr4ts@npm:0.5.0-dev" + dependencies: + source-map-support: "npm:^0.5.16" + checksum: 10c0/948d95d02497a5751105cc61e9931d03a9bf0566b33a28ea8f2c72484a47ec4c5148670e1a525bfbc0069b1b86ab820417ec3fad120081211ff55f542fb4a835 + languageName: node + linkType: hard + "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -178,6 +217,13 @@ __metadata: languageName: node linkType: hard +"async@npm:^3.2.4": + version: 3.2.6 + resolution: "async@npm:3.2.6" + checksum: 10c0/36484bb15ceddf07078688d95e27076379cc2f87b10c03b6dd8a83e89475a3c8df5848859dd06a4c95af1e4c16fc973de0171a77f18ea00be899aca2a4f85e70 + languageName: node + linkType: hard + "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -203,6 +249,20 @@ __metadata: languageName: node linkType: hard +"buffer-from@npm:^1.0.0": + version: 1.1.2 + resolution: "buffer-from@npm:1.1.2" + checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34 + languageName: node + linkType: hard + +"c3-linearization@npm:^0.3.0": + version: 0.3.0 + resolution: "c3-linearization@npm:0.3.0" + checksum: 10c0/7d07af10d6cc861e75f07fb55b7db3e97efc4b3e27921d047bb18a96dc18a147a78d6ab6e4195b6d25cab457d45158914942e7d5dc8d7cb150d13b16672adb03 + languageName: node + linkType: hard + "cacheable-lookup@npm:^7.0.0": version: 7.0.0 resolution: "cacheable-lookup@npm:7.0.0" @@ -242,7 +302,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:~5.4.1": +"chalk@npm:^5.4.1": version: 5.4.1 resolution: "chalk@npm:5.4.1" checksum: 10c0/b23e88132c702f4855ca6d25cb5538b1114343e41472d5263ee8a37cccfccd9c4216d111e1097c6a27830407a1dc81fecdf2a56f2c63033d4dbbd88c10b0dcef @@ -258,6 +318,15 @@ __metadata: languageName: node linkType: hard +"cli-table@npm:^0.3.11": + version: 0.3.11 + resolution: "cli-table@npm:0.3.11" + dependencies: + colors: "npm:1.0.3" + checksum: 10c0/6e31da4e19e942bf01749ff78d7988b01e0101955ce2b1e413eecdc115d4bb9271396464761491256a7d3feeedb5f37ae505f4314c4f8044b5d0f4b579c18f29 + languageName: node + linkType: hard + "cli-truncate@npm:^4.0.0": version: 4.0.0 resolution: "cli-truncate@npm:4.0.0" @@ -268,6 +337,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^8.0.1": + version: 8.0.1 + resolution: "cliui@npm:8.0.1" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^7.0.0" + checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5 + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -291,6 +371,20 @@ __metadata: languageName: node linkType: hard +"colors@npm:1.0.3": + version: 1.0.3 + resolution: "colors@npm:1.0.3" + checksum: 10c0/f9e40dd8b3e1a65378a7ced3fced15ddfd60aaf38e99a7521a7fdb25056b15e092f651cd0f5aa1e9b04fa8ce3616d094e07fc6c2bb261e24098db1ddd3d09a1d + languageName: node + linkType: hard + +"colors@npm:^1.4.0": + version: 1.4.0 + resolution: "colors@npm:1.4.0" + checksum: 10c0/9af357c019da3c5a098a301cf64e3799d27549d8f185d86f79af23069e4f4303110d115da98483519331f6fb71c8568d5688fa1c6523600044fd4a54e97c4efb + languageName: node + linkType: hard + "commander@npm:^10.0.0": version: 10.0.1 resolution: "commander@npm:10.0.1" @@ -298,10 +392,17 @@ __metadata: languageName: node linkType: hard -"commander@npm:~12.1.0": - version: 12.1.0 - resolution: "commander@npm:12.1.0" - checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9 +"commander@npm:^11.0.0": + version: 11.1.0 + resolution: "commander@npm:11.1.0" + checksum: 10c0/13cc6ac875e48780250f723fb81c1c1178d35c5decb1abb1b628b3177af08a8554e76b2c0f29de72d69eef7c864d12613272a71fabef8047922bc622ab75a179 + languageName: node + linkType: hard + +"commander@npm:^13.1.0": + version: 13.1.0 + resolution: "commander@npm:13.1.0" + checksum: 10c0/7b8c5544bba704fbe84b7cab2e043df8586d5c114a4c5b607f83ae5060708940ed0b5bd5838cf8ce27539cde265c1cbd59ce3c8c6b017ed3eec8943e3a415164 languageName: node linkType: hard @@ -337,15 +438,16 @@ __metadata: resolution: "credible-commitment-curation-provider@workspace:." dependencies: husky: "npm:^9.1.7" - lint-staged: "npm:^15.3.0" + lint-staged: "npm:^15.4.2" prettier: "npm:^3.4.2" prettier-plugin-solidity: "npm:^1.4.2" - solhint: "npm:5.0.4" + solhint: "npm:5.0.5" solhint-plugin-lido-csm: "https://github.com/lidofinance/solhint-plugin-lido-csm.git#0.3.3" + solidity-code-metrics: "npm:^0.0.28" languageName: unknown linkType: soft -"cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -356,7 +458,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:~4.4.0": +"debug@npm:^4.4.0": version: 4.4.0 resolution: "debug@npm:4.4.0" dependencies: @@ -391,6 +493,13 @@ __metadata: languageName: node linkType: hard +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 + languageName: node + linkType: hard + "emoji-regex@npm:^10.3.0": version: 10.4.0 resolution: "emoji-regex@npm:10.4.0" @@ -405,6 +514,13 @@ __metadata: languageName: node linkType: hard +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 + languageName: node + linkType: hard + "environment@npm:^1.0.0": version: 1.1.0 resolution: "environment@npm:1.1.0" @@ -421,6 +537,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.1.1": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 + languageName: node + linkType: hard + "eventemitter3@npm:^5.0.1": version: 5.0.1 resolution: "eventemitter3@npm:5.0.1" @@ -428,7 +551,7 @@ __metadata: languageName: node linkType: hard -"execa@npm:~8.0.1": +"execa@npm:^8.0.1": version: 8.0.1 resolution: "execa@npm:8.0.1" dependencies: @@ -482,6 +605,16 @@ __metadata: languageName: node linkType: hard +"foreground-child@npm:^3.1.0": + version: 3.3.0 + resolution: "foreground-child@npm:3.3.0" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 10c0/028f1d41000553fcfa6c4bb5c372963bf3d9bf0b1f25a87d1a6253014343fb69dfb1b42d9625d7cf44c8ba429940f3d0ff718b62105d4d4a4f6ef8ca0a53faa2 + languageName: node + linkType: hard + "form-data-encoder@npm:^2.1.2": version: 2.1.4 resolution: "form-data-encoder@npm:2.1.4" @@ -496,6 +629,13 @@ __metadata: languageName: node linkType: hard +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde + languageName: node + linkType: hard + "get-east-asian-width@npm:^1.0.0": version: 1.3.0 resolution: "get-east-asian-width@npm:1.3.0" @@ -517,6 +657,22 @@ __metadata: languageName: node linkType: hard +"glob@npm:^10.3.15": + version: 10.4.5 + resolution: "glob@npm:10.4.5" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e + languageName: node + linkType: hard + "glob@npm:^8.0.3": version: 8.1.0 resolution: "glob@npm:8.1.0" @@ -556,6 +712,15 @@ __metadata: languageName: node linkType: hard +"graphviz@npm:0.0.9": + version: 0.0.9 + resolution: "graphviz@npm:0.0.9" + dependencies: + temp: "npm:~0.4.0" + checksum: 10c0/d9e7ea3d74b00db43ae96fe465f988dccc2e62b48471bdfb134ea914f4ba552e5ec5817da350993e68b11452392d2fe9bfd79ad3d06ccaac6724301778c32870 + languageName: node + linkType: hard + "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -563,6 +728,16 @@ __metadata: languageName: node linkType: hard +"hasha@npm:^5.2.0": + version: 5.2.2 + resolution: "hasha@npm:5.2.2" + dependencies: + is-stream: "npm:^2.0.0" + type-fest: "npm:^0.8.0" + checksum: 10c0/9d10d4e665a37beea6e18ba3a0c0399a05b26e505c5ff2fe9115b64fedb3ca95f68c89cf15b08ee4d09fd3064b5e1bfc8e8247353c7aa6b7388471d0f86dca74 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" @@ -674,6 +849,13 @@ __metadata: languageName: node linkType: hard +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: 10c0/7c284241313fc6efc329b8d7f08e16c0efeb6baab1b4cd0ba579eb78e5af1aa5da11e68559896a2067cd6c526bd29241dda4eb1225e627d5aa1a89a76d4635a5 + languageName: node + linkType: hard + "is-stream@npm:^3.0.0": version: 3.0.0 resolution: "is-stream@npm:3.0.0" @@ -688,6 +870,19 @@ __metadata: languageName: node linkType: hard +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 + languageName: node + linkType: hard + "js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -752,7 +947,7 @@ __metadata: languageName: node linkType: hard -"lilconfig@npm:~3.1.3": +"lilconfig@npm:^3.1.3": version: 3.1.3 resolution: "lilconfig@npm:3.1.3" checksum: 10c0/f5604e7240c5c275743561442fbc5abf2a84ad94da0f5adc71d25e31fa8483048de3dcedcb7a44112a942fed305fd75841cdf6c9681c7f640c63f1049e9a5dcc @@ -766,27 +961,27 @@ __metadata: languageName: node linkType: hard -"lint-staged@npm:^15.3.0": - version: 15.3.0 - resolution: "lint-staged@npm:15.3.0" +"lint-staged@npm:^15.4.2": + version: 15.4.2 + resolution: "lint-staged@npm:15.4.2" dependencies: - chalk: "npm:~5.4.1" - commander: "npm:~12.1.0" - debug: "npm:~4.4.0" - execa: "npm:~8.0.1" - lilconfig: "npm:~3.1.3" - listr2: "npm:~8.2.5" - micromatch: "npm:~4.0.8" - pidtree: "npm:~0.6.0" - string-argv: "npm:~0.3.2" - yaml: "npm:~2.6.1" + chalk: "npm:^5.4.1" + commander: "npm:^13.1.0" + debug: "npm:^4.4.0" + execa: "npm:^8.0.1" + lilconfig: "npm:^3.1.3" + listr2: "npm:^8.2.5" + micromatch: "npm:^4.0.8" + pidtree: "npm:^0.6.0" + string-argv: "npm:^0.3.2" + yaml: "npm:^2.7.0" bin: lint-staged: bin/lint-staged.js - checksum: 10c0/1ddf9488c523c0b65c85b755428d4ad74fac3aa6ccb2e28e9bff5b8d86503158fe241d20d5433a11146872050b43580644901a5ef4c924b1ad7017c224a07339 + checksum: 10c0/08dd28149241788f7ca628a64c9c1817a9dfbe19517ba0317fdf96a1109f6d624948864edfeaf2936561bb49c65aeb32d5ddc75fb15afa2b6527024ef01a546b languageName: node linkType: hard -"listr2@npm:~8.2.5": +"listr2@npm:^8.2.5": version: 8.2.5 resolution: "listr2@npm:8.2.5" dependencies: @@ -834,6 +1029,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -841,7 +1043,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:~4.0.8": +"micromatch@npm:^4.0.8": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -888,6 +1090,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed + languageName: node + linkType: hard + "minimist@npm:^1.2.0": version: 1.2.8 resolution: "minimist@npm:1.2.8" @@ -895,6 +1106,13 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557 + languageName: node + linkType: hard + "ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" @@ -952,6 +1170,13 @@ __metadata: languageName: node linkType: hard +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 10c0/62ba2785eb655fec084a257af34dbe24292ab74516d6aecef97ef72d4897310bc6898f6c85b5cd22770eaa1ce60d55a0230e150fb6a966e3ecd6c511e23d164b + languageName: node + linkType: hard + "package-json@npm:^8.1.0": version: 8.1.1 resolution: "package-json@npm:8.1.1" @@ -999,6 +1224,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d + languageName: node + linkType: hard + "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0" @@ -1013,14 +1248,14 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^2.3.1": +"picomatch@npm:^2.2.1, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be languageName: node linkType: hard -"pidtree@npm:~0.6.0": +"pidtree@npm:^0.6.0": version: 0.6.0 resolution: "pidtree@npm:0.6.0" bin: @@ -1101,6 +1336,15 @@ __metadata: languageName: node linkType: hard +"readdirp@npm:^3.3.0": + version: 3.6.0 + resolution: "readdirp@npm:3.6.0" + dependencies: + picomatch: "npm:^2.2.1" + checksum: 10c0/6fa848cf63d1b82ab4e985f4cf72bd55b7dcfd8e0a376905804e48c3634b7e749170940ba77b32804d5fe93b3cc521aa95a8d7e7d725f830da6d93f3669ce66b + languageName: node + linkType: hard + "registry-auth-token@npm:^5.0.1": version: 5.0.3 resolution: "registry-auth-token@npm:5.0.3" @@ -1119,6 +1363,13 @@ __metadata: languageName: node linkType: hard +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 + languageName: node + linkType: hard + "require-from-string@npm:^2.0.2": version: 2.0.2 resolution: "require-from-string@npm:2.0.2" @@ -1175,6 +1426,15 @@ __metadata: languageName: node linkType: hard +"sha1-file@npm:^2.0.0": + version: 2.0.1 + resolution: "sha1-file@npm:2.0.1" + dependencies: + hasha: "npm:^5.2.0" + checksum: 10c0/aa8a3ae2f64360163190adc75eebd2bf22a3ad8223069af3aaa88b6b1832fb71ce18df57cd2c67e1f7653fdc3011661d2ca90974b29e0d9d7b2f1844a14aba51 + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -1191,7 +1451,7 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^4.1.0": +"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 @@ -1229,6 +1489,20 @@ __metadata: languageName: node linkType: hard +"sloc@npm:^0.3.2": + version: 0.3.2 + resolution: "sloc@npm:0.3.2" + dependencies: + async: "npm:^3.2.4" + cli-table: "npm:^0.3.11" + commander: "npm:^11.0.0" + readdirp: "npm:^3.3.0" + bin: + sloc: bin/sloc + checksum: 10c0/6287e561407c668f73139c2931db35c605aa471d5dade6dac81fb5d1659aed43f8464c629497556768df0fd4f692a5a8322283c9bb42b078433de6b021f8998d + languageName: node + linkType: hard + "solhint-plugin-lido-csm@https://github.com/lidofinance/solhint-plugin-lido-csm.git#0.3.3": version: 0.3.3 resolution: "solhint-plugin-lido-csm@https://github.com/lidofinance/solhint-plugin-lido-csm.git#commit=db949adb893af939bfb1ca5ba191c26fd94aa69c" @@ -1270,9 +1544,9 @@ __metadata: languageName: node linkType: hard -"solhint@npm:5.0.4": - version: 5.0.4 - resolution: "solhint@npm:5.0.4" +"solhint@npm:5.0.5": + version: 5.0.5 + resolution: "solhint@npm:5.0.5" dependencies: "@solidity-parser/parser": "npm:^0.19.0" ajv: "npm:^6.12.6" @@ -1298,18 +1572,61 @@ __metadata: optional: true bin: solhint: solhint.js - checksum: 10c0/70058b23c8746762fc88d48b571c4571719913ca7f3c582a55c123ad9ba38976a2338782025fbb9643bb75bfad18bf3dce1b71e500df6d99589e9814fbcce1d7 + checksum: 10c0/becf018ff57f6b3579a7001179dcf941814bbdbc9fed8e4bb6502d35a8b5adc4fc42d0fa7f800e3003471768f9e17d2c458fb9f21c65c067160573f16ff12769 + languageName: node + linkType: hard + +"solidity-code-metrics@npm:^0.0.28": + version: 0.0.28 + resolution: "solidity-code-metrics@npm:0.0.28" + dependencies: + "@solidity-parser/parser": "npm:^0.18.0" + glob: "npm:^10.3.15" + sloc: "npm:^0.3.2" + solidity-doppelganger: "npm:^0.0.11" + surya: "npm:^0.4.12" + bin: + solidity-code-metrics: src/cli.js + checksum: 10c0/cbd0de8b37ee342cf943975ab8963859f6b13e0f1a1df8635e37882bc0f085d506cc35e20413684ce36acfbbb116b35be99afe7bb42e39391f880e885cf09f9d + languageName: node + linkType: hard + +"solidity-doppelganger@npm:^0.0.11": + version: 0.0.11 + resolution: "solidity-doppelganger@npm:0.0.11" + dependencies: + "@solidity-parser/parser": "npm:^0.16.1" + glob: "npm:^8.0.3" + yargs: "npm:^17.0.1" + checksum: 10c0/43bc2ce9a2c5ab39d7a09ddd72f8939fe1f24cd353833ebc2fdba77bcb2d374c7fffee1d8cff74a9665cbdfc331feadab9e518722913772c2163c1b37163c21a + languageName: node + linkType: hard + +"source-map-support@npm:^0.5.16": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10c0/9ee09942f415e0f721d6daad3917ec1516af746a8120bba7bb56278707a37f1eb8642bde456e98454b8a885023af81a16e646869975f06afc1a711fb90484e7d + languageName: node + linkType: hard + +"source-map@npm:^0.6.0": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 languageName: node linkType: hard -"string-argv@npm:~0.3.2": +"string-argv@npm:^0.3.2": version: 0.3.2 resolution: "string-argv@npm:0.3.2" checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82 languageName: node linkType: hard -"string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -1320,6 +1637,17 @@ __metadata: languageName: node linkType: hard +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca + languageName: node + linkType: hard + "string-width@npm:^7.0.0": version: 7.2.0 resolution: "string-width@npm:7.2.0" @@ -1331,7 +1659,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" dependencies: @@ -1340,7 +1668,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^7.1.0": +"strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0": version: 7.1.0 resolution: "strip-ansi@npm:7.1.0" dependencies: @@ -1372,6 +1700,23 @@ __metadata: languageName: node linkType: hard +"surya@npm:^0.4.12": + version: 0.4.12 + resolution: "surya@npm:0.4.12" + dependencies: + "@solidity-parser/parser": "npm:^0.16.1" + c3-linearization: "npm:^0.3.0" + colors: "npm:^1.4.0" + graphviz: "npm:0.0.9" + sha1-file: "npm:^2.0.0" + treeify: "npm:^1.1.0" + yargs: "npm:^17.0.0" + bin: + surya: bin/surya + checksum: 10c0/ed90d4ba50390e33df65590c5e8f2bfcc444822202431baabe39abbac6486946770007d0aa4b2441e906ac1aa6fda26ac8efbab07bf4b83b1410587625641490 + languageName: node + linkType: hard + "table@npm:^6.8.1": version: 6.9.0 resolution: "table@npm:6.9.0" @@ -1385,6 +1730,13 @@ __metadata: languageName: node linkType: hard +"temp@npm:~0.4.0": + version: 0.4.0 + resolution: "temp@npm:0.4.0" + checksum: 10c0/cf25c604d7509c3a41d2893c9779d4130a127ac2a9bea23ec1a5ff7da0f82e0014b5dcd77a4ce7227e63bc667ad4bd5ec312441e01e39ca5dcee6e146fbdaefb + languageName: node + linkType: hard + "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -1401,6 +1753,20 @@ __metadata: languageName: node linkType: hard +"treeify@npm:^1.1.0": + version: 1.1.0 + resolution: "treeify@npm:1.1.0" + checksum: 10c0/2f0dea9e89328b8a42296a3963d341ab19897a05b723d6b0bced6b28701a340d2a7b03241aef807844198e46009aaf3755139274eb082cfce6fdc1935cbd69dd + languageName: node + linkType: hard + +"type-fest@npm:^0.8.0": + version: 0.8.1 + resolution: "type-fest@npm:0.8.1" + checksum: 10c0/dffbb99329da2aa840f506d376c863bd55f5636f4741ad6e65e82f5ce47e6914108f44f340a0b74009b0cb5d09d6752ae83203e53e98b1192cf80ecee5651636 + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -1421,6 +1787,28 @@ __metadata: languageName: node linkType: hard +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 + languageName: node + linkType: hard + "wrap-ansi@npm:^9.0.0": version: 9.0.0 resolution: "wrap-ansi@npm:9.0.0" @@ -1439,11 +1827,40 @@ __metadata: languageName: node linkType: hard -"yaml@npm:~2.6.1": - version: 2.6.1 - resolution: "yaml@npm:2.6.1" +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249 + languageName: node + linkType: hard + +"yaml@npm:^2.7.0": + version: 2.7.0 + resolution: "yaml@npm:2.7.0" bin: yaml: bin.mjs - checksum: 10c0/aebf07f61c72b38c74d2b60c3a3ccf89ee4da45bcd94b2bfb7899ba07a5257625a7c9f717c65a6fc511563d48001e01deb1d9e55f0133f3e2edf86039c8c1be7 + checksum: 10c0/886a7d2abbd70704b79f1d2d05fe9fb0aa63aefb86e1cb9991837dced65193d300f5554747a872b4b10ae9a12bc5d5327e4d04205f70336e863e35e89d8f4ea9 + languageName: node + linkType: hard + +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 + languageName: node + linkType: hard + +"yargs@npm:^17.0.0, yargs@npm:^17.0.1": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 languageName: node linkType: hard