diff --git a/build-docs.sh b/build-docs.sh index 0df63888..1901d8a0 100755 --- a/build-docs.sh +++ b/build-docs.sh @@ -16,18 +16,6 @@ FOUNDRY_PROFILE=docs forge doc --out "$temp_folder" rm -rf ./solidity/contracts/core rm -rf ./solidity/interfaces/core -# edit generated summary not to have container pages -# - [jobs](solidity/interfaces/jobs/README.md) -# should become -# - [jobs]() -# TODO - -# edit generated summary titles to start with an uppercase letter -# - [jobs]() -# should become -# - [Jobs]() -# TODO - # edit the SUMMARY after the Interfaces section # https://stackoverflow.com/questions/67086574/no-such-file-or-directory-when-using-sed-in-combination-with-find if [[ "$OSTYPE" == "darwin"* ]]; then diff --git a/package.json b/package.json index d7808a25..d5bfcb1a 100644 --- a/package.json +++ b/package.json @@ -39,13 +39,13 @@ }, "dependencies": { "@defi-wonderland/prophet-core-contracts": "0.0.0-49fc8fa6", - "@defi-wonderland/solidity-utils": "0.0.0-3e9c8e8b", "@openzeppelin/contracts": "^4.9.3", "solmate": "https://github.com/transmissions11/solmate.git#bfc9c25865a274a7827fea5abf6e4fb64fc64e6c" }, "devDependencies": { "@commitlint/cli": "17.0.3", "@commitlint/config-conventional": "17.0.3", + "@defi-wonderland/solidity-utils": "0.0.0-3e9c8e8b", "@typechain/ethers-v6": "0.3.0", "@typechain/truffle-v5": "8.0.2", "@typechain/web3-v1": "6.0.2", @@ -57,7 +57,7 @@ "lint-staged": "13.2.2", "pinst": "3.0.0", "solhint": "3.5.1", - "solhint-plugin-defi-wonderland": "1.1.0", + "solhint-plugin-defi-wonderland": "1.1.2", "solidity-docgen": "0.6.0-beta.35", "sort-package-json": "2.4.1", "standard-version": "9.5.0", diff --git a/solidity/contracts/extensions/BondEscalationAccounting.sol b/solidity/contracts/extensions/BondEscalationAccounting.sol index 3efe1e2a..c1f30dc5 100644 --- a/solidity/contracts/extensions/BondEscalationAccounting.sol +++ b/solidity/contracts/extensions/BondEscalationAccounting.sol @@ -49,7 +49,6 @@ contract BondEscalationAccounting is AccountingExtension, IBondEscalationAccount uint256 _amountPerPledger, uint256 _winningPledgersLength ) external onlyAllowedModule(_requestId) { - // TODO: check that flooring at _amountPerPledger calculation doesn't mess with this check if (pledges[_disputeId][_token] < _amountPerPledger * _winningPledgersLength) { revert BondEscalationAccounting_InsufficientFunds(); } diff --git a/solidity/contracts/modules/dispute/CircuitResolverModule.sol b/solidity/contracts/modules/dispute/CircuitResolverModule.sol index 8518a2b4..f17a7cad 100644 --- a/solidity/contracts/modules/dispute/CircuitResolverModule.sol +++ b/solidity/contracts/modules/dispute/CircuitResolverModule.sol @@ -29,14 +29,10 @@ contract CircuitResolverModule is Module, ICircuitResolverModule { IOracle.Response calldata _response, IOracle.Dispute calldata _dispute ) external onlyOracle { - // TODO: Call `disputeStatus` to check the current status instead of reading from `_correctResponses` RequestParameters memory _params = decodeRequestData(_request.disputeModuleData); + IOracle.DisputeStatus _status = ORACLE.disputeStatus(_disputeId); - bytes memory _correctResponse = _correctResponses[_dispute.requestId]; - bool _won = _response.response.length != _correctResponse.length - || keccak256(_response.response) != keccak256(_correctResponse); - - if (_won) { + if (_status == IOracle.DisputeStatus.Won) { _params.accountingExtension.pay({ _requestId: _dispute.requestId, _payer: _dispute.proposer, @@ -45,8 +41,11 @@ contract CircuitResolverModule is Module, ICircuitResolverModule { _amount: _params.bondSize }); - IOracle.Response memory _newResponse = - IOracle.Response({requestId: _dispute.requestId, proposer: _dispute.disputer, response: _correctResponse}); + IOracle.Response memory _newResponse = IOracle.Response({ + requestId: _dispute.requestId, + proposer: _dispute.disputer, + response: _correctResponses[_dispute.requestId] + }); emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Won}); diff --git a/solidity/contracts/modules/dispute/RootVerificationModule.sol b/solidity/contracts/modules/dispute/RootVerificationModule.sol index e954fc1a..d9d3a93f 100644 --- a/solidity/contracts/modules/dispute/RootVerificationModule.sol +++ b/solidity/contracts/modules/dispute/RootVerificationModule.sol @@ -35,13 +35,10 @@ contract RootVerificationModule is Module, IRootVerificationModule { IOracle.Response calldata _response, IOracle.Dispute calldata _dispute ) external onlyOracle { - // TODO: Call `disputeStatus` to check the current status RequestParameters memory _params = decodeRequestData(_request.disputeModuleData); + IOracle.DisputeStatus _status = ORACLE.disputeStatus(_disputeId); - bytes32 _correctRoot = _correctRoots[_dispute.requestId]; - bool _won = abi.decode(_response.response, (bytes32)) != _correctRoot; - - if (_won) { + if (_status == IOracle.DisputeStatus.Won) { _params.accountingExtension.pay({ _requestId: _dispute.requestId, _payer: _dispute.proposer, @@ -53,7 +50,7 @@ contract RootVerificationModule is Module, IRootVerificationModule { IOracle.Response memory _newResponse = IOracle.Response({ requestId: _dispute.requestId, proposer: _dispute.disputer, - response: abi.encode(_correctRoot) + response: abi.encode(_correctRoots[_dispute.requestId]) }); emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Won}); diff --git a/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol b/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol index 6bb09197..32986583 100644 --- a/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol +++ b/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol @@ -9,6 +9,7 @@ import {FixedPointMathLib} from 'solmate/utils/FixedPointMathLib.sol'; // solhint-disable-next-line no-unused-import import {IResolutionModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; +// solhint-disable-next-line no-unused-import import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; diff --git a/solidity/contracts/modules/response/BondedResponseModule.sol b/solidity/contracts/modules/response/BondedResponseModule.sol index 13707cdd..8f776657 100644 --- a/solidity/contracts/modules/response/BondedResponseModule.sol +++ b/solidity/contracts/modules/response/BondedResponseModule.sol @@ -40,8 +40,8 @@ contract BondedResponseModule is Module, IBondedResponseModule { // Allowing one undisputed response at a time if (_disputeId == bytes32(0)) revert BondedResponseModule_AlreadyResponded(); IOracle.DisputeStatus _status = ORACLE.disputeStatus(_disputeId); - // TODO: leaving a note here to re-check this check if a new status is added - // If the dispute was lost, we assume the proposed answer was correct. DisputeStatus.None should not be reachable due to the previous check. + // If the dispute was lost, we assume the proposed answer was correct. + // DisputeStatus.None should not be reachable due to the previous check. if (_status == IOracle.DisputeStatus.Lost) revert BondedResponseModule_AlreadyResponded(); } @@ -64,7 +64,6 @@ contract BondedResponseModule is Module, IBondedResponseModule { ) external override(IBondedResponseModule, Module) onlyOracle { RequestParameters memory _params = decodeRequestData(_request.responseModuleData); - // TODO: If deadline has passed, we can skip the caller validation bool _isModule = ORACLE.allowedModule(_response.requestId, _finalizer); if (!_isModule && block.number < _params.deadline) { diff --git a/solidity/interfaces/extensions/IBondEscalationAccounting.sol b/solidity/interfaces/extensions/IBondEscalationAccounting.sol index ce7728c9..835e9346 100644 --- a/solidity/interfaces/extensions/IBondEscalationAccounting.sol +++ b/solidity/interfaces/extensions/IBondEscalationAccounting.sol @@ -89,26 +89,6 @@ interface IBondEscalationAccounting is IAccountingExtension { bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, IERC20 _token, uint256 _amount ); - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Contains the data of the result of an escalation. Is used by users to claim their pledges - * @param requestId The ID of the bond-escalated request - * @param forVotesWon Whether the for votes won the dispute - * @param token The address of the token being paid out - * @param amountPerPledger The amount of token paid to each of the winning pledgers - * @param bondEscalationModule The address of the bond escalation module that was used - */ - struct EscalationResult { - bytes32 requestId; - bool forVotesWon; - IERC20 token; - uint256 amountPerPledger; - IBondEscalationModule bondEscalationModule; - } - /*/////////////////////////////////////////////////////////////// ERRORS //////////////////////////////////////////////////////////////*/ @@ -133,6 +113,26 @@ interface IBondEscalationAccounting is IAccountingExtension { */ error BondEscalationAccounting_AlreadySettled(); + /*/////////////////////////////////////////////////////////////// + STRUCTS + //////////////////////////////////////////////////////////////*/ + + /** + * @notice Contains the data of the result of an escalation. Is used by users to claim their pledges + * @param requestId The ID of the bond-escalated request + * @param forVotesWon Whether the for votes won the dispute + * @param token The address of the token being paid out + * @param amountPerPledger The amount of token paid to each of the winning pledgers + * @param bondEscalationModule The address of the bond escalation module that was used + */ + struct EscalationResult { + bytes32 requestId; + bool forVotesWon; + IERC20 token; + uint256 amountPerPledger; + IBondEscalationModule bondEscalationModule; + } + /*/////////////////////////////////////////////////////////////// VARIABLES //////////////////////////////////////////////////////////////*/ diff --git a/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol b/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol index ae3272fd..c7de588d 100644 --- a/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol +++ b/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol @@ -20,6 +20,15 @@ import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; * and the request is finalized. */ interface ICircuitResolverModule is IDisputeModule { + /*/////////////////////////////////////////////////////////////// + ERRORS + //////////////////////////////////////////////////////////////*/ + + /** + * @notice Thrown when the verification of a response fails + */ + error CircuitResolverModule_VerificationFailed(); + /*/////////////////////////////////////////////////////////////// STRUCTS //////////////////////////////////////////////////////////////*/ @@ -41,15 +50,6 @@ interface ICircuitResolverModule is IDisputeModule { uint256 bondSize; } - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Thrown when the verification of a response fails - */ - error CircuitResolverModule_VerificationFailed(); - /*/////////////////////////////////////////////////////////////// LOGIC //////////////////////////////////////////////////////////////*/ diff --git a/solidity/interfaces/modules/request/IHttpRequestModule.sol b/solidity/interfaces/modules/request/IHttpRequestModule.sol index a4e3db93..9060688c 100644 --- a/solidity/interfaces/modules/request/IHttpRequestModule.sol +++ b/solidity/interfaces/modules/request/IHttpRequestModule.sol @@ -12,6 +12,18 @@ import {IAccountingExtension} from '../../../interfaces/extensions/IAccountingEx * @notice Module allowing users to request HTTP calls */ interface IHttpRequestModule is IRequestModule { + /*/////////////////////////////////////////////////////////////// + ENUMS + //////////////////////////////////////////////////////////////*/ + + /** + * @notice Available HTTP methods + */ + enum HttpMethod { + GET, + POST + } + /*/////////////////////////////////////////////////////////////// STRUCTS //////////////////////////////////////////////////////////////*/ @@ -34,18 +46,6 @@ interface IHttpRequestModule is IRequestModule { uint256 paymentAmount; } - /*/////////////////////////////////////////////////////////////// - ENUMS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Available HTTP methods - */ - enum HttpMethod { - GET, - POST - } - /*/////////////////////////////////////////////////////////////// LOGIC //////////////////////////////////////////////////////////////*/ diff --git a/solidity/interfaces/modules/resolution/IArbitratorModule.sol b/solidity/interfaces/modules/resolution/IArbitratorModule.sol index fe78357f..74d182a2 100644 --- a/solidity/interfaces/modules/resolution/IArbitratorModule.sol +++ b/solidity/interfaces/modules/resolution/IArbitratorModule.sol @@ -29,17 +29,6 @@ interface IArbitratorModule is IResolutionModule { */ error ArbitratorModule_InvalidResolutionStatus(); - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @param arbitrator The address of the arbitrator - */ - struct RequestParameters { - address arbitrator; - } - /*/////////////////////////////////////////////////////////////// ENUMS //////////////////////////////////////////////////////////////*/ @@ -53,6 +42,17 @@ interface IArbitratorModule is IResolutionModule { Resolved // The arbitration process is resolved } + /*/////////////////////////////////////////////////////////////// + STRUCTS + //////////////////////////////////////////////////////////////*/ + /** + * @notice Parameters of the request as stored in the module + * @param arbitrator The address of the arbitrator + */ + struct RequestParameters { + address arbitrator; + } + /*/////////////////////////////////////////////////////////////// LOGIC //////////////////////////////////////////////////////////////*/ diff --git a/solidity/test/unit/extensions/AccountingExtension.t.sol b/solidity/test/unit/extensions/AccountingExtension.t.sol index c342a343..d22ef4b2 100644 --- a/solidity/test/unit/extensions/AccountingExtension.t.sol +++ b/solidity/test/unit/extensions/AccountingExtension.t.sol @@ -5,7 +5,7 @@ import 'forge-std/Test.sol'; import {Helpers} from '../../utils/Helpers.sol'; -import {Oracle, IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Oracle.sol'; +import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Oracle.sol'; import { AccountingExtension, IAccountingExtension, IERC20 } from '../../../contracts/extensions/AccountingExtension.sol'; diff --git a/solidity/test/unit/modules/dispute/BondedDisputeModule.t.sol b/solidity/test/unit/modules/dispute/BondedDisputeModule.t.sol index 67868623..9d0adfc8 100644 --- a/solidity/test/unit/modules/dispute/BondedDisputeModule.t.sol +++ b/solidity/test/unit/modules/dispute/BondedDisputeModule.t.sol @@ -27,7 +27,13 @@ contract BaseTest is Test, Helpers { IOracle public oracle; event DisputeStatusChanged(bytes32 indexed _disputeId, IOracle.Dispute _dispute, IOracle.DisputeStatus _status); - // TODO: event ResponseDisputed(bytes32 indexed _requestId, bytes32 indexed _responseId, IOracle.Dispute _dispute, uint256 _blockNumber); + event ResponseDisputed( + bytes32 indexed _requestId, + bytes32 indexed _responseId, + bytes32 indexed _disputeId, + IOracle.Dispute _dispute, + uint256 _blockNumber + ); /** * @notice Deploy the target and mock oracle @@ -224,7 +230,9 @@ contract BondedResponseModule_Unit_DisputeResponse is BaseTest { mockRequest.disputeModuleData = abi.encode(IBondedDisputeModule.RequestParameters(accountingExtension, _token, _bondSize)); bytes32 _requestId = _getId(mockRequest); + mockResponse.requestId = _requestId; mockDispute.requestId = _requestId; + mockDispute.responseId = _getId(mockResponse); // Mock and expect the call to the accounting extension, initiating the bond _mockAndExpect( @@ -235,6 +243,10 @@ contract BondedResponseModule_Unit_DisputeResponse is BaseTest { abi.encode() ); + // Expect the event + vm.expectEmit(true, true, true, true, address(bondedDisputeModule)); + emit ResponseDisputed(_requestId, _getId(mockResponse), _getId(mockDispute), mockDispute, block.number); + // Test: call disputeResponse vm.prank(address(oracle)); bondedDisputeModule.disputeResponse(mockRequest, mockResponse, mockDispute); diff --git a/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol b/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol index 1132c7c8..617dbc44 100644 --- a/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol +++ b/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol @@ -259,7 +259,7 @@ contract CircuitResolverModule_Unit_OnDisputeStatusChange is BaseTest { IERC20 _randomToken, uint256 _bondSize, bytes memory _callData - ) public { + ) public assumeFuzzable(address(_accountingExtension)) { mockRequest.disputeModuleData = abi.encode( ICircuitResolverModule.RequestParameters({ callData: _callData, @@ -279,15 +279,18 @@ contract CircuitResolverModule_Unit_OnDisputeStatusChange is BaseTest { mockResponse.response = _encodedCorrectResponse; mockResponse.proposer = makeAddr('proposer'); - // Mock and expect the call to the oracle, finalizing the request - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.finalize, (mockRequest, mockResponse)), abi.encode()); - // Populate the mock dispute with the correct values mockDispute.responseId = _getId(mockResponse); mockDispute.requestId = _requestId; bytes32 _disputeId = _getId(mockDispute); IOracle.DisputeStatus _status = IOracle.DisputeStatus.Lost; + // Mock and expect the call to the oracle, getting the dispute status + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(_status)); + + // Mock and expect the call to the oracle, finalizing the request + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.finalize, (mockRequest, mockResponse)), abi.encode()); + // Check: is the event emitted? vm.expectEmit(true, true, true, true, address(circuitResolverModule)); emit DisputeStatusChanged(_disputeId, mockDispute, _status); @@ -301,7 +304,7 @@ contract CircuitResolverModule_Unit_OnDisputeStatusChange is BaseTest { IERC20 _randomToken, uint256 _bondSize, bytes memory _callData - ) public { + ) public assumeFuzzable(address(_accountingExtension)) { mockRequest.disputeModuleData = abi.encode( ICircuitResolverModule.RequestParameters({ callData: _callData, @@ -327,6 +330,9 @@ contract CircuitResolverModule_Unit_OnDisputeStatusChange is BaseTest { bytes32 _disputeId = _getId(mockDispute); IOracle.DisputeStatus _status = IOracle.DisputeStatus.Won; + // Mock and expect the call to the oracle, getting the dispute status + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(_status)); + // Mock and expect the call to the accounting extension, paying the disputer _mockAndExpect( address(_accountingExtension), diff --git a/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol b/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol index b38234e5..2c3bc89c 100644 --- a/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol +++ b/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol @@ -30,7 +30,7 @@ contract BaseTest is Test, Helpers { // A mock tree verifier ITreeVerifier public treeVerifier; // Mock addresses - IERC20 public _token = IERC20(makeAddr('token')); + IERC20 public token = IERC20(makeAddr('token')); // Mock request data bytes32[32] internal _treeBranches = [ @@ -162,7 +162,7 @@ contract RootVerificationModule_Unit_DisputeResponse is BaseTest { leavesToInsert: _leavesToInsert, treeVerifier: treeVerifier, accountingExtension: _accountingExtension, - bondToken: _token, + bondToken: token, bondSize: _bondSize }) ); @@ -202,7 +202,7 @@ contract RootVerificationModule_Unit_DisputeResponse is BaseTest { leavesToInsert: _leavesToInsert, treeVerifier: treeVerifier, accountingExtension: _accountingExtension, - bondToken: _token, + bondToken: token, bondSize: _bondSize }) ); @@ -258,7 +258,7 @@ contract RootVerificationModule_Unit_DisputeResponse is BaseTest { leavesToInsert: _leavesToInsert, treeVerifier: treeVerifier, accountingExtension: _accountingExtension, - bondToken: _token, + bondToken: token, bondSize: _bondSize }) ); diff --git a/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol b/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol index 129ce78f..46570f65 100644 --- a/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol @@ -356,7 +356,7 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { // Check: is totalVotes updated? assertEq(_totalVotes, _amountOfVotes); - // Check: is voter data proplerly updated? + // Check: is voter data properly updated? IPrivateERC20ResolutionModule.VoterData memory _voterData = module.forTest_getVoterData(_disputeId, _voter); assertEq(_voterData.numOfVotes, _amountOfVotes); } diff --git a/solidity/test/utils/Helpers.sol b/solidity/test/utils/Helpers.sol index 9e7beab2..41bd14a5 100644 --- a/solidity/test/utils/Helpers.sol +++ b/solidity/test/utils/Helpers.sol @@ -3,9 +3,6 @@ pragma solidity ^0.8.19; import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; import {DSTestPlus} from '@defi-wonderland/solidity-utils/solidity/test/DSTestPlus.sol'; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -import {IAccountingExtension} from '../../interfaces/extensions/IAccountingExtension.sol'; import {TestConstants} from './TestConstants.sol'; contract Helpers is DSTestPlus, TestConstants { @@ -38,7 +35,7 @@ contract Helpers is DSTestPlus, TestConstants { function _assumeFuzzable(address _address) internal view { assumeNotForgeAddress(_address); assumeNotZeroAddress(_address); - assumeNotPrecompile(_address, block.chainid); // using Optimsim chaind id for precompiles filtering + assumeNotPrecompile(_address, block.chainid); // using Optimism chaind id for precompiles filtering } /** diff --git a/yarn.lock b/yarn.lock index a0be5325..ff1d0fbe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3194,10 +3194,10 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" -solhint-plugin-defi-wonderland@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/solhint-plugin-defi-wonderland/-/solhint-plugin-defi-wonderland-1.1.0.tgz#6b82ee4da9fea1a4aeed4409915c3980f0f6b6a2" - integrity sha512-dl5wyURqrs9KgkDjYDW5RN55Fij7rrtybluqG45csilqD9x2vd+iAkaMD2VU150TqmfrcYN5p1Rer3sKWRNIPQ== +solhint-plugin-defi-wonderland@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/solhint-plugin-defi-wonderland/-/solhint-plugin-defi-wonderland-1.1.2.tgz#9bb26e173dd14c23eb28d107dd5ee21953ce0d5e" + integrity sha512-LkszaY3JwTpnWPRWTjPVzemMl+2LSw64Xd0wOE3dmPvBsELfvPo659zfQexLfxEtuubfuA33rw5WQw0LBC2alA== dependencies: solhint "3.3.7"