From 55fef91e38bd21057303f6b0308bbeef1e403a66 Mon Sep 17 00:00:00 2001 From: zorzal Date: Thu, 12 Dec 2024 06:31:04 -0500 Subject: [PATCH 1/2] chore: add openzeppelin dependency --- package.json | 3 +++ yarn.lock | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/package.json b/package.json index 07a15ed..85325ae 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,9 @@ "*.sol": "solhint --fix 'solidity/contracts/**/*.sol' 'solidity/interfaces/**/*.sol' && solhint --fix -c .solhint.tests.json 'solidity/test/**/*.sol'", "package.json": "sort-package-json" }, + "dependencies": { + "@openzeppelin/contracts": "4.9.5" + }, "devDependencies": { "@commitlint/cli": "17.0.3", "@commitlint/config-conventional": "17.0.3", diff --git a/yarn.lock b/yarn.lock index e314636..088922f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -227,6 +227,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@openzeppelin/contracts@4.9.5": + version "4.9.5" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.5.tgz#1eed23d4844c861a1835b5d33507c1017fa98de8" + integrity sha512-ZK+W5mVhRppff9BE6YdR8CC52C8zAvsVAiWhEtQ5+oNxFE6h1WdeWo+FJSF8KKvtxxVYZ7MTP/5KoVpAU3aSWg== + "@solidity-parser/parser@^0.14.1": version "0.14.5" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.5.tgz#87bc3cc7b068e08195c219c91cd8ddff5ef1a804" From e6c328cc40f4c96cb9b6dd4cd7a0e1be6daf14ce Mon Sep 17 00:00:00 2001 From: zorzal Date: Thu, 12 Dec 2024 06:31:43 -0500 Subject: [PATCH 2/2] fix: replace mapping's `bytes` value with EnumerableSet --- solidity/contracts/Oracle.sol | 22 +++++++--------------- solidity/test/unit/Oracle.t.sol | 3 ++- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/solidity/contracts/Oracle.sol b/solidity/contracts/Oracle.sol index 9283cb9..67f64cd 100644 --- a/solidity/contracts/Oracle.sol +++ b/solidity/contracts/Oracle.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; + import {IOracle} from '../interfaces/IOracle.sol'; import {IAccessModule} from '../interfaces/modules/access/IAccessModule.sol'; @@ -15,6 +17,7 @@ import {OracleTypehash} from './utils/OracleTypehash.sol'; contract Oracle is IOracle, OracleAccessController { using ValidatorLib for *; + using EnumerableSet for EnumerableSet.Bytes32Set; /// @inheritdoc IOracle mapping(bytes32 _requestId => uint256 _finalizedAt) public finalizedAt; @@ -50,24 +53,13 @@ contract Oracle is IOracle, OracleAccessController { uint256 public totalRequestCount; /** - * @notice The list of the response ids for each request + * @notice An enumerable set of the response ids for each request */ - mapping(bytes32 _requestId => bytes _responseIds) internal _responseIds; + mapping(bytes32 _requestId => EnumerableSet.Bytes32Set _responseIds) internal _responseIds; /// @inheritdoc IOracle function getResponseIds(bytes32 _requestId) public view returns (bytes32[] memory _ids) { - bytes memory _responses = _responseIds[_requestId]; - uint256 _length = _responses.length / 32; - - assembly { - for { let _i := 0 } lt(_i, _length) { _i := add(_i, 1) } { - // Increase the size of the array - mstore(_ids, add(mload(_ids), 1)) - - // Store the response id in the array - mstore(add(_ids, add(32, mul(_i, 32))), mload(add(_responses, add(32, mul(_i, 32))))) - } - } + _ids = _responseIds[_requestId].values(); } /// @inheritdoc IOracle @@ -154,7 +146,7 @@ contract Oracle is IOracle, OracleAccessController { } isParticipant[_requestId][_response.proposer] = true; IResponseModule(_request.responseModule).propose(_request, _response, _accessControl.user); - _responseIds[_requestId] = abi.encodePacked(_responseIds[_requestId], _responseId); + _responseIds[_requestId].add(_responseId); responseCreatedAt[_responseId] = block.timestamp; emit ResponseProposed(_requestId, _responseId, _response); diff --git a/solidity/test/unit/Oracle.t.sol b/solidity/test/unit/Oracle.t.sol index 6034398..e6c8fe0 100644 --- a/solidity/test/unit/Oracle.t.sol +++ b/solidity/test/unit/Oracle.t.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; import 'forge-std/Test.sol'; import {IModule} from '../../interfaces/IModule.sol'; @@ -71,7 +72,7 @@ contract MockOracle is Oracle { } function mock_addResponseId(bytes32 _requestId, bytes32 _responseId) external { - _responseIds[_requestId] = abi.encodePacked(_responseIds[_requestId], _responseId); + EnumerableSet.add(_responseIds[_requestId], _responseId); } function mock_setAccessModuleApproved(address _user, address _accessModule, bool _approved) external {