From 46e5da536288ff30edfcac961e597cc3ba2fd6e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 17 May 2024 17:55:11 -0300 Subject: [PATCH 1/3] [WIP] Horizon: add subgraph data service (#946) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: add first draft IHorizonStaking * fix: horizon staking interface compilation errors Signed-off-by: Tomás Migone * chore: bump contracts package version Signed-off-by: Tomás Migone * fix(contracts): build type code Signed-off-by: Tomás Migone * feat: add subgraph service boilerplate Signed-off-by: Tomás Migone * chore: add subgraph service contracts boilerplate Signed-off-by: Tomás Migone * feat(ss): add register flow Signed-off-by: Tomás Migone * feat(ss): add slash flow Signed-off-by: Tomás Migone * wip: redeem flow Signed-off-by: Tomás Migone * feat: query fee redeem flow Signed-off-by: Tomás Migone * fix: add events to subgraph service redeem flow Signed-off-by: Tomás Migone * feat: start allocation flows Signed-off-by: Tomás Migone * chore(horizon): add horizon package boilerplate Signed-off-by: Tomás Migone * chore: horizon dispute manager WIP * chore: testing * chore: rename DisputeManager to SubgraphDisputeManager * fix: remove unneeded code * fix: merge conflicts * fix: indentation * chore: add Ownable * chore: use errors * chore: use subgraph service contract for dispute tests * fix: remove unused code * feat: start work on data service sdk Signed-off-by: Tomás Migone * feat(data-service): break out fee model from subgraph service Signed-off-by: Tomás Migone * chore: simplify data service sdk naming convention Signed-off-by: Tomás Migone * chore(ss): simplify naming convention Signed-off-by: Tomás Migone * fix: cleanup Signed-off-by: Tomás Migone * feat(subgraph-service): register via ds sdk Signed-off-by: Tomás Migone * feat(data-service): add ownable and rescuable data service extensions Signed-off-by: Tomás Migone * feat: provision tracker Signed-off-by: Tomás Migone * feat: add stop service to subgraph service Signed-off-by: Tomás Migone * chore: minor tweaks to ss Signed-off-by: Tomás Migone * chore: update start stop service in ss Signed-off-by: Tomás Migone * feat: improvements to data service framework Signed-off-by: Tomás Migone * feat(ss): dont delete allos when closing, update getallocation Signed-off-by: Tomás Migone * fix: final touches to service flows on subgraph service Signed-off-by: Tomás Migone * chore(ss): rewrite using allocation library Signed-off-by: Tomás Migone * chore(ds): rewrite data service using provision handler and getter Signed-off-by: Tomás Migone * chore(ss): refactor with allocation manager Signed-off-by: Tomás Migone * chore: provide not implemented default fns for data service base contract Signed-off-by: Tomás Migone * feat(ss): revamp allocations, add legacy allocations and migrations Signed-off-by: Tomás Migone * feat(ds): add pausable data service extension Signed-off-by: Tomás Migone * fix(ds): add rescuer role to DataServiceRescuable, dont use Ownable Signed-off-by: Tomás Migone * chore(ds): move PPM lib to data service sdk Signed-off-by: Tomás Migone * chore(ds): rename ProvisionHandler to ProvisionManager Signed-off-by: Tomás Migone * chore: clean up inheritance and interfacesd Signed-off-by: Tomás Migone * chore: cleanup dependencies Signed-off-by: Tomás Migone * chore: ensure consistent stlye in sol files Signed-off-by: Tomás Migone * chore(ss): use math ppm for dispute manager Signed-off-by: Tomás Migone * chore: use attestation lib for dispute manager Signed-off-by: Tomás Migone * chore: attestation manager Signed-off-by: Tomás Migone * chore: remove unused event Signed-off-by: Tomás Migone * chore: readd event in proper contract Signed-off-by: Tomás Migone * docs: add natspec to data service contract Signed-off-by: Tomás Migone * feat: implement curation fees distribution Signed-off-by: Tomás Migone * chore(solhint): update lint rules Signed-off-by: Tomás Migone * chore: apply new linting rules Signed-off-by: Tomás Migone * fix: stack too deep error in subgraph service collect Signed-off-by: Tomás Migone * feat(solhint): add custom leading underscore rule Signed-off-by: Tomás Migone * feat(solhint): fix leading underscore errors with plugin Signed-off-by: Tomás Migone * fix(solhint): properly lint function parameters Signed-off-by: Tomás Migone * chore: apply latest linting rules Signed-off-by: Tomás Migone * docs: natspec for data service interface Signed-off-by: Tomás Migone * chore: fix linting Signed-off-by: Tomás Migone * fix: horizon dispute manager tests * fix: yarn lock Signed-off-by: Tomás Migone --------- Signed-off-by: Tomás Migone Co-authored-by: Pablo Carranza Velez Co-authored-by: Miguel de Elias Co-authored-by: Maikol <86025070+Maikol@users.noreply.github.com> --- .github/workflows/ci-subgraph-service.yml | 30 + .gitmodules | 3 + .husky/pre-commit | 5 + README.md | 1 + package.json | 1 + .../contracts/governance/Controller.sol | 2 +- .../contracts/governance/Governed.sol | 2 +- .../contracts/governance/Pausable.sol | 2 +- .../contracts/staking/IHorizonStaking.sol | 166 ++ .../contracts/contracts/token/IGraphToken.sol | 2 +- .../contracts/contracts/utils/TokenUtils.sol | 2 +- packages/horizon/contracts/SimpleTest.sol | 10 + packages/horizon/test/SimpleTest.t.sol | 17 + packages/horizon/test/SimpleTest.ts | 23 + packages/solhint-graph-config/README.md | 7 + packages/solhint-graph-config/index.js | 24 +- packages/solhint-graph-config/package.json | 5 +- packages/solhint-graph-config/plugin/index.js | 114 + .../solhint-graph-config/plugin/package.json | 5 + packages/subgraph-service/README.md | 13 + .../contracts/DisputeManager.sol | 783 +++++ .../contracts/DisputeManagerStorage.sol | 33 + .../contracts/SubgraphService.sol | 273 ++ .../contracts/SubgraphServiceStorage.sol | 19 + .../contracts/TAPVerifier.sol | 220 ++ .../contracts/data-service/DataService.sol | 39 + .../data-service/DataServiceStorage.sol | 7 + .../contracts/data-service/GraphDirectory.sol | 55 + .../contracts/data-service/IDataService.sol | 164 ++ .../extensions/DataServiceFees.sol | 99 + .../extensions/DataServiceFeesStorage.sol | 20 + .../extensions/DataServicePausable.sol | 35 + .../extensions/DataServiceRescuable.sol | 64 + .../extensions/IDataServiceFees.sol | 27 + .../extensions/IDataServicePausable.sol | 9 + .../extensions/IDataServiceRescuable.sol | 9 + .../data-service/libraries/Denominations.sol | 15 + .../data-service/libraries/PPMMath.sol | 32 + .../libraries/ProvisionGetter.sol | 21 + .../libraries/ProvisionTracker.sol | 43 + .../data-service/libraries/UintRange.sol | 10 + .../utilities/ProvisionManager.sol | 109 + .../utilities/ProvisionManagerStorage.sol | 25 + .../contracts/interfaces/IDisputeManager.sol | 86 + .../contracts/interfaces/IGraphEscrow.sol | 6 + .../contracts/interfaces/IGraphPayments.sol | 17 + .../contracts/interfaces/ISubgraphService.sol | 32 + .../contracts/interfaces/ITAPVerifier.sol | 24 + .../contracts/libraries/Allocation.sol | 101 + .../contracts/libraries/Attestation.sol | 115 + .../contracts/libraries/LegacyAllocation.sol | 46 + .../contracts/utilities/AllocationManager.sol | 251 ++ .../utilities/AllocationManagerStorage.sol | 24 + .../utilities/AttestationManager.sol | 77 + .../utilities/AttestationManagerStorage.sol | 9 + .../contracts/utilities/Directory.sol | 38 + packages/subgraph-service/eslint.config.js | 21 + packages/subgraph-service/foundry.toml | 6 + packages/subgraph-service/hardhat.config.ts | 37 + packages/subgraph-service/lib/forge-std | 1 + packages/subgraph-service/package.json | 63 + packages/subgraph-service/prettier.config.js | 2 + packages/subgraph-service/remappings.txt | 5 + packages/subgraph-service/scripts/deploy.ts | 28 + .../test/DisputeManager.t.sol | 501 ++++ .../test/mocks/MockGRTToken.sol | 46 + .../test/mocks/MockHorizonStaking.sol | 108 + .../test/mocks/MockRewardsManager.sol | 50 + packages/subgraph-service/tsconfig.json | 18 + yarn.lock | 2603 +++++++---------- 70 files changed, 5358 insertions(+), 1502 deletions(-) create mode 100644 .github/workflows/ci-subgraph-service.yml create mode 100644 packages/contracts/contracts/staking/IHorizonStaking.sol create mode 100644 packages/horizon/contracts/SimpleTest.sol create mode 100644 packages/horizon/test/SimpleTest.t.sol create mode 100644 packages/horizon/test/SimpleTest.ts create mode 100644 packages/solhint-graph-config/plugin/index.js create mode 100644 packages/solhint-graph-config/plugin/package.json create mode 100644 packages/subgraph-service/README.md create mode 100644 packages/subgraph-service/contracts/DisputeManager.sol create mode 100644 packages/subgraph-service/contracts/DisputeManagerStorage.sol create mode 100644 packages/subgraph-service/contracts/SubgraphService.sol create mode 100644 packages/subgraph-service/contracts/SubgraphServiceStorage.sol create mode 100644 packages/subgraph-service/contracts/TAPVerifier.sol create mode 100644 packages/subgraph-service/contracts/data-service/DataService.sol create mode 100644 packages/subgraph-service/contracts/data-service/DataServiceStorage.sol create mode 100644 packages/subgraph-service/contracts/data-service/GraphDirectory.sol create mode 100644 packages/subgraph-service/contracts/data-service/IDataService.sol create mode 100644 packages/subgraph-service/contracts/data-service/extensions/DataServiceFees.sol create mode 100644 packages/subgraph-service/contracts/data-service/extensions/DataServiceFeesStorage.sol create mode 100644 packages/subgraph-service/contracts/data-service/extensions/DataServicePausable.sol create mode 100644 packages/subgraph-service/contracts/data-service/extensions/DataServiceRescuable.sol create mode 100644 packages/subgraph-service/contracts/data-service/extensions/IDataServiceFees.sol create mode 100644 packages/subgraph-service/contracts/data-service/extensions/IDataServicePausable.sol create mode 100644 packages/subgraph-service/contracts/data-service/extensions/IDataServiceRescuable.sol create mode 100644 packages/subgraph-service/contracts/data-service/libraries/Denominations.sol create mode 100644 packages/subgraph-service/contracts/data-service/libraries/PPMMath.sol create mode 100644 packages/subgraph-service/contracts/data-service/libraries/ProvisionGetter.sol create mode 100644 packages/subgraph-service/contracts/data-service/libraries/ProvisionTracker.sol create mode 100644 packages/subgraph-service/contracts/data-service/libraries/UintRange.sol create mode 100644 packages/subgraph-service/contracts/data-service/utilities/ProvisionManager.sol create mode 100644 packages/subgraph-service/contracts/data-service/utilities/ProvisionManagerStorage.sol create mode 100644 packages/subgraph-service/contracts/interfaces/IDisputeManager.sol create mode 100644 packages/subgraph-service/contracts/interfaces/IGraphEscrow.sol create mode 100644 packages/subgraph-service/contracts/interfaces/IGraphPayments.sol create mode 100644 packages/subgraph-service/contracts/interfaces/ISubgraphService.sol create mode 100644 packages/subgraph-service/contracts/interfaces/ITAPVerifier.sol create mode 100644 packages/subgraph-service/contracts/libraries/Allocation.sol create mode 100644 packages/subgraph-service/contracts/libraries/Attestation.sol create mode 100644 packages/subgraph-service/contracts/libraries/LegacyAllocation.sol create mode 100644 packages/subgraph-service/contracts/utilities/AllocationManager.sol create mode 100644 packages/subgraph-service/contracts/utilities/AllocationManagerStorage.sol create mode 100644 packages/subgraph-service/contracts/utilities/AttestationManager.sol create mode 100644 packages/subgraph-service/contracts/utilities/AttestationManagerStorage.sol create mode 100644 packages/subgraph-service/contracts/utilities/Directory.sol create mode 100644 packages/subgraph-service/eslint.config.js create mode 100644 packages/subgraph-service/foundry.toml create mode 100644 packages/subgraph-service/hardhat.config.ts create mode 160000 packages/subgraph-service/lib/forge-std create mode 100644 packages/subgraph-service/package.json create mode 100644 packages/subgraph-service/prettier.config.js create mode 100644 packages/subgraph-service/remappings.txt create mode 100644 packages/subgraph-service/scripts/deploy.ts create mode 100644 packages/subgraph-service/test/DisputeManager.t.sol create mode 100644 packages/subgraph-service/test/mocks/MockGRTToken.sol create mode 100644 packages/subgraph-service/test/mocks/MockHorizonStaking.sol create mode 100644 packages/subgraph-service/test/mocks/MockRewardsManager.sol create mode 100644 packages/subgraph-service/tsconfig.json diff --git a/.github/workflows/ci-subgraph-service.yml b/.github/workflows/ci-subgraph-service.yml new file mode 100644 index 000000000..bda15deff --- /dev/null +++ b/.github/workflows/ci-subgraph-service.yml @@ -0,0 +1,30 @@ +name: CI - packages/subgraph-service + +env: + CI: true + +on: + push: + branches: "*" + paths: + - packages/subgraph-service/** + pull_request: + branches: "*" + paths: + - packages/subgraph-service/** + workflow_dispatch: + +jobs: + test-ci: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Set up environment + uses: ./.github/actions/setup + - name: Run tests + run: | + pushd packages/subgraph-service + yarn test \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index edd86d2b7..6e4ecf4c6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ +[submodule "packages/subgraph-service/lib/forge-std"] + path = packages/subgraph-service/lib/forge-std + url = https://github.com/foundry-rs/forge-std [submodule "packages/horizon/lib/forge-std"] path = packages/horizon/lib/forge-std url = https://github.com/foundry-rs/forge-std diff --git a/.husky/pre-commit b/.husky/pre-commit index 92fa26604..aa9adeab4 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -6,6 +6,11 @@ pushd packages/contracts npx --no-install lint-staged popd +# subgraph service +pushd packages/subgraph-service +npx --no-install lint-staged +popd + # data-edge pushd packages/data-edge npx --no-install lint-staged diff --git a/README.md b/README.md index a36de65bf..d9b46bb52 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ This repository is a Yarn workspaces monorepo containing the following packages: | [horizon](./packages/horizon) | [![npm version]()]() | Contracts for Graph Horizon, the next iteration of The Graph protocol. | | [sdk](./packages/sdk) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Fsdk.svg)](https://badge.fury.io/js/@graphprotocol%2Fsdk) | TypeScript based SDK to interact with the protocol contracts | | [solhint-graph-config](./packages/eslint-graph-config) | [![npm version]()]() | Shared linting and formatting rules for Solidity projects. | +| [subgraph-service](./packages/subgraph-service) | [![npm version]()]() | Contracts for the Subgraph data service in Graph Horizon. | | [token-distribution](./packages/token-distribution) | - | Contracts managing token locks for network participants | diff --git a/package.json b/package.json index d27a50288..126006c96 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "packages/horizon", "packages/sdk", "packages/solhint-graph-config", + "packages/subgraph-service", "packages/token-distribution" ], "scripts": { diff --git a/packages/contracts/contracts/governance/Controller.sol b/packages/contracts/contracts/governance/Controller.sol index affb29a05..74854cbfe 100644 --- a/packages/contracts/contracts/governance/Controller.sol +++ b/packages/contracts/contracts/governance/Controller.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.7.6; +pragma solidity >=0.7.6 <0.9.0; import { IController } from "./IController.sol"; import { IManaged } from "./IManaged.sol"; diff --git a/packages/contracts/contracts/governance/Governed.sol b/packages/contracts/contracts/governance/Governed.sol index f692b2d19..570e2839c 100644 --- a/packages/contracts/contracts/governance/Governed.sol +++ b/packages/contracts/contracts/governance/Governed.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.7.6; +pragma solidity >=0.7.6 <0.9.0; /** * @title Graph Governance contract diff --git a/packages/contracts/contracts/governance/Pausable.sol b/packages/contracts/contracts/governance/Pausable.sol index 552b0aa15..1e9baf5fe 100644 --- a/packages/contracts/contracts/governance/Pausable.sol +++ b/packages/contracts/contracts/governance/Pausable.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.7.6; +pragma solidity >=0.7.6 <0.9.0; abstract contract Pausable { /** diff --git a/packages/contracts/contracts/staking/IHorizonStaking.sol b/packages/contracts/contracts/staking/IHorizonStaking.sol new file mode 100644 index 000000000..b45aee1ac --- /dev/null +++ b/packages/contracts/contracts/staking/IHorizonStaking.sol @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity >=0.7.6 <0.9.0; +pragma abicoder v2; + +interface Test { + function test() external returns (uint256); +} + +interface IHorizonStaking { + struct Provision { + // Service provider that created the provision + address serviceProvider; + // tokens in the provision + uint256 tokens; + // delegated tokens in the provision + uint256 delegatedTokens; + // tokens that are being thawed (and will stop being slashable soon) + uint256 tokensThawing; + // timestamp of provision creation + uint64 createdAt; + // authority to slash the provision + address verifier; + // max amount that can be taken by the verifier when slashing, expressed in parts-per-million of the amount slashed + uint32 maxVerifierCut; + // time, in seconds, tokens must thaw before being withdrawn + uint64 thawingPeriod; + } + + // the new "Indexer" struct + struct ServiceProviderInternal { + // Tokens on the Service Provider stake (staked by the provider) + uint256 tokensStaked; + // Tokens used in allocations + uint256 __DEPRECATED_tokensAllocated; + // Tokens locked for withdrawal subject to thawing period + uint256 __DEPRECATED_tokensLocked; + // Block when locked tokens can be withdrawn + uint256 __DEPRECATED_tokensLockedUntil; + // tokens used in a provision + uint256 tokensProvisioned; + // tokens that initiated a thawing in any one of the provider's provisions + uint256 tokensRequestedThaw; + // tokens that have been removed from any one of the provider's provisions after thawing + uint256 tokensFulfilledThaw; + // provisions that take priority for undelegation force thawing + bytes32[] forceThawProvisions; + } + + struct ServiceProvider { + // Tokens on the provider stake (staked by the provider) + uint256 tokensStaked; + // tokens used in a provision + uint256 tokensProvisioned; + // tokens that initiated a thawing in any one of the provider's provisions + uint256 tokensRequestedThaw; + // tokens that have been removed from any one of the provider's provisions after thawing + uint256 tokensFulfilledThaw; + // provisions that take priority for undelegation force thawing + bytes32[] forceThawProvisions; + } + + struct DelegationPool { + uint32 __DEPRECATED_cooldownBlocks; // solhint-disable-line var-name-mixedcase + uint32 __DEPRECATED_indexingRewardCut; // in PPM + uint32 __DEPRECATED_queryFeeCut; // in PPM + uint256 __DEPRECATED_updatedAtBlock; // Block when the pool was last updated + uint256 tokens; // Total tokens as pool reserves + uint256 shares; // Total shares minted in the pool + mapping(address => Delegation) delegators; // Mapping of delegator => Delegation + } + + struct Delegation { + // shares owned by the delegator in the pool + uint256 shares; + // tokens delegated to the pool + uint256 tokens; + // Timestamp when locked tokens can be undelegated (after the timelock) + uint256 tokensLockedUntil; + } + + struct ThawRequest { + // tokens that are being thawed by this request + uint256 tokens; + // the provision id to which this request corresponds to + bytes32 provisionId; + // the address that initiated the thaw request, allowed to remove the funds once thawed + address owner; + // the timestamp when the thawed funds can be removed from the provision + uint64 thawingUntil; + // the value of `ServiceProvider.tokensRequestedThaw` the moment the thaw request is created + uint256 tokensRequestedThawSnapshot; + } + + // whitelist/deny a verifier + function allowVerifier(address verifier, bool allow) external; + + // deposit stake + function stake(uint256 tokens) external; + + // create a provision + function provision(uint256 tokens, address verifier, uint32 maxVerifierCut, uint64 thawingPeriod) external; + + // accept a provision + function acceptProvision(address serviceProvider) external; + + // initiate a thawing to remove tokens from a provision + function thaw(bytes32 provisionId, uint256 tokens) external returns (bytes32 thawRequestId); + + // moves thawed stake from a provision back into the provider's available stake + function deprovision(bytes32 thawRequestId) external; + + // moves thawed stake from one provision into another provision + function reprovision(bytes32 thawRequestId, bytes32 provisionId) external; + + // moves thawed stake back to the owner's account - stake is removed from the protocol + function withdraw(bytes32 thawRequestId) external; + + // delegate tokens to a provider + function delegate(address serviceProvider, uint256 tokens) external; + + // undelegate tokens + function undelegate( + address serviceProvider, + uint256 tokens, + bytes32[] calldata provisions + ) external returns (bytes32 thawRequestId); + + // slash a service provider + function slash(address serviceProvider, uint256 tokens, uint256 reward, address rewardsDestination) external; + + // set the Service Provider's preferred provisions to be force thawed + function setForceThawProvisions(bytes32[] calldata provisions) external; + + // total staked tokens to the provider + // `ServiceProvider.tokensStaked + DelegationPool.serviceProvider.tokens` + function getStake(address serviceProvider) external view returns (uint256 tokens); + + // staked tokens that are currently not provisioned, aka idle stake + // `getStake(serviceProvider) - ServiceProvider.tokensProvisioned` + function getIdleStake(address serviceProvider) external view returns (uint256 tokens); + + // staked tokens the provider can provision before hitting the delegation cap + // `ServiceProvider.tokensStaked * Staking.delegationRatio - Provision.tokensProvisioned` + function getCapacity(address serviceProvider) external view returns (uint256 tokens); + + // provisioned tokens that are not being used + // `Provision.tokens - Provision.tokensThawing` + function getTokensAvailable(address serviceProvider, address verifier) external view returns (uint256 tokens); + + function getServiceProvider(address serviceProvider) external view returns (ServiceProvider memory); + + function getProvision(address serviceProvider, address verifier) external view returns (Provision memory); + + /** + * @notice Check if an operator is authorized for the caller on a specific verifier / data service. + * @param _operator The address to check for auth + * @param _serviceProvider The service provider on behalf of whom they're claiming to act + * @param _verifier The verifier / data service on which they're claiming to act + */ + function isAuthorized(address _operator, address _serviceProvider, address _verifier) external view returns (bool); + + function getDelegationCut(address serviceProvider, uint8 paymentType) external view returns (uint256 delegationCut); + function addToDelegationPool(address serviceProvider, uint256 tokens) external; + function stakeToProvision(address _serviceProvider, address _verifier, uint256 _tokens) external; +} diff --git a/packages/contracts/contracts/token/IGraphToken.sol b/packages/contracts/contracts/token/IGraphToken.sol index 8255e18d5..f24467d42 100644 --- a/packages/contracts/contracts/token/IGraphToken.sol +++ b/packages/contracts/contracts/token/IGraphToken.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.7.6; +pragma solidity >=0.7.6 <=0.9.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/packages/contracts/contracts/utils/TokenUtils.sol b/packages/contracts/contracts/utils/TokenUtils.sol index 265f918a5..09d9ed704 100644 --- a/packages/contracts/contracts/utils/TokenUtils.sol +++ b/packages/contracts/contracts/utils/TokenUtils.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.7.6; +pragma solidity >=0.7.6 <=0.8.24; import "../token/IGraphToken.sol"; diff --git a/packages/horizon/contracts/SimpleTest.sol b/packages/horizon/contracts/SimpleTest.sol new file mode 100644 index 000000000..5cc28d9cc --- /dev/null +++ b/packages/horizon/contracts/SimpleTest.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.4.0 <0.9.0; + +import { Test } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; + +contract SimpleTest is Test { + function test() external pure returns (uint256) { + return 42; + } +} diff --git a/packages/horizon/test/SimpleTest.t.sol b/packages/horizon/test/SimpleTest.t.sol new file mode 100644 index 000000000..b130e5d34 --- /dev/null +++ b/packages/horizon/test/SimpleTest.t.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.10; + +import "forge-std/Test.sol"; +import { SimpleTest } from "../contracts/SimpleTest.sol"; + +contract ContractTest is Test { + SimpleTest simpleTest; + + function setUp() public { + simpleTest = new SimpleTest(); + } + + function test_NumberIs42() public { + assertEq(simpleTest.test(), 42); + } +} diff --git a/packages/horizon/test/SimpleTest.ts b/packages/horizon/test/SimpleTest.ts new file mode 100644 index 000000000..cfcfb1443 --- /dev/null +++ b/packages/horizon/test/SimpleTest.ts @@ -0,0 +1,23 @@ +import hardhat from 'hardhat' + +import { expect } from 'chai' +import { loadFixture } from '@nomicfoundation/hardhat-toolbox/network-helpers' + +const ethers = hardhat.ethers + +describe('SimpleTest', function () { + async function deployFixture() { + const [owner] = await ethers.getSigners() + const SimpleTest = await ethers.getContractFactory('SimpleTest') + const simpleTest = await SimpleTest.deploy() + return { simpleTest, owner } + } + + describe('Deployment', function () { + it('Should return 42', async function () { + const { simpleTest } = await loadFixture(deployFixture) + + expect(await simpleTest.test()).to.equal(42) + }) + }) +}) diff --git a/packages/solhint-graph-config/README.md b/packages/solhint-graph-config/README.md index 7a724946b..4257b2dd8 100644 --- a/packages/solhint-graph-config/README.md +++ b/packages/solhint-graph-config/README.md @@ -17,6 +17,13 @@ yarn add --dev solhint solhint-graph-config yarn add --dev solhint solhint-graph-config@workspace:^x.y.z ``` +To use graph plugin you'll also need to manually add the plugin to your `package.json`: +```json + "devDependencies": { + "solhint-plugin-graph": "file:node_modules/solhint-graph-config/plugin" + } +``` + ### Configuration Run `solhint` with `node_modules/solhint-graph-config/index.js` as the configuration file. We suggest creating an npm script to make it easier to run: diff --git a/packages/solhint-graph-config/index.js b/packages/solhint-graph-config/index.js index b37be2810..f7193d748 100644 --- a/packages/solhint-graph-config/index.js +++ b/packages/solhint-graph-config/index.js @@ -1,12 +1,28 @@ module.exports = { + plugins: [ 'graph' ], extends: 'solhint:recommended', rules: { - 'func-visibility': ['warn', { ignoreConstructors: true }], - 'compiler-version': ['off'], + // best practices + 'no-empty-blocks': 'off', 'constructor-syntax': 'warn', + + // style rules + 'private-vars-leading-underscore': 'off', // see graph/leading-underscore + 'const-name-snakecase': 'warn', + 'named-parameters-mapping': 'warn', + 'imports-on-top': 'warn', + 'ordering': 'warn', + 'visibility-modifier-order': 'warn', + + // miscellaneous 'quotes': ['error', 'double'], - 'reason-string': ['off'], + + // security + 'compiler-version': ['off'], + 'func-visibility': ['warn', { ignoreConstructors: true }], 'not-rely-on-time': 'off', - 'no-empty-blocks': 'off', + + // graph + 'graph/leading-underscore': 'warn', }, } diff --git a/packages/solhint-graph-config/package.json b/packages/solhint-graph-config/package.json index 2ead8bbef..d976b3cb9 100644 --- a/packages/solhint-graph-config/package.json +++ b/packages/solhint-graph-config/package.json @@ -5,9 +5,12 @@ "main": "index.js", "author": "The Graph Team", "license": "GPL-2.0-or-later", + "dependencies": { + "solhint-plugin-graph": "file:plugin" + }, "peerDependencies": { "prettier": "^3.2.5", "prettier-plugin-solidity": "^1.3.1", - "solhint": "^4.1.1" + "solhint": "^4.5.4" } } diff --git a/packages/solhint-graph-config/plugin/index.js b/packages/solhint-graph-config/plugin/index.js new file mode 100644 index 000000000..cd16840e8 --- /dev/null +++ b/packages/solhint-graph-config/plugin/index.js @@ -0,0 +1,114 @@ +function hasLeadingUnderscore(text) { + return text && text[0] === '_' +} + +class Base { + constructor(reporter, config, source, fileName) { + this.reporter = reporter; + this.ignored = this.constructor.global; + this.ruleId = this.constructor.ruleId; + if (this.ruleId === undefined) { + throw Error('missing ruleId static property'); + } + } + + error(node, message, fix) { + if (!this.ignored) { + this.reporter.error(node, this.ruleId, message, fix); + } + } +} + +module.exports = [ + class extends Base { + static ruleId = 'leading-underscore'; + + ContractDefinition(node) { + if (node.kind === 'library') { + this.inLibrary = true + } + } + + 'ContractDefinition:exit'() { + this.inLibrary = false + } + + StateVariableDeclaration() { + this.inStateVariableDeclaration = true + } + + 'StateVariableDeclaration:exit'() { + this.inStateVariableDeclaration = false + } + + VariableDeclaration(node) { + if (!this.inLibrary) { + if (!this.inStateVariableDeclaration) { + this.validateName(node, false, 'variable') + return + } + + this.validateName(node, 'variable') + } + + } + + FunctionDefinition(node) { + if (!this.inLibrary) { + if (!node.name) { + return + } + for (const parameter of node.parameters) { + parameter.visibility = node.visibility + } + + this.validateName(node, 'function') + + } + } + + validateName(node, type) { + const isPrivate = node.visibility === 'private' + const isInternal = node.visibility === 'internal' || node.visibility === 'default' + const isConstant = node.isDeclaredConst + const isImmutable = node.isImmutable + const shouldHaveLeadingUnderscore = (isPrivate || isInternal) && !(isConstant || isImmutable) + + if (node.name === null) { + return + } + + if (hasLeadingUnderscore(node.name) !== shouldHaveLeadingUnderscore) { + this._error(node, node.name, shouldHaveLeadingUnderscore, type) + } + } + + fixStatement(node, shouldHaveLeadingUnderscore, type) { + let range + + if (type === 'function') { + range = node.range + range[0] += 8 + } else if (type === 'parameter') { + range = node.identifier.range + } else { + range = node.identifier.range + range[0] -= 1 + } + + return (fixer) => + shouldHaveLeadingUnderscore + ? fixer.insertTextBeforeRange(range, ' _') + : fixer.removeRange([range[0] + 1, range[0] + 1]) + } + + _error(node, name, shouldHaveLeadingUnderscore, type) { + this.error( + node, + `'${name}' ${shouldHaveLeadingUnderscore ? 'should' : 'should not'} start with _`, + this.fixStatement(node, shouldHaveLeadingUnderscore, type) + ) + } + }, + +]; \ No newline at end of file diff --git a/packages/solhint-graph-config/plugin/package.json b/packages/solhint-graph-config/plugin/package.json new file mode 100644 index 000000000..53bab497d --- /dev/null +++ b/packages/solhint-graph-config/plugin/package.json @@ -0,0 +1,5 @@ +{ + "name": "solhint-plugin-graph", + "version": "0.0.0", + "private": true +} \ No newline at end of file diff --git a/packages/subgraph-service/README.md b/packages/subgraph-service/README.md new file mode 100644 index 000000000..7be82e5d6 --- /dev/null +++ b/packages/subgraph-service/README.md @@ -0,0 +1,13 @@ +# Sample Hardhat Project + +This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract. + +Try running some of the following tasks: + +```shell +npx hardhat help +npx hardhat test +REPORT_GAS=true npx hardhat test +npx hardhat node +npx hardhat run scripts/deploy.ts +``` diff --git a/packages/subgraph-service/contracts/DisputeManager.sol b/packages/subgraph-service/contracts/DisputeManager.sol new file mode 100644 index 000000000..dc5f785f2 --- /dev/null +++ b/packages/subgraph-service/contracts/DisputeManager.sol @@ -0,0 +1,783 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.24; +pragma abicoder v2; + +import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; +import { IDisputeManager } from "./interfaces/IDisputeManager.sol"; +import { ISubgraphService } from "./interfaces/ISubgraphService.sol"; + +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { DisputeManagerV1Storage } from "./DisputeManagerStorage.sol"; +import { GraphDirectory } from "./data-service/GraphDirectory.sol"; +import { AttestationManager } from "./utilities/AttestationManager.sol"; + +import { Math } from "@openzeppelin/contracts/utils/math/Math.sol"; +import { TokenUtils } from "@graphprotocol/contracts/contracts/utils/TokenUtils.sol"; +import { Allocation } from "./libraries/Allocation.sol"; +import { PPMMath } from "./data-service/libraries/PPMMath.sol"; +import { Attestation } from "./libraries/Attestation.sol"; + +/* + * @title DisputeManager + * @notice Provides a way to align the incentives of participants by having slashing as deterrent + * for incorrect behaviour. + * + * There are two types of disputes that can be created: Query disputes and Indexing disputes. + * + * Query Disputes: + * Graph nodes receive queries and return responses with signed receipts called attestations. + * An attestation can be disputed if the consumer thinks the query response was invalid. + * Indexers use the derived private key for an allocation to sign attestations. + * + * Indexing Disputes: + * Indexers present a Proof of Indexing (POI) when they close allocations to prove + * they were indexing a subgraph. The Staking contract emits that proof with the format + * keccak256(indexer.address, POI). + * Any challenger can dispute the validity of a POI by submitting a dispute to this contract + * along with a deposit. + * + * Arbitration: + * Disputes can only be accepted, rejected or drawn by the arbitrator role that can be delegated + * to a EOA or DAO. + */ +contract DisputeManager is Ownable, GraphDirectory, AttestationManager, DisputeManagerV1Storage, IDisputeManager { + using PPMMath for uint256; + + // -- Events -- + event ArbitratorSet(address arbitrator); + event DisputePeriodSet(uint64 disputePeriod); + event MinimumDepositSet(uint256 minimumDeposit); + event MaxSlashingPercentageSet(uint32 maxSlashingPercentage); + event FishermanRewardPercentageSet(uint32 fishermanRewardPercentage); + event SubgraphServiceSet(address indexed subgraphService); + + /** + * @dev Emitted when a query dispute is created for `subgraphDeploymentId` and `indexer` + * by `fisherman`. + * The event emits the amount of `tokens` deposited by the fisherman and `attestation` submitted. + */ + event QueryDisputeCreated( + bytes32 indexed disputeId, + address indexed indexer, + address indexed fisherman, + uint256 tokens, + bytes32 subgraphDeploymentId, + bytes attestation + ); + + /** + * @dev Emitted when an indexing dispute is created for `allocationId` and `indexer` + * by `fisherman`. + * The event emits the amount of `tokens` deposited by the fisherman. + */ + event IndexingDisputeCreated( + bytes32 indexed disputeId, + address indexed indexer, + address indexed fisherman, + uint256 tokens, + address allocationId + ); + + /** + * @dev Emitted when arbitrator accepts a `disputeId` to `indexer` created by `fisherman`. + * The event emits the amount `tokens` transferred to the fisherman, the deposit plus reward. + */ + event DisputeAccepted( + bytes32 indexed disputeId, + address indexed indexer, + address indexed fisherman, + uint256 tokens + ); + + /** + * @dev Emitted when arbitrator rejects a `disputeId` for `indexer` created by `fisherman`. + * The event emits the amount `tokens` burned from the fisherman deposit. + */ + event DisputeRejected( + bytes32 indexed disputeId, + address indexed indexer, + address indexed fisherman, + uint256 tokens + ); + + /** + * @dev Emitted when arbitrator draw a `disputeId` for `indexer` created by `fisherman`. + * The event emits the amount `tokens` used as deposit and returned to the fisherman. + */ + event DisputeDrawn(bytes32 indexed disputeId, address indexed indexer, address indexed fisherman, uint256 tokens); + + /** + * @dev Emitted when two disputes are in conflict to link them. + * This event will be emitted after each DisputeCreated event is emitted + * for each of the individual disputes. + */ + event DisputeLinked(bytes32 indexed disputeId1, bytes32 indexed disputeId2); + + // -- Errors -- + + error DisputeManagerNotArbitrator(); + error DisputeManagerNotFisherman(); + error DisputeManagerInvalidZeroAddress(); + error DisputeManagerDisputePeriodZero(); + error DisputeManagerZeroTokens(); + error DisputeManagerInvalidDispute(bytes32 disputeId); + error DisputeManagerInvalidMinimumDeposit(uint256 minimumDeposit); + error DisputeManagerInvalidFishermanReward(uint32 percentage); + error DisputeManagerInvalidMaxSlashingPercentage(uint32 maxSlashingPercentage); + error DisputeManagerInvalidSlashAmount(uint256 slashAmount); + error DisputeManagerInvalidDisputeStatus(IDisputeManager.DisputeStatus status); + error DisputeManagerInsufficientDeposit(uint256 deposit, uint256 minimumDeposit); + error DisputeManagerDisputeAlreadyCreated(bytes32 disputeId); + error DisputeManagerDisputePeriodNotFinished(); + error DisputeManagerMustAcceptRelatedDispute(bytes32 disputeId, bytes32 relatedDisputeId); + error DisputeManagerIndexerNotFound(address allocationId); + error DisputeManagerNonMatchingSubgraphDeployment(bytes32 subgraphDeploymentId1, bytes32 subgraphDeploymentId2); + error DisputeManagerNonConflictingAttestations( + bytes32 requestCID1, + bytes32 responseCID1, + bytes32 subgraphDeploymentId1, + bytes32 requestCID2, + bytes32 responseCID2, + bytes32 subgraphDeploymentId2 + ); + + // -- Modifiers -- + + /** + * @dev Check if the caller is the arbitrator. + */ + modifier onlyArbitrator() { + if (msg.sender != arbitrator) { + revert DisputeManagerNotArbitrator(); + } + _; + } + + modifier onlyPendingDispute(bytes32 disputeId) { + if (!isDisputeCreated(disputeId)) { + revert DisputeManagerInvalidDispute(disputeId); + } + + if (disputes[disputeId].status != IDisputeManager.DisputeStatus.Pending) { + revert DisputeManagerInvalidDisputeStatus(disputes[disputeId].status); + } + _; + } + + modifier onlyFisherman(bytes32 disputeId) { + if (!isDisputeCreated(disputeId)) { + revert DisputeManagerInvalidDispute(disputeId); + } + + if (msg.sender != disputes[disputeId].fisherman) { + revert DisputeManagerNotFisherman(); + } + _; + } + + // -- Functions -- + + /** + * @dev Initialize this contract. + * @param controller Address of Graph Controller contract + * @param arbitrator Arbitrator role + * @param disputePeriod Dispute period in seconds + * @param minimumDeposit Minimum deposit required to create a Dispute + * @param fishermanRewardPercentage Percent of slashed funds for fisherman (ppm) + * @param maxSlashingPercentage Maximum percentage of indexer stake that can be slashed (ppm) + */ + constructor( + address controller, + address arbitrator, + uint64 disputePeriod, + uint256 minimumDeposit, + uint32 fishermanRewardPercentage, + uint32 maxSlashingPercentage + ) Ownable(msg.sender) GraphDirectory(controller) { + // Settings + _setArbitrator(arbitrator); + _setDisputePeriod(disputePeriod); + _setMinimumDeposit(minimumDeposit); + _setFishermanRewardPercentage(fishermanRewardPercentage); + _setMaxSlashingPercentage(maxSlashingPercentage); + } + + /** + * @dev Create an indexing dispute for the arbitrator to resolve. + * The disputes are created in reference to an allocationId + * This function is called by a challenger that will need to `_deposit` at + * least `minimumDeposit` GRT tokens. + * @param allocationId The allocation to dispute + * @param deposit Amount of tokens staked as deposit + */ + function createIndexingDispute(address allocationId, uint256 deposit) external override returns (bytes32) { + // Get funds from submitter + _pullSubmitterDeposit(deposit); + + // Create a dispute + return _createIndexingDisputeWithAllocation(msg.sender, deposit, allocationId); + } + + /** + * @dev Create a query dispute for the arbitrator to resolve. + * This function is called by a fisherman that will need to `_deposit` at + * least `minimumDeposit` GRT tokens. + * @param attestationData Attestation bytes submitted by the fisherman + * @param deposit Amount of tokens staked as deposit + */ + function createQueryDispute(bytes calldata attestationData, uint256 deposit) external override returns (bytes32) { + // Get funds from submitter + _pullSubmitterDeposit(deposit); + + // Create a dispute + return + _createQueryDisputeWithAttestation( + msg.sender, + deposit, + Attestation.parse(attestationData), + attestationData + ); + } + + /** + * @dev Create query disputes for two conflicting attestations. + * A conflicting attestation is a proof presented by two different indexers + * where for the same request on a subgraph the response is different. + * For this type of dispute the submitter is not required to present a deposit + * as one of the attestation is considered to be right. + * Two linked disputes will be created and if the arbitrator resolve one, the other + * one will be automatically resolved. + * @param attestationData1 First attestation data submitted + * @param attestationData2 Second attestation data submitted + * @return DisputeId1, DisputeId2 + */ + function createQueryDisputeConflict( + bytes calldata attestationData1, + bytes calldata attestationData2 + ) external override returns (bytes32, bytes32) { + address fisherman = msg.sender; + + // Parse each attestation + Attestation.State memory attestation1 = Attestation.parse(attestationData1); + Attestation.State memory attestation2 = Attestation.parse(attestationData2); + + // Test that attestations are conflicting + if (!Attestation.areConflicting(attestation2, attestation1)) { + revert DisputeManagerNonConflictingAttestations( + attestation1.requestCID, + attestation1.responseCID, + attestation1.subgraphDeploymentId, + attestation2.requestCID, + attestation2.responseCID, + attestation2.subgraphDeploymentId + ); + } + + // Create the disputes + // The deposit is zero for conflicting attestations + bytes32 dId1 = _createQueryDisputeWithAttestation(fisherman, 0, attestation1, attestationData1); + bytes32 dId2 = _createQueryDisputeWithAttestation(fisherman, 0, attestation2, attestationData2); + + // Store the linked disputes to be resolved + disputes[dId1].relatedDisputeId = dId2; + disputes[dId2].relatedDisputeId = dId1; + + // Emit event that links the two created disputes + emit DisputeLinked(dId1, dId2); + + return (dId1, dId2); + } + + /** + * @dev The arbitrator accepts a dispute as being valid. + * This function will revert if the indexer is not slashable, whether because it does not have + * any stake available or the slashing percentage is configured to be zero. In those cases + * a dispute must be resolved using drawDispute or rejectDispute. + * @notice Accept a dispute with Id `disputeId` + * @param disputeId Id of the dispute to be accepted + * @param slashAmount Amount of tokens to slash from the indexer + */ + function acceptDispute( + bytes32 disputeId, + uint256 slashAmount + ) external override onlyArbitrator onlyPendingDispute(disputeId) { + Dispute storage dispute = disputes[disputeId]; + + // store the dispute status + dispute.status = IDisputeManager.DisputeStatus.Accepted; + + // Slash + uint256 tokensToReward = _slashIndexer(dispute.indexer, slashAmount); + + // Give the fisherman their reward and their deposit back + TokenUtils.pushTokens(GRAPH_TOKEN, dispute.fisherman, tokensToReward + dispute.deposit); + + if (_isDisputeInConflict(dispute)) { + rejectDispute(dispute.relatedDisputeId); + } + + emit DisputeAccepted(disputeId, dispute.indexer, dispute.fisherman, dispute.deposit + tokensToReward); + } + + /** + * @dev The arbitrator draws dispute. + * @notice Ignore a dispute with Id `disputeId` + * @param disputeId Id of the dispute to be disregarded + */ + function drawDispute(bytes32 disputeId) external override onlyArbitrator onlyPendingDispute(disputeId) { + Dispute storage dispute = disputes[disputeId]; + + // Return deposit to the fisherman + TokenUtils.pushTokens(GRAPH_TOKEN, dispute.fisherman, dispute.deposit); + + // resolve related dispute if any + _drawDisputeInConflict(dispute); + + // store dispute status + dispute.status = IDisputeManager.DisputeStatus.Drawn; + + emit DisputeDrawn(disputeId, dispute.indexer, dispute.fisherman, dispute.deposit); + } + + /** + * @dev Once the dispute period ends, if the disput status remains Pending, + * the fisherman can cancel the dispute and get back their initial deposit. + * @notice Cancel a dispute with Id `disputeId` + * @param disputeId Id of the dispute to be cancelled + */ + function cancelDispute(bytes32 disputeId) external override onlyFisherman(disputeId) onlyPendingDispute(disputeId) { + Dispute storage dispute = disputes[disputeId]; + + // Check if dispute period has finished + if (block.timestamp <= dispute.createdAt + disputePeriod) { + revert DisputeManagerDisputePeriodNotFinished(); + } + + // Return deposit to the fisherman + TokenUtils.pushTokens(GRAPH_TOKEN, dispute.fisherman, dispute.deposit); + + // resolve related dispute if any + _cancelDisputeInConflict(dispute); + + // store dispute status + dispute.status = IDisputeManager.DisputeStatus.Cancelled; + } + + /** + * @dev Set the arbitrator address. + * @notice Update the arbitrator to `_arbitrator` + * @param arbitrator The address of the arbitration contract or party + */ + function setArbitrator(address arbitrator) external override onlyOwner { + _setArbitrator(arbitrator); + } + + /** + * @dev Set the dispute period. + * @notice Update the dispute period to `_disputePeriod` in seconds + * @param disputePeriod Dispute period in seconds + */ + function setDisputePeriod(uint64 disputePeriod) external override { + _setDisputePeriod(disputePeriod); + } + + /** + * @dev Set the minimum deposit required to create a dispute. + * @notice Update the minimum deposit to `_minimumDeposit` Graph Tokens + * @param minimumDeposit The minimum deposit in Graph Tokens + */ + function setMinimumDeposit(uint256 minimumDeposit) external override onlyOwner { + _setMinimumDeposit(minimumDeposit); + } + + /** + * @dev Set the percent reward that the fisherman gets when slashing occurs. + * @notice Update the reward percentage to `_percentage` + * @param percentage Reward as a percentage of indexer stake + */ + function setFishermanRewardPercentage(uint32 percentage) external override onlyOwner { + _setFishermanRewardPercentage(percentage); + } + + /** + * @dev Set the maximum percentage that can be used for slashing indexers. + * @param maxSlashingPercentage Max percentage slashing for disputes + */ + function setMaxSlashingPercentage(uint32 maxSlashingPercentage) external override onlyOwner { + _setMaxSlashingPercentage(maxSlashingPercentage); + } + + /** + * @dev Set the subgraph service address. + * @notice Update the subgraph service to `_subgraphService` + * @param subgraphService The address of the subgraph service contract + */ + function setSubgraphService(address subgraphService) external onlyOwner { + _setSubgraphService(subgraphService); + } + + /** + * @dev Get the message hash that a indexer used to sign the receipt. + * Encodes a receipt using a domain separator, as described on + * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#specification. + * @notice Return the message hash used to sign the receipt + * @param receipt Receipt returned by indexer and submitted by fisherman + * @return Message hash used to sign the receipt + */ + function encodeReceipt(Attestation.Receipt memory receipt) external view returns (bytes32) { + return _encodeReceipt(receipt); + } + + /** + * @dev Get the verifier cut. + * @return Verifier cut in percentage (ppm) + */ + function getVerifierCut() external view returns (uint32) { + return fishermanRewardPercentage; + } + + /** + * @dev Get the dispute period. + * @return Dispute period in seconds + */ + function getDisputePeriod() external view returns (uint64) { + return disputePeriod; + } + + function areConflictingAttestations( + Attestation.State memory attestation1, + Attestation.State memory attestation2 + ) external pure returns (bool) { + return Attestation.areConflicting(attestation1, attestation2); + } + + /** + * @dev The arbitrator rejects a dispute as being invalid. + * @notice Reject a dispute with Id `disputeId` + * @param disputeId Id of the dispute to be rejected + */ + function rejectDispute(bytes32 disputeId) public override onlyArbitrator onlyPendingDispute(disputeId) { + Dispute storage dispute = disputes[disputeId]; + + // store dispute status + dispute.status = IDisputeManager.DisputeStatus.Rejected; + + // For conflicting disputes, the related dispute must be accepted + if (_isDisputeInConflict(dispute)) { + revert DisputeManagerMustAcceptRelatedDispute(disputeId, dispute.relatedDisputeId); + } + + // Burn the fisherman's deposit + TokenUtils.burnTokens(GRAPH_TOKEN, dispute.deposit); + + emit DisputeRejected(disputeId, dispute.indexer, dispute.fisherman, dispute.deposit); + } + + /** + * @dev Returns the indexer that signed an attestation. + * @param attestation Attestation + * @return indexer address + */ + function getAttestationIndexer(Attestation.State memory attestation) public view returns (address) { + // Get attestation signer. Indexers signs with the allocationId + address allocationId = _recoverSigner(attestation); + + Allocation.State memory alloc = subgraphService.getAllocation(allocationId); + if (alloc.indexer == address(0)) { + revert DisputeManagerIndexerNotFound(allocationId); + } + if (alloc.subgraphDeploymentId != attestation.subgraphDeploymentId) { + revert DisputeManagerNonMatchingSubgraphDeployment( + alloc.subgraphDeploymentId, + attestation.subgraphDeploymentId + ); + } + return alloc.indexer; + } + + /** + * @dev Return whether a dispute exists or not. + * @notice Return if dispute with Id `disputeId` exists + * @param disputeId True if dispute already exists + */ + function isDisputeCreated(bytes32 disputeId) public view override returns (bool) { + return disputes[disputeId].status != DisputeStatus.Null; + } + + /** + * @dev Create a query dispute passing the parsed attestation. + * To be used in createQueryDispute() and createQueryDisputeConflict() + * to avoid calling parseAttestation() multiple times + * `attestationData` is only passed to be emitted + * @param _fisherman Creator of dispute + * @param _deposit Amount of tokens staked as deposit + * @param _attestation Attestation struct parsed from bytes + * @param _attestationData Attestation bytes submitted by the fisherman + * @return DisputeId + */ + function _createQueryDisputeWithAttestation( + address _fisherman, + uint256 _deposit, + Attestation.State memory _attestation, + bytes memory _attestationData + ) private returns (bytes32) { + // Get the indexer that signed the attestation + address indexer = getAttestationIndexer(_attestation); + + // The indexer is disputable + IHorizonStaking.Provision memory provision = GRAPH_STAKING.getProvision(indexer, address(subgraphService)); + if (provision.tokens == 0) { + revert DisputeManagerZeroTokens(); + } + + // Create a disputeId + bytes32 disputeId = keccak256( + abi.encodePacked( + _attestation.requestCID, + _attestation.responseCID, + _attestation.subgraphDeploymentId, + indexer, + _fisherman + ) + ); + + // Only one dispute for a (indexer, subgraphDeploymentId) at a time + if (isDisputeCreated(disputeId)) { + revert DisputeManagerDisputeAlreadyCreated(disputeId); + } + + // Store dispute + disputes[disputeId] = Dispute( + indexer, + _fisherman, + _deposit, + 0, // no related dispute, + DisputeType.QueryDispute, + IDisputeManager.DisputeStatus.Pending, + block.timestamp + ); + + emit QueryDisputeCreated( + disputeId, + indexer, + _fisherman, + _deposit, + _attestation.subgraphDeploymentId, + _attestationData + ); + + return disputeId; + } + + /** + * @dev Create indexing dispute internal function. + * @param _fisherman The challenger creating the dispute + * @param _deposit Amount of tokens staked as deposit + * @param _allocationId Allocation disputed + */ + function _createIndexingDisputeWithAllocation( + address _fisherman, + uint256 _deposit, + address _allocationId + ) private returns (bytes32) { + // Create a disputeId + bytes32 disputeId = keccak256(abi.encodePacked(_allocationId)); + + // Only one dispute for an allocationId at a time + if (isDisputeCreated(disputeId)) { + revert DisputeManagerDisputeAlreadyCreated(disputeId); + } + + // Allocation must exist + Allocation.State memory alloc = subgraphService.getAllocation(_allocationId); + address indexer = alloc.indexer; + if (indexer == address(0)) { + revert DisputeManagerIndexerNotFound(_allocationId); + } + + // The indexer must be disputable + IHorizonStaking.Provision memory provision = GRAPH_STAKING.getProvision(indexer, address(subgraphService)); + if (provision.tokens == 0) { + revert DisputeManagerZeroTokens(); + } + + // Store dispute + disputes[disputeId] = Dispute( + alloc.indexer, + _fisherman, + _deposit, + 0, + DisputeType.IndexingDispute, + IDisputeManager.DisputeStatus.Pending, + block.timestamp + ); + + emit IndexingDisputeCreated(disputeId, alloc.indexer, _fisherman, _deposit, _allocationId); + + return disputeId; + } + + /** + * @dev Resolve the conflicting dispute if there is any for the one passed to this function. + * @param _dispute Dispute + * @return True if resolved + */ + function _drawDisputeInConflict(Dispute memory _dispute) private returns (bool) { + if (_isDisputeInConflict(_dispute)) { + bytes32 relatedDisputeId = _dispute.relatedDisputeId; + Dispute storage relatedDispute = disputes[relatedDisputeId]; + relatedDispute.status = IDisputeManager.DisputeStatus.Drawn; + return true; + } + return false; + } + + /** + * @dev Cancel the conflicting dispute if there is any for the one passed to this function. + * @param _dispute Dispute + * @return True if cancelled + */ + function _cancelDisputeInConflict(Dispute memory _dispute) private returns (bool) { + if (_isDisputeInConflict(_dispute)) { + bytes32 relatedDisputeId = _dispute.relatedDisputeId; + Dispute storage relatedDispute = disputes[relatedDisputeId]; + relatedDispute.status = IDisputeManager.DisputeStatus.Cancelled; + return true; + } + return false; + } + + /** + * @dev Pull deposit from submitter account. + * @param _deposit Amount of tokens to deposit + */ + function _pullSubmitterDeposit(uint256 _deposit) private { + // Ensure that fisherman has staked at least the minimum amount + if (_deposit < minimumDeposit) { + revert DisputeManagerInsufficientDeposit(_deposit, minimumDeposit); + } + + // Transfer tokens to deposit from fisherman to this contract + TokenUtils.pullTokens(GRAPH_TOKEN, msg.sender, _deposit); + } + + /** + * @dev Make the subgraph service contract slash the indexer and reward the challenger. + * Give the challenger a reward equal to the fishermanRewardPercentage of slashed amount + * @param _indexer Address of the indexer + * @param _slashAmount Amount of tokens to slash from the indexer + */ + function _slashIndexer(address _indexer, uint256 _slashAmount) private returns (uint256 rewardsAmount) { + // Get slashable amount for indexer + IHorizonStaking.Provision memory provision = GRAPH_STAKING.getProvision(_indexer, address(subgraphService)); + uint256 totalProvisionTokens = provision.tokens + provision.delegatedTokens; // slashable tokens + + // Get slash amount + uint256 maxSlashAmount = uint256(maxSlashingPercentage).mulPPM(totalProvisionTokens); + if (_slashAmount == 0) { + revert DisputeManagerInvalidSlashAmount(_slashAmount); + } + + if (_slashAmount > maxSlashAmount) { + revert DisputeManagerInvalidSlashAmount(_slashAmount); + } + + // Rewards amount can only be extracted from service poriver tokens so + // we grab the minimum between the slash amount and indexer's tokens + uint256 maxRewardableTokens = Math.min(_slashAmount, provision.tokens); + rewardsAmount = uint256(fishermanRewardPercentage).mulPPM(maxRewardableTokens); + + subgraphService.slash(_indexer, abi.encode(_slashAmount, rewardsAmount)); + return rewardsAmount; + } + + /** + * @dev Internal: Set the arbitrator address. + * @notice Update the arbitrator to `_arbitrator` + * @param _arbitrator The address of the arbitration contract or party + */ + function _setArbitrator(address _arbitrator) private { + if (_arbitrator == address(0)) { + revert DisputeManagerInvalidZeroAddress(); + } + arbitrator = _arbitrator; + emit ArbitratorSet(arbitrator); + } + + /** + * @dev Internal: Set the dispute period. + * @notice Update the dispute period to `_disputePeriod` in seconds + * @param _disputePeriod Dispute period in seconds + */ + function _setDisputePeriod(uint64 _disputePeriod) private { + if (_disputePeriod == 0) { + revert DisputeManagerDisputePeriodZero(); + } + disputePeriod = _disputePeriod; + emit DisputePeriodSet(disputePeriod); + } + + /** + * @dev Internal: Set the minimum deposit required to create a dispute. + * @notice Update the minimum deposit to `_minimumDeposit` Graph Tokens + * @param _minimumDeposit The minimum deposit in Graph Tokens + */ + function _setMinimumDeposit(uint256 _minimumDeposit) private { + if (_minimumDeposit == 0) { + revert DisputeManagerInvalidMinimumDeposit(_minimumDeposit); + } + minimumDeposit = _minimumDeposit; + emit MinimumDepositSet(minimumDeposit); + } + + /** + * @dev Internal: Set the percent reward that the fisherman gets when slashing occurs. + * @notice Update the reward percentage to `_percentage` + * @param _percentage Reward as a percentage of indexer stake + */ + function _setFishermanRewardPercentage(uint32 _percentage) private { + // Must be within 0% to 100% (inclusive) + if (!PPMMath.isValidPPM(_percentage)) { + revert DisputeManagerInvalidFishermanReward(_percentage); + } + fishermanRewardPercentage = _percentage; + emit FishermanRewardPercentageSet(fishermanRewardPercentage); + } + + /** + * @dev Internal: Set the maximum percentage that can be used for slashing indexers. + * @param _maxSlashingPercentage Max percentage slashing for disputes + */ + function _setMaxSlashingPercentage(uint32 _maxSlashingPercentage) private { + // Must be within 0% to 100% (inclusive) + if (!PPMMath.isValidPPM(_maxSlashingPercentage)) { + revert DisputeManagerInvalidMaxSlashingPercentage(_maxSlashingPercentage); + } + maxSlashingPercentage = _maxSlashingPercentage; + emit MaxSlashingPercentageSet(maxSlashingPercentage); + } + + /** + * @dev Internal: Set the subgraph service address. + * @notice Update the subgraph service to `_subgraphService` + * @param _subgraphService The address of the subgraph service contract + */ + function _setSubgraphService(address _subgraphService) private { + if (_subgraphService == address(0)) { + revert DisputeManagerInvalidZeroAddress(); + } + subgraphService = ISubgraphService(_subgraphService); + emit SubgraphServiceSet(_subgraphService); + } + + /** + * @dev Returns whether the dispute is for a conflicting attestation or not. + * @param _dispute Dispute + * @return True conflicting attestation dispute + */ + function _isDisputeInConflict(Dispute memory _dispute) private view returns (bool) { + bytes32 relatedId = _dispute.relatedDisputeId; + // this is so the check returns false when rejecting the related dispute. + return relatedId != 0 && disputes[relatedId].status == IDisputeManager.DisputeStatus.Pending; + } +} diff --git a/packages/subgraph-service/contracts/DisputeManagerStorage.sol b/packages/subgraph-service/contracts/DisputeManagerStorage.sol new file mode 100644 index 000000000..350d96566 --- /dev/null +++ b/packages/subgraph-service/contracts/DisputeManagerStorage.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.24; + +import { IDisputeManager } from "./interfaces/IDisputeManager.sol"; +import { ISubgraphService } from "./interfaces/ISubgraphService.sol"; + +abstract contract DisputeManagerV1Storage { + // -- State -- + + ISubgraphService public subgraphService; + + // The arbitrator is solely in control of arbitrating disputes + address public arbitrator; + + // dispute period in seconds + uint64 public disputePeriod; + + // Minimum deposit required to create a Dispute + uint256 public minimumDeposit; + + // Percentage of indexer slashed funds to assign as a reward to fisherman in successful dispute + // Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) + uint32 public fishermanRewardPercentage; + + // Maximum percentage of indexer stake that can be slashed on a dispute + // Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) + uint32 public maxSlashingPercentage; + + // Disputes created : disputeID => Dispute + // disputeID - check creation functions to see how disputeID is built + mapping(bytes32 disputeID => IDisputeManager.Dispute dispute) public disputes; +} diff --git a/packages/subgraph-service/contracts/SubgraphService.sol b/packages/subgraph-service/contracts/SubgraphService.sol new file mode 100644 index 000000000..9489373ab --- /dev/null +++ b/packages/subgraph-service/contracts/SubgraphService.sol @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IGraphPayments } from "./interfaces/IGraphPayments.sol"; +import { ISubgraphService } from "./interfaces/ISubgraphService.sol"; +import { ITAPVerifier } from "./interfaces/ITAPVerifier.sol"; + +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { DataService } from "./data-service/DataService.sol"; +import { DataServicePausable } from "./data-service/extensions/DataServicePausable.sol"; +import { DataServiceRescuable } from "./data-service/extensions/DataServiceRescuable.sol"; +import { DataServiceFees } from "./data-service/extensions/DataServiceFees.sol"; +import { Directory } from "./utilities/Directory.sol"; +import { AllocationManager } from "./utilities/AllocationManager.sol"; +import { SubgraphServiceV1Storage } from "./SubgraphServiceStorage.sol"; + +import { PPMMath } from "./data-service/libraries/PPMMath.sol"; +import { Allocation } from "./libraries/Allocation.sol"; +import { LegacyAllocation } from "./libraries/LegacyAllocation.sol"; + +// TODO: contract needs to be upgradeable +contract SubgraphService is + Ownable, + DataService, + DataServicePausable, + DataServiceRescuable, + DataServiceFees, + Directory, + AllocationManager, + SubgraphServiceV1Storage, + ISubgraphService +{ + using PPMMath for uint256; + using Allocation for mapping(address => Allocation.State); + + event QueryFeesRedeemed( + address serviceProvider, + address payer, + uint256 tokensCollected, + uint256 tokensCurators, + uint256 tokensSubgraphService + ); + + error SubgraphServiceEmptyUrl(); + error SubgraphServiceInconsistentRAVTokens(uint256 tokens, uint256 tokensCollected); + error SubgraphServiceInvalidPaymentType(IGraphPayments.PaymentTypes feeType); + error SubgraphServiceIndexerAlreadyRegistered(); + error SubgraphServiceIndexerNotRegistered(address indexer); + error SubgraphServiceInconsistentCollection(uint256 tokensExpected, uint256 tokensCollected); + + modifier onlyRegisteredIndexer(address indexer) { + if (indexers[indexer].registeredAt == 0) { + revert SubgraphServiceIndexerNotRegistered(indexer); + } + _; + } + + constructor( + address graphController, + address disputeManager, + address tapVerifier, + address curation, + uint256 minimumProvisionTokens + ) + Ownable(msg.sender) + DataService(graphController) + Directory(address(this), tapVerifier, disputeManager, curation) + AllocationManager("SubgraphService", "1.0") + { + _setProvisionTokensRange(minimumProvisionTokens, type(uint256).max); + } + + function register( + address indexer, + bytes calldata data + ) external override onlyProvisionAuthorized(indexer) whenNotPaused { + (string memory url, string memory geohash) = abi.decode(data, (string, string)); + + // Must provide a URL + if (bytes(url).length == 0) { + revert SubgraphServiceEmptyUrl(); + } + + // Only allow registering once + if (indexers[indexer].registeredAt != 0) { + revert SubgraphServiceIndexerAlreadyRegistered(); + } + + // Register the indexer + indexers[indexer] = Indexer({ registeredAt: block.timestamp, url: url, geoHash: geohash }); + + // Ensure the service provider created a valid provision for the data service + // and accept it in the staking contract + _acceptProvision(indexer); + + emit ServiceProviderRegistered(indexer); + } + + function acceptProvision( + address indexer, + bytes calldata + ) external override onlyProvisionAuthorized(indexer) onlyRegisteredIndexer(indexer) whenNotPaused { + _acceptProvision(indexer); + } + + function startService( + address indexer, + bytes calldata data + ) external override onlyProvisionAuthorized(indexer) onlyRegisteredIndexer(indexer) whenNotPaused { + (bytes32 subgraphDeploymentId, uint256 tokens, address allocationId, bytes memory allocationProof) = abi.decode( + data, + (bytes32, uint256, address, bytes) + ); + _allocate(indexer, allocationId, subgraphDeploymentId, tokens, allocationProof); + emit ServiceStarted(indexer); + } + + function collectServicePayment( + address indexer, + bytes calldata data + ) external override onlyProvisionAuthorized(indexer) onlyRegisteredIndexer(indexer) whenNotPaused { + (address allocationId, bytes32 poi) = abi.decode(data, (address, bytes32)); + uint256 rewards = _collectPOIRewards(allocationId, poi); + emit ServicePaymentCollected(indexer, rewards); + } + + function stopService( + address indexer, + bytes calldata data + ) external override onlyProvisionAuthorized(indexer) onlyRegisteredIndexer(indexer) whenNotPaused { + address allocationId = abi.decode(data, (address)); + _closeAllocation(allocationId); + emit ServiceStopped(indexer); + } + + function resizeAllocation( + address indexer, + address allocationId, + uint256 tokens + ) external onlyProvisionAuthorized(indexer) onlyRegisteredIndexer(indexer) whenNotPaused { + _resizeAllocation(allocationId, tokens); + } + + // TODO: Does this design allow custom payment types?! + function redeem( + address indexer, + IGraphPayments.PaymentTypes feeType, + bytes calldata data + ) external override onlyRegisteredIndexer(indexer) whenNotPaused { + uint256 feesCollected = 0; + + if (feeType == IGraphPayments.PaymentTypes.QueryFee) { + feesCollected = _redeemQueryFees(abi.decode(data, (ITAPVerifier.SignedRAV))); + } else { + revert SubgraphServiceInvalidPaymentType(feeType); + } + + emit ServiceFeesRedeemed(indexer, feeType, feesCollected); + } + + function slash(address indexer, bytes calldata data) external override onlyDisputeManager whenNotPaused { + (uint256 tokens, uint256 reward) = abi.decode(data, (uint256, uint256)); + GRAPH_STAKING.slash(indexer, tokens, reward, address(DISPUTE_MANAGER)); + emit ServiceProviderSlashed(indexer, tokens); + } + + function migrateLegacyAllocation( + address indexer, + address allocationId, + bytes32 subgraphDeploymentID + ) external onlyOwner { + _migrateLegacyAllocation(indexer, allocationId, subgraphDeploymentID); + } + + function setPauseGuardian(address pauseGuardian, bool allowed) external onlyOwner { + _setPauseGuardian(pauseGuardian, allowed); + } + + function getAllocation(address allocationId) external view override returns (Allocation.State memory) { + return allocations[allocationId]; + } + + function getLegacyAllocation(address allocationId) external view returns (LegacyAllocation.State memory) { + return legacyAllocations[allocationId]; + } + + function encodeAllocationProof(address _indexer, address _allocationId) external view returns (bytes32) { + return _encodeAllocationProof(_indexer, _allocationId); + } + + // -- Data service parameter getters -- + function _getThawingPeriodRange() internal view override returns (uint64 min, uint64 max) { + uint64 disputePeriod = DISPUTE_MANAGER.getDisputePeriod(); + return (disputePeriod, type(uint64).max); + } + + function _getVerifierCutRange() internal view override returns (uint32 min, uint32 max) { + uint32 verifierCut = DISPUTE_MANAGER.getVerifierCut(); + return (verifierCut, type(uint32).max); + } + + function _redeemQueryFees(ITAPVerifier.SignedRAV memory _signedRAV) private returns (uint256 feesCollected) { + address indexer = _signedRAV.rav.serviceProvider; + address allocationId = abi.decode(_signedRAV.rav.metadata, (address)); + + // release expired stake claims + _releaseStake(IGraphPayments.PaymentTypes.QueryFee, indexer, 0); + + // validate RAV and calculate tokens to collect + address payer = TAP_VERIFIER.verify(_signedRAV); + uint256 tokens = _signedRAV.rav.valueAggregate; + uint256 tokensAlreadyCollected = tokensCollected[indexer][payer]; + if (tokens <= tokensAlreadyCollected) { + revert SubgraphServiceInconsistentRAVTokens(tokens, tokensAlreadyCollected); + } + uint256 tokensToCollect = tokens - tokensAlreadyCollected; + uint256 tokensCurators = 0; + uint256 tokensSubgraphService = 0; + + if (tokensToCollect > 0) { + // lock stake as economic security for fees + // block scope to avoid 'stack too deep' error + { + uint256 tokensToLock = tokensToCollect * stakeToFeesRatio; + uint256 unlockTimestamp = block.timestamp + DISPUTE_MANAGER.getDisputePeriod(); + _lockStake(IGraphPayments.PaymentTypes.QueryFee, indexer, tokensToLock, unlockTimestamp); + } + + // get subgraph deployment id - reverts if allocation is not found + bytes32 subgraphDeploymentId = allocations.get(allocationId).subgraphDeploymentId; + + // calculate service and curator cuts + // TODO: note we don't let curation cut round down to zero + PaymentFee memory feePercentages = _getQueryFeesPaymentFees(subgraphDeploymentId); + tokensSubgraphService = tokensToCollect.mulPPM(feePercentages.servicePercentage); + tokensCurators = tokensToCollect.mulPPMRoundUp(feePercentages.curationPercentage); + uint256 totalCut = tokensSubgraphService + tokensCurators; + + // collect fees + uint256 balanceBefore = GRAPH_TOKEN.balanceOf(address(this)); + GRAPH_PAYMENTS.collect(payer, indexer, tokensToCollect, IGraphPayments.PaymentTypes.QueryFee, totalCut); + uint256 balanceAfter = GRAPH_TOKEN.balanceOf(address(this)); + if (balanceBefore + totalCut != balanceAfter) { + revert SubgraphServiceInconsistentCollection(balanceBefore + totalCut, balanceAfter); + } + tokensCollected[indexer][payer] = tokens; + + // distribute curation cut to curators + if (tokensCurators > 0) { + // we are about to change subgraph signal so we take rewards snapshot + GRAPH_REWARDS_MANAGER.onSubgraphSignalUpdate(subgraphDeploymentId); + + // Send GRT and bookkeep by calling collect() + GRAPH_TOKEN.transfer(address(CURATION), tokensCurators); + CURATION.collect(subgraphDeploymentId, tokensCurators); + } + } + + emit QueryFeesRedeemed(indexer, payer, tokensToCollect, tokensCurators, tokensSubgraphService); + return tokensToCollect; + } + + function _getQueryFeesPaymentFees(bytes32 _subgraphDeploymentId) private view returns (PaymentFee memory) { + PaymentFee memory feePercentages = paymentFees[IGraphPayments.PaymentTypes.QueryFee]; + + // Only pay curation fees if the subgraph is curated + if (!CURATION.isCurated(_subgraphDeploymentId)) { + feePercentages.curationPercentage = 0; + } + + return feePercentages; + } +} diff --git a/packages/subgraph-service/contracts/SubgraphServiceStorage.sol b/packages/subgraph-service/contracts/SubgraphServiceStorage.sol new file mode 100644 index 000000000..27ebc13ff --- /dev/null +++ b/packages/subgraph-service/contracts/SubgraphServiceStorage.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { ISubgraphService } from "./interfaces/ISubgraphService.sol"; +import { IGraphPayments } from "./interfaces/IGraphPayments.sol"; + +abstract contract SubgraphServiceV1Storage { + /// @notice Service providers registered in the data service + mapping(address indexer => ISubgraphService.Indexer details) public indexers; + + // -- Fees -- + // multiplier for how many tokens back collected query fees + uint256 public stakeToFeesRatio; + + /// @notice The fees cut taken by the subgraph service + mapping(IGraphPayments.PaymentTypes paymentType => ISubgraphService.PaymentFee paymentFees) public paymentFees; + + mapping(address indexer => mapping(address payer => uint256 tokens)) public tokensCollected; +} diff --git a/packages/subgraph-service/contracts/TAPVerifier.sol b/packages/subgraph-service/contracts/TAPVerifier.sol new file mode 100644 index 000000000..e7b3d5a7f --- /dev/null +++ b/packages/subgraph-service/contracts/TAPVerifier.sol @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { ITAPVerifier } from "./interfaces/ITAPVerifier.sol"; + +import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; + +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; + +/** + * @title TAPVerifier + * @dev A contract for verifying receipt aggregation vouchers. + */ +contract TAPVerifier is EIP712, ITAPVerifier { + bytes32 private constant EIP712_RAV_TYPEHASH = + keccak256( + "ReceiptAggregateVoucher(address dataService, address serviceProvider,uint64 timestampNs,uint128 valueAggregate,bytes metadata)" + ); + + // The duration (in seconds) in which a signer is thawing before they can be revoked + uint256 public immutable REVOKE_SIGNER_THAWING_PERIOD; + + // Map of signer to authorized signer information + mapping(address signer => SenderAuthorization authorizedSigner) public authorizedSigners; + + /** + * @dev Emitted when a signer is authorized to sign RAVs for a sender. + */ + event AuthorizeSigner(address indexed signer, address indexed sender); + /** + * @dev Emitted when a thaw request is made for authorized signer + */ + event ThawSigner(address indexed sender, address indexed authorizedSigner, uint256 thawEndTimestamp); + + /** + * @dev Emitted when the thawing of a signer is cancelled + */ + event CancelThawSigner(address indexed sender, address indexed authorizedSigner, uint256 thawEndTimestamp); + + /** + * @dev Emitted when a authorized signer has been revoked + */ + event RevokeAuthorizedSigner(address indexed sender, address indexed authorizedSigner); + + error TAPVerifierInvalidCaller(address sender, address expected); + error TAPVerifierInvalidSignerProof(); + error TAPVerifierAlreadyAuthorized(address signer, address authorizingSender); + error TAPVerifierNotAuthorized(address signer, address sender); + error TAPVerifierNotThawing(); + error TAPVerifierStillThawing(uint256 currentTimestamp, uint256 thawEndTimestamp); + + /** + * @dev Constructs a new instance of the TAPVerifier contract. + */ + constructor(string memory eip712Name, string memory eip712Version) EIP712(eip712Name, eip712Version) {} + + /** + * @dev Authorizes a signer to sign RAVs for the sender. + * @param signer Address of the authorized signer. + * @param proof The proof provided by the signer to authorize the sender, consisting of packed (chainID, proof deadline, sender address). + * @dev The proof deadline is the timestamp at which the proof expires. The proof is susceptible to replay attacks until the deadline is reached. + * @notice REVERT with error: + * - SignerAlreadyAuthorized: Signer is currently authorized for a sender + * - InvalidSignerProof: The provided signer proof is invalid + */ + function authorizeSigner(address signer, uint256 proofDeadline, bytes calldata proof) external { + if (authorizedSigners[signer].sender != address(0)) { + revert TAPVerifierAlreadyAuthorized(signer, authorizedSigners[signer].sender); + } + + _verifyAuthorizedSignerProof(proof, proofDeadline, signer); + + authorizedSigners[signer].sender = msg.sender; + authorizedSigners[signer].thawEndTimestamp = 0; + emit AuthorizeSigner(signer, msg.sender); + } + + /** + * @dev Starts thawing a signer to be removed from the authorized signers list. + * @param signer Address of the signer to remove. + * @notice WARNING: Thawing a signer alerts receivers that signatures from that signer will soon be deemed invalid. + * Receivers without existing signed receipts or RAVs from this signer should treat them as unauthorized. + * Those with existing signed documents from this signer should work towards settling their engagements. + * Once a signer is thawed, they should be viewed as revoked regardless of their revocation status. + * @notice REVERT with error: + * - SignerNotAuthorizedBySender: The provided signer is either not authorized or + * authorized by a different sender + */ + function thawSigner(address signer) external { + SenderAuthorization storage authorization = authorizedSigners[signer]; + + if (authorization.sender != msg.sender) { + revert TAPVerifierNotAuthorized(signer, authorizedSigners[signer].sender); + } + + authorization.thawEndTimestamp = block.timestamp + REVOKE_SIGNER_THAWING_PERIOD; + emit ThawSigner(authorization.sender, signer, authorization.thawEndTimestamp); + } + + /** + * @dev Stops thawing a signer. + * @param signer Address of the signer to stop thawing. + * @notice REVERT with error: + * - SignerNotAuthorizedBySender: The provided signer is either not authorized or + * authorized by a different sender + */ + function cancelThawSigner(address signer) external { + SenderAuthorization storage authorization = authorizedSigners[signer]; + + if (authorization.sender != msg.sender) { + revert TAPVerifierNotAuthorized(signer, authorizedSigners[signer].sender); + } + + authorization.thawEndTimestamp = 0; + emit CancelThawSigner(authorization.sender, signer, authorization.thawEndTimestamp); + } + + /** + * @dev Revokes a signer from the authorized signers list if thawed. + * @param signer Address of the signer to remove. + * @notice REVERT with error: + * - SignerNotAuthorizedBySender: The provided signer is either not authorized or + * authorized by a different sender + * - SignerNotThawing: No thaw was initiated for the provided signer + * - SignerStillThawing: ThawEndTimestamp has not been reached + * for provided signer + */ + function revokeAuthorizedSigner(address signer) external { + SenderAuthorization storage authorization = authorizedSigners[signer]; + + if (authorization.sender != msg.sender) { + revert TAPVerifierNotAuthorized(signer, authorizedSigners[signer].sender); + } + + if (authorization.thawEndTimestamp == 0) { + revert TAPVerifierNotThawing(); + } + + if (authorization.thawEndTimestamp > block.timestamp) { + revert TAPVerifierStillThawing({ + currentTimestamp: block.timestamp, + thawEndTimestamp: authorization.thawEndTimestamp + }); + } + + delete authorizedSigners[signer]; + emit RevokeAuthorizedSigner(authorization.sender, signer); + } + + /** + * @notice Verify validity of a SignedRAV + * @dev Caller must be the data service the RAV was issued to. + * @param signedRAV The SignedRAV containing the RAV and its signature. + * @return The address of the signer. + * @notice REVERT: This function may revert if ECDSA.recover fails, check ECDSA library for details. + */ + function verify(SignedRAV calldata signedRAV) external view returns (address) { + if (signedRAV.rav.dataService != msg.sender) { + revert TAPVerifierInvalidCaller(msg.sender, signedRAV.rav.dataService); + } + return recover(signedRAV); + } + + /** + * @dev Recovers the signer address of a signed ReceiptAggregateVoucher (RAV). + * @param signedRAV The SignedRAV containing the RAV and its signature. + * @return The address of the signer. + * @notice REVERT: This function may revert if ECDSA.recover fails, check ECDSA library for details. + */ + function recover(SignedRAV calldata signedRAV) public view returns (address) { + bytes32 messageHash = encodeRAV(signedRAV.rav); + return ECDSA.recover(messageHash, signedRAV.signature); + } + + /** + * @dev Computes the hash of a ReceiptAggregateVoucher (RAV). + * @param rav The RAV for which to compute the hash. + * @return The hash of the RAV. + */ + function encodeRAV(ReceiptAggregateVoucher calldata rav) public view returns (bytes32) { + return + _hashTypedDataV4( + keccak256( + abi.encode( + EIP712_RAV_TYPEHASH, + rav.dataService, + rav.serviceProvider, + rav.timestampNs, + rav.valueAggregate + ) + ) + ); + } + + /** + * @dev Verifies a proof that authorizes the sender to authorize the signer. + * @param _proof The proof provided by the signer to authorize the sender. + * @param _signer The address of the signer being authorized. + * @notice REVERT with error: + * - InvalidSignerProof: If the given proof is not valid + */ + function _verifyAuthorizedSignerProof(bytes calldata _proof, uint256 _proofDeadline, address _signer) private view { + // Verify that the proof deadline has not passed + if (block.timestamp > _proofDeadline) { + revert TAPVerifierInvalidSignerProof(); + } + + // Generate the hash of the sender's address + bytes32 messageHash = keccak256(abi.encodePacked(block.chainid, _proofDeadline, msg.sender)); + + // Generate the digest to be signed by the signer + bytes32 digest = MessageHashUtils.toEthSignedMessageHash(messageHash); + + // Verify that the recovered signer matches the expected signer + if (ECDSA.recover(digest, _proof) != _signer) { + revert TAPVerifierInvalidSignerProof(); + } + } +} diff --git a/packages/subgraph-service/contracts/data-service/DataService.sol b/packages/subgraph-service/contracts/data-service/DataService.sol new file mode 100644 index 000000000..52f1e25b5 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/DataService.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IDataService } from "./IDataService.sol"; + +import { GraphDirectory } from "./GraphDirectory.sol"; +import { DataServiceV1Storage } from "./DataServiceStorage.sol"; +import { ProvisionManager } from "./utilities/ProvisionManager.sol"; + +/** + * @title Implementation of the {IDataService} interface. + * @dev This implementation provides base functionality for a data service: + * - GraphDirectory, allows the data service to interact with Graph Horizon contracts + * - ProvisionManager, provides functionality to manage provisions + * + * The derived contract should add functionality that implements the interfaces described in {IDataService}. + */ +abstract contract DataService is GraphDirectory, ProvisionManager, DataServiceV1Storage, IDataService { + /** + * @dev Addresses in GraphDirectory are immutables, they can only be set in this constructor. + * @param controller The address of the Graph Horizon controller contract. + */ + constructor(address controller) GraphDirectory(controller) {} + + /** + * @notice Verifies and accepts the provision of a service provider in the {Graph Horizon staking + * contract}. + * @dev This internal function is a wrapper around {ProvisionManager-checkAndAcceptProvision} + * that ensures the event {ProvisionAccepted} is emitted when called from different contexts. + * + * Emits a {ProvisionAccepted} event. + * + * @param _serviceProvider The address of the service provider. + */ + function _acceptProvision(address _serviceProvider) internal { + _checkAndAcceptProvision(_serviceProvider); + emit ProvisionAccepted(_serviceProvider); + } +} diff --git a/packages/subgraph-service/contracts/data-service/DataServiceStorage.sol b/packages/subgraph-service/contracts/data-service/DataServiceStorage.sol new file mode 100644 index 000000000..3cb7e0b86 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/DataServiceStorage.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +abstract contract DataServiceV1Storage { + /// @dev Gap to allow adding variables in future upgrades + uint256[50] private __gap; +} diff --git a/packages/subgraph-service/contracts/data-service/GraphDirectory.sol b/packages/subgraph-service/contracts/data-service/GraphDirectory.sol new file mode 100644 index 000000000..f35a7a663 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/GraphDirectory.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity 0.8.24; + +import { IController } from "@graphprotocol/contracts/contracts/governance/IController.sol"; +import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; +import { IGraphToken } from "@graphprotocol/contracts/contracts/token/IGraphToken.sol"; +// import { IGraphTokenGateway } from "@graphprotocol/contracts/contracts/gateway/IGraphTokenGateway.sol"; +import { IEpochManager } from "@graphprotocol/contracts/contracts/epochs/IEpochManager.sol"; +import { IRewardsManager } from "@graphprotocol/contracts/contracts/rewards/IRewardsManager.sol"; +import { IGraphEscrow } from "../interfaces/IGraphEscrow.sol"; +import { IGraphPayments } from "../interfaces/IGraphPayments.sol"; + +abstract contract GraphDirectory { + IController public immutable GRAPH_CONTROLLER; + IHorizonStaking public immutable GRAPH_STAKING; + IEpochManager public immutable GRAPH_EPOCH_MANAGER; + IGraphToken public immutable GRAPH_TOKEN; + // IGraphTokenGateway public immutable graphTokenGateway; + IGraphEscrow public immutable GRAPH_ESCROW; + IGraphPayments public immutable GRAPH_PAYMENTS; + IRewardsManager public immutable GRAPH_REWARDS_MANAGER; + + event GraphDirectoryInitialized( + IController graphController, + IHorizonStaking graphStaking, + IEpochManager graphEpochManager, + IGraphToken graphToken, + // address graphTokenGateway, + IGraphEscrow graphEscrow, + IGraphPayments graphPayments, + IRewardsManager graphRewardsManager + ); + + constructor(address controller) { + GRAPH_CONTROLLER = IController(controller); + GRAPH_STAKING = IHorizonStaking(GRAPH_CONTROLLER.getContractProxy(keccak256("Staking"))); + GRAPH_EPOCH_MANAGER = IEpochManager(GRAPH_CONTROLLER.getContractProxy(keccak256("EpochManager"))); + GRAPH_TOKEN = IGraphToken(GRAPH_CONTROLLER.getContractProxy(keccak256("GraphToken"))); + // graphTokenGateway = graphController.getContractProxy(keccak256("GraphTokenGateway")); + GRAPH_ESCROW = IGraphEscrow(GRAPH_CONTROLLER.getContractProxy(keccak256("GraphEscrow"))); + GRAPH_PAYMENTS = IGraphPayments(GRAPH_CONTROLLER.getContractProxy(keccak256("GraphPayments"))); + GRAPH_REWARDS_MANAGER = IRewardsManager(GRAPH_CONTROLLER.getContractProxy(keccak256("RewardsManager"))); + emit GraphDirectoryInitialized( + GRAPH_CONTROLLER, + GRAPH_STAKING, + GRAPH_EPOCH_MANAGER, + GRAPH_TOKEN, + // graphTokenGateway, + GRAPH_ESCROW, + GRAPH_PAYMENTS, + GRAPH_REWARDS_MANAGER + ); + } +} diff --git a/packages/subgraph-service/contracts/data-service/IDataService.sol b/packages/subgraph-service/contracts/data-service/IDataService.sol new file mode 100644 index 000000000..0e598b2cb --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/IDataService.sol @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IGraphPayments } from "../interfaces/IGraphPayments.sol"; + +/** + * @title Interface of the base {DataService} contract as defined by the Graph Horizon specification. + * @dev This interface provides a guardrail for data service implementations that utilize Graph Horizon. + * It's expected that implementations follow the specification however much of it is intentionally loose + * to allow for greater flexibility when designing a data service. For specifics always check the data + * service implementation. + + * In general, this is a great starting point for data services that want to use Graph Horizon + * to provide economic security for a service being provided. It assumes two main forms of retribution for + * service providers: + * - service payment, to compensate ongoing work required to serve customers requests + * - service fees, earnt by serving customer requests, ideally leveraging {GraphPayments} to collect fees from the payer + * + * TIP: TODO: link to data service framework documentation + */ +interface IDataService { + /** + * @notice Emitted when a service provider is registered with the data service. + * @param serviceProvider The address of the service provider. + */ + event ServiceProviderRegistered(address indexed serviceProvider); + + /** + * @notice Emitted when a service provider accepts a provision in {Graph Horizon staking contract}. + * @param serviceProvider The address of the service provider. + */ + event ProvisionAccepted(address indexed serviceProvider); + + /** + * @notice Emitted when a service provider starts providing the service. + * @param serviceProvider The address of the service provider. + */ + event ServiceStarted(address indexed serviceProvider); + + /** + * @notice Emitted when a service provider stops providing the service. + * @param serviceProvider The address of the service provider. + */ + event ServiceStopped(address indexed serviceProvider); + + /** + * @notice Emitted when a service provider collects payment for the service being provided. + * @param serviceProvider The address of the service provider. + * @param tokens The amount of tokens collected. + */ + event ServicePaymentCollected(address indexed serviceProvider, uint256 tokens); + + /** + * @notice Emitted when a service provider redeems fees. + * @param serviceProvider The address of the service provider. + * @param feeType The type of fee to redeem as defined in {GraphPayments}. + * @param tokens The amount of tokens redeemed. + */ + event ServiceFeesRedeemed( + address indexed serviceProvider, + IGraphPayments.PaymentTypes indexed feeType, + uint256 tokens + ); + + /** + * @notice Emitted when a service provider is slashed. + * @param serviceProvider The address of the service provider. + * @param tokens The amount of tokens slashed. + */ + event ServiceProviderSlashed(address indexed serviceProvider, uint256 tokens); + + /** + * @notice Thrown to signal that a feature is not implemented by a data service. + */ + error DataServiceFeatureNotImplemented(); + + /** + * @notice Registers a service provider with the data service. The service provider can now + * start providing the service. + * @dev Before registering, the service provider must have created a provision in the + * Graph Horizon staking contract with parameters that are compatible with the data service. + * + * Verifies the provision parameters and marks it as accepted it in the Graph Horizon + * staking contract using {_acceptProvision}. + * + * Emits a {ServiceProviderRegistered} event. + * + * NOTE: Failing to accept the provision will result in the service provider operating + * on an unverified provision. Depending on of the data service this can be a security + * risk as the protocol won't be able to guarantee economic security for the consumer. + * @param serviceProvider The address of the service provider. + * @param data Custom data, usage defined by the data service. + */ + function register(address serviceProvider, bytes calldata data) external; + + /** + * @notice Accepts the provision of a service provider in the {Graph Horizon staking + * contract}. + * @dev Provides a way for the data service to revalidate and reaccept a provision that + * had a parameter change. Should call {_acceptProvision}. + * + * Emits a {ProvisionAccepted} event. + * + * @param serviceProvider The address of the service provider. + * @param data Custom data, usage defined by the data service. + */ + function acceptProvision(address serviceProvider, bytes calldata data) external; + + /** + * @notice Service provider starts providing the service. + * @dev Emits a {ServiceStarted} event. + * @param serviceProvider The address of the service provider. + * @param data Custom data, usage defined by the data service. + */ + function startService(address serviceProvider, bytes calldata data) external; + + /** + * @notice Service provider collects payment for the service being provided. + * @dev This is payment owed to a service provided for ongoing work required to fullfil + * customer requests. How the funds for the payment are procured is up to the data service. + * + * Emits a {ServicePaymentCollected} event. + * + * NOTE: Data services that are vetted by the Graph Council might qualify for a portion of + * the protocol issuance to cover these payments. In this case, the funds are taken by + * interacting with the rewards manager contract. + * @param serviceProvider The address of the service provider. + * @param data Custom data, usage defined by the data service. + */ + function collectServicePayment(address serviceProvider, bytes calldata data) external; + + /** + * @notice Service provider stops providing the service. + * @dev Emits a {ServiceStopped} event. + * @param serviceProvider The address of the service provider. + * @param data Custom data, usage defined by the data service. + */ + function stopService(address serviceProvider, bytes calldata data) external; + + /** + * @notice Redeeems fees earnt by the service provider. + * @dev The implementation of this function is expected to interact with {GraphPayments} + * to collect fees from the service payer, which is done via {IGraphPayments-collect}. + * @param serviceProvider The address of the service provider. + * + * Emits a {ServicePaymentRedeemed} event. + * + * @param feeType The type of fee to redeem as defined in {GraphPayments}. + * @param data Custom data, usage defined by the data service. + */ + function redeem(address serviceProvider, IGraphPayments.PaymentTypes feeType, bytes calldata data) external; + + /** + * @notice Slash a service provider for misbehaviour. + * @dev To slash the service provider's provision the function should call + * {Staking-slash}. + * + * Emits a {ServiceProviderSlashed} event. + * + * @param serviceProvider The address of the service provider. + * @param data Custom data, usage defined by the data service. + */ + function slash(address serviceProvider, bytes calldata data) external; +} diff --git a/packages/subgraph-service/contracts/data-service/extensions/DataServiceFees.sol b/packages/subgraph-service/contracts/data-service/extensions/DataServiceFees.sol new file mode 100644 index 000000000..583f01efa --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/extensions/DataServiceFees.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IDataServiceFees } from "./IDataServiceFees.sol"; +import { IGraphPayments } from "../../interfaces/IGraphPayments.sol"; + +import { DataService } from "../DataService.sol"; +import { DataServiceFeesV1Storage } from "./DataServiceFeesStorage.sol"; + +import { ProvisionTracker } from "../libraries/ProvisionTracker.sol"; + +abstract contract DataServiceFees is DataService, DataServiceFeesV1Storage, IDataServiceFees { + using ProvisionTracker for mapping(address => uint256); + + event StakeClaimLocked( + address indexed serviceProvider, + bytes32 indexed claimId, + uint256 tokens, + uint256 unlockTimestamp + ); + event StakeClaimReleased( + address indexed serviceProvider, + bytes32 indexed claimId, + uint256 tokens, + uint256 releaseAt + ); + + error DataServiceFeesClaimNotFound(bytes32 claimId); + + function releaseStake(IGraphPayments.PaymentTypes feeType, uint256 n) external virtual { + _releaseStake(feeType, msg.sender, n); + } + + /// @notice Release expired stake claims for a service provider + /// @param _n The number of stake claims to release, or 0 to release all + function _releaseStake(IGraphPayments.PaymentTypes _feeType, address _serviceProvider, uint256 _n) internal { + bool releaseAll = _n == 0; + + // check the stake claims list + // TODO: evaluate replacing with OZ DoubleEndedQueue + bytes32 head = claimsLists[_feeType][_serviceProvider].head; + while (head != bytes32(0) && (releaseAll || _n > 0)) { + StakeClaim memory claim = _getStakeClaim(head); + + if (block.timestamp >= claim.releaseAt) { + // Release stake + feesProvisionTracker[_feeType].release(_serviceProvider, claim.tokens); + + // Update list and refresh pointer + StakeClaimsList storage claimsList = claimsLists[_feeType][_serviceProvider]; + claimsList.head = claim.nextClaim; + delete claims[head]; + head = claimsList.head; + if (!releaseAll) _n--; + + emit StakeClaimReleased(_serviceProvider, claimsList.head, claim.tokens, claim.releaseAt); + } else { + break; + } + } + } + + function _lockStake( + IGraphPayments.PaymentTypes _feeType, + address _serviceProvider, + uint256 _tokens, + uint256 _unlockTimestamp + ) internal { + feesProvisionTracker[_feeType].lock(GRAPH_STAKING, _serviceProvider, _tokens); + + StakeClaimsList storage claimsList = claimsLists[_feeType][_serviceProvider]; + bytes32 claimId = _buildStakeClaimId(_serviceProvider, claimsList.nonce); + claims[claimId] = StakeClaim({ + serviceProvider: _serviceProvider, + tokens: _tokens, + createdAt: block.timestamp, + releaseAt: _unlockTimestamp, + nextClaim: bytes32(0) + }); + + claims[claimsList.tail].nextClaim = claimId; + claimsList.tail = claimId; + claimsList.nonce += 1; + + emit StakeClaimLocked(_serviceProvider, claimId, _tokens, _unlockTimestamp); + } + + function _getStakeClaim(bytes32 _claimId) private view returns (StakeClaim memory) { + StakeClaim memory claim = claims[_claimId]; + if (claim.createdAt == 0) { + revert DataServiceFeesClaimNotFound(_claimId); + } + return claim; + } + + function _buildStakeClaimId(address _serviceProvider, uint256 _nonce) private view returns (bytes32) { + return keccak256(abi.encodePacked(address(this), _serviceProvider, _nonce)); + } +} diff --git a/packages/subgraph-service/contracts/data-service/extensions/DataServiceFeesStorage.sol b/packages/subgraph-service/contracts/data-service/extensions/DataServiceFeesStorage.sol new file mode 100644 index 000000000..4296a952a --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/extensions/DataServiceFeesStorage.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IDataServiceFees } from "./IDataServiceFees.sol"; +import { IGraphPayments } from "../../interfaces/IGraphPayments.sol"; + +abstract contract DataServiceFeesV1Storage { + /// @notice List of all locked stake claims to be released to service providers + mapping(bytes32 claimId => IDataServiceFees.StakeClaim claim) public claims; + + mapping(IGraphPayments.PaymentTypes feeType => mapping(address serviceProvider => uint256 tokens)) + public feesProvisionTracker; + + /// @notice Service providers registered in the data service + mapping(IGraphPayments.PaymentTypes feeType => mapping(address serviceProvider => IDataServiceFees.StakeClaimsList list)) + public claimsLists; + + /// @dev Gap to allow adding variables in future upgrades + uint256[50] private __gap; +} diff --git a/packages/subgraph-service/contracts/data-service/extensions/DataServicePausable.sol b/packages/subgraph-service/contracts/data-service/extensions/DataServicePausable.sol new file mode 100644 index 000000000..ab0ec97c3 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/extensions/DataServicePausable.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IDataServicePausable } from "./IDataServicePausable.sol"; + +import { Pausable } from "@openzeppelin/contracts/utils/Pausable.sol"; +import { DataService } from "../DataService.sol"; + +abstract contract DataServicePausable is Pausable, DataService, IDataServicePausable { + mapping(address pauseGuardian => bool allowed) public pauseGuardians; + + event PauseGuardianSet(address indexed account, bool allowed); + + error DataServicePausableNotPauseGuardian(address account); + + modifier onlyPauseGuardian() { + if (!pauseGuardians[msg.sender]) { + revert DataServicePausableNotPauseGuardian(msg.sender); + } + _; + } + + function pause() public onlyPauseGuardian whenNotPaused { + _pause(); + } + + function unpause() public onlyPauseGuardian whenPaused { + _unpause(); + } + + function _setPauseGuardian(address _pauseGuardian, bool _allowed) internal whenNotPaused { + pauseGuardians[_pauseGuardian] = _allowed; + emit PauseGuardianSet(_pauseGuardian, _allowed); + } +} diff --git a/packages/subgraph-service/contracts/data-service/extensions/DataServiceRescuable.sol b/packages/subgraph-service/contracts/data-service/extensions/DataServiceRescuable.sol new file mode 100644 index 000000000..7e6120783 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/extensions/DataServiceRescuable.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IDataServiceRescuable } from "./IDataServiceRescuable.sol"; + +import { DataService } from "../DataService.sol"; + +import { Denominations } from "../libraries/Denominations.sol"; +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +/** + * @title Rescuable contract + * @dev Allows a contract to have a function to rescue tokens sent by mistake. + * The contract must implement the external rescueTokens function or similar, + * that calls this contract's _rescueTokens. + */ +abstract contract DataServiceRescuable is DataService, IDataServiceRescuable { + mapping(address rescuer => bool allowed) public rescuers; + + /** + * @dev Tokens rescued by the user + */ + event TokensRescued(address indexed from, address indexed to, uint256 amount); + event RescuerSet(address indexed account, bool allowed); + + error DataServiceRescuableCannotRescueZero(); + error DataServiceRescuableNotRescuer(address account); + + modifier onlyRescuer() { + if (!rescuers[msg.sender]) { + revert DataServiceRescuableNotRescuer(msg.sender); + } + _; + } + + function rescueGRT(address to, uint256 amount) external onlyRescuer { + _rescueTokens(to, address(GRAPH_TOKEN), amount); + } + + function rescueETH(address payable to, uint256 amount) external onlyRescuer { + _rescueTokens(to, Denominations.NATIVE_TOKEN, amount); + } + + function _setRescuer(address _rescuer, bool _allowed) internal { + rescuers[_rescuer] = _allowed; + emit RescuerSet(_rescuer, _allowed); + } + + /** + * @dev Allows rescuing tokens sent to this contract + * @param _to Destination address to send the tokens + * @param _token Address of the token being rescued + * @param _amount Amount of tokens to pull + */ + function _rescueTokens(address _to, address _token, uint256 _amount) internal { + if (_amount == 0) revert DataServiceRescuableCannotRescueZero(); + + if (Denominations.isNativeToken(_token)) payable(_to).transfer(_amount); + else SafeERC20.safeTransfer(IERC20(_token), _to, _amount); + + emit TokensRescued(msg.sender, _to, _amount); + } +} diff --git a/packages/subgraph-service/contracts/data-service/extensions/IDataServiceFees.sol b/packages/subgraph-service/contracts/data-service/extensions/IDataServiceFees.sol new file mode 100644 index 000000000..36caf73f1 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/extensions/IDataServiceFees.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IDataService } from "../IDataService.sol"; +import { IGraphPayments } from "../../interfaces/IGraphPayments.sol"; + +interface IDataServiceFees is IDataService { + struct StakeClaimsList { + bytes32 head; + bytes32 tail; + uint256 nonce; + } + + /// A locked stake claim to be released to a service provider + struct StakeClaim { + address serviceProvider; + // tokens to be released with this claim + uint256 tokens; + uint256 createdAt; + // timestamp when the claim can be released + uint256 releaseAt; + // next claim in the linked list + bytes32 nextClaim; + } + + function releaseStake(IGraphPayments.PaymentTypes feeType, uint256 n) external; +} diff --git a/packages/subgraph-service/contracts/data-service/extensions/IDataServicePausable.sol b/packages/subgraph-service/contracts/data-service/extensions/IDataServicePausable.sol new file mode 100644 index 000000000..5b2940d6c --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/extensions/IDataServicePausable.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IDataService } from "../IDataService.sol"; + +interface IDataServicePausable is IDataService { + function pause() external; + function unpause() external; +} diff --git a/packages/subgraph-service/contracts/data-service/extensions/IDataServiceRescuable.sol b/packages/subgraph-service/contracts/data-service/extensions/IDataServiceRescuable.sol new file mode 100644 index 000000000..36ad6d68f --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/extensions/IDataServiceRescuable.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IDataService } from "../IDataService.sol"; + +interface IDataServiceRescuable is IDataService { + function rescueGRT(address to, uint256 amount) external; + function rescueETH(address payable to, uint256 amount) external; +} diff --git a/packages/subgraph-service/contracts/data-service/libraries/Denominations.sol b/packages/subgraph-service/contracts/data-service/libraries/Denominations.sol new file mode 100644 index 000000000..a5f543fb2 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/libraries/Denominations.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +/** + * @title Denominations + * @dev Provides a list of ground denominations for those tokens that cannot be represented by an ERC20. + * For now, the only needed is the native token that could be ETH, MATIC, or other depending on the layer being operated. + */ +library Denominations { + address internal constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; + + function isNativeToken(address token) internal pure returns (bool) { + return token == NATIVE_TOKEN; + } +} diff --git a/packages/subgraph-service/contracts/data-service/libraries/PPMMath.sol b/packages/subgraph-service/contracts/data-service/libraries/PPMMath.sol new file mode 100644 index 000000000..ac0f65252 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/libraries/PPMMath.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +library PPMMath { + /// @notice Maximum value in parts per million (PPM). + uint256 internal constant MAX_PPM = 1_000_000; + + error PPMMathInvalidPPM(uint256 ppm); + error PPMMathInvalidMulPPM(uint256 a, uint256 b); + + // one of a or b must be in PPM + function mulPPM(uint256 a, uint256 b) internal pure returns (uint256) { + if (!isValidPPM(a) && !isValidPPM(b)) { + revert PPMMathInvalidMulPPM(a, b); + } + return (a * b) / MAX_PPM; + } + + // Calculate the tokens after curation fees first, and subtact that, + // to prevent curation fees from rounding down to zero + // a must be in ppm + function mulPPMRoundUp(uint256 a, uint256 b) internal pure returns (uint256) { + if (!isValidPPM(a)) { + revert PPMMathInvalidPPM(a); + } + return b - mulPPM(MAX_PPM - a, b); + } + + function isValidPPM(uint256 ppm) internal pure returns (bool) { + return ppm >= 0 && ppm <= MAX_PPM; + } +} diff --git a/packages/subgraph-service/contracts/data-service/libraries/ProvisionGetter.sol b/packages/subgraph-service/contracts/data-service/libraries/ProvisionGetter.sol new file mode 100644 index 000000000..4de039012 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/libraries/ProvisionGetter.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; + +library ProvisionGetter { + using ProvisionGetter for IHorizonStaking.Provision; + + error ProvisionGetterProvisionNotFound(address serviceProvider, address service); + + function get( + IHorizonStaking graphStaking, + address serviceProvider + ) internal view returns (IHorizonStaking.Provision memory) { + IHorizonStaking.Provision memory provision = graphStaking.getProvision(serviceProvider, address(this)); + if (provision.createdAt == 0) { + revert ProvisionGetterProvisionNotFound(serviceProvider, address(this)); + } + return provision; + } +} diff --git a/packages/subgraph-service/contracts/data-service/libraries/ProvisionTracker.sol b/packages/subgraph-service/contracts/data-service/libraries/ProvisionTracker.sol new file mode 100644 index 000000000..216bbe3dc --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/libraries/ProvisionTracker.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; + +library ProvisionTracker { + error ProvisionTrackerInsufficientTokens(uint256 tokensAvailable, uint256 tokensRequired); + + function lock( + mapping(address => uint256) storage self, + IHorizonStaking graphStaking, + address serviceProvider, + uint256 tokens + ) internal { + if (tokens == 0) return; + + uint256 tokensRequired = self[serviceProvider] + tokens; + uint256 tokensAvailable = graphStaking.getTokensAvailable(serviceProvider, address(this)); + if (tokensRequired > tokensAvailable) { + revert ProvisionTrackerInsufficientTokens(tokensAvailable, tokensRequired); + } + self[serviceProvider] += tokens; + } + + function release(mapping(address => uint256) storage self, address serviceProvider, uint256 tokens) internal { + if (tokens == 0) return; + + if (tokens > self[serviceProvider]) { + revert ProvisionTrackerInsufficientTokens(self[serviceProvider], tokens); + } + self[serviceProvider] -= tokens; + } + + function getTokensFree( + mapping(address => uint256) storage self, + IHorizonStaking graphStaking, + address serviceProvider + ) internal view returns (uint256) { + uint256 tokensAvailable = graphStaking.getTokensAvailable(serviceProvider, address(this)); + if (tokensAvailable >= self[serviceProvider]) return tokensAvailable - self[serviceProvider]; + else return 0; + } +} diff --git a/packages/subgraph-service/contracts/data-service/libraries/UintRange.sol b/packages/subgraph-service/contracts/data-service/libraries/UintRange.sol new file mode 100644 index 000000000..f98714d25 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/libraries/UintRange.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +library UintRange { + using UintRange for uint256; + + function isInRange(uint256 self, uint256 min, uint256 max) internal pure returns (bool) { + return self >= min && self <= max; + } +} diff --git a/packages/subgraph-service/contracts/data-service/utilities/ProvisionManager.sol b/packages/subgraph-service/contracts/data-service/utilities/ProvisionManager.sol new file mode 100644 index 000000000..581cff131 --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/utilities/ProvisionManager.sol @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; + +import { GraphDirectory } from "../GraphDirectory.sol"; +import { ProvisionManagerV1Storage } from "./ProvisionManagerStorage.sol"; + +import { ProvisionGetter } from "../libraries/ProvisionGetter.sol"; +import { UintRange } from "../libraries/UintRange.sol"; + +abstract contract ProvisionManager is GraphDirectory, ProvisionManagerV1Storage { + using ProvisionGetter for IHorizonStaking; + using UintRange for uint256; + + error ProvisionManagerInvalidProvisionTokens( + uint256 tokens, + uint256 minimumProvisionTokens, + uint256 maximumProvisionTokens + ); + error ProvisionManagerInvalidVerifierCut( + uint256 verifierCut, + uint256 minimumVerifierCut, + uint256 maximumVerifierCut + ); + error ProvisionManagerInvalidThawingPeriod( + uint64 thawingPeriod, + uint64 minimumThawingPeriod, + uint64 maximumThawingPeriod + ); + error ProvisionManagerNotAuthorized(address caller, address serviceProvider, address service); + + modifier onlyProvisionAuthorized(address serviceProvider) { + if (!GRAPH_STAKING.isAuthorized(msg.sender, serviceProvider, address(this))) { + revert ProvisionManagerNotAuthorized(msg.sender, serviceProvider, address(this)); + } + _; + } + + constructor() { + minimumProvisionTokens = type(uint256).min; + maximumProvisionTokens = type(uint256).max; + + minimumThawingPeriod = type(uint64).min; + maximumThawingPeriod = type(uint64).max; + + minimumVerifierCut = type(uint32).min; + maximumVerifierCut = type(uint32).max; + } + + function _checkAndAcceptProvision(address _serviceProvider) internal virtual { + _checkProvisionParameters(_serviceProvider); + GRAPH_STAKING.acceptProvision(_serviceProvider); + } + + // -- Provision Parameters: setters -- + function _setProvisionTokensRange(uint256 _min, uint256 _max) internal { + minimumProvisionTokens = _min; + maximumProvisionTokens = _max; + } + + function _setVerifierCutRange(uint32 _min, uint32 _max) internal { + minimumVerifierCut = _min; + maximumVerifierCut = _max; + } + + function _setThawingPeriodRange(uint64 _min, uint64 _max) internal { + minimumThawingPeriod = _min; + maximumThawingPeriod = _max; + } + + /// @notice Checks if the service provider has a valid provision for the data service in the staking contract + /// @param _serviceProvider The address of the service provider + function _checkProvisionParameters(address _serviceProvider) internal view virtual { + IHorizonStaking.Provision memory provision = _getProvision(_serviceProvider); + + (uint256 provisionTokensMin, uint256 provisionTokensMax) = _getProvisionTokensRange(); + if (!provision.tokens.isInRange(provisionTokensMin, provisionTokensMax)) { + revert ProvisionManagerInvalidProvisionTokens(provision.tokens, provisionTokensMin, provisionTokensMax); + } + + (uint64 thawingPeriodMin, uint64 thawingPeriodMax) = _getThawingPeriodRange(); + if (!uint256(provision.thawingPeriod).isInRange(thawingPeriodMin, thawingPeriodMax)) { + revert ProvisionManagerInvalidThawingPeriod(provision.thawingPeriod, thawingPeriodMin, thawingPeriodMax); + } + + (uint32 verifierCutMin, uint32 verifierCutMax) = _getVerifierCutRange(); + if (!uint256(provision.maxVerifierCut).isInRange(verifierCutMin, verifierCutMax)) { + revert ProvisionManagerInvalidVerifierCut(provision.maxVerifierCut, verifierCutMin, verifierCutMax); + } + } + + // -- Provision Parameters: getters -- + function _getProvisionTokensRange() internal view virtual returns (uint256 min, uint256 max) { + return (minimumProvisionTokens, maximumProvisionTokens); + } + + function _getThawingPeriodRange() internal view virtual returns (uint64 min, uint64 max) { + return (minimumThawingPeriod, maximumThawingPeriod); + } + + function _getVerifierCutRange() internal view virtual returns (uint32 min, uint32 max) { + return (minimumVerifierCut, maximumVerifierCut); + } + + function _getProvision(address _serviceProvider) internal view returns (IHorizonStaking.Provision memory) { + return GRAPH_STAKING.get(_serviceProvider); + } +} diff --git a/packages/subgraph-service/contracts/data-service/utilities/ProvisionManagerStorage.sol b/packages/subgraph-service/contracts/data-service/utilities/ProvisionManagerStorage.sol new file mode 100644 index 000000000..e7a25e6ab --- /dev/null +++ b/packages/subgraph-service/contracts/data-service/utilities/ProvisionManagerStorage.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +abstract contract ProvisionManagerV1Storage { + /// @notice The minimum amount of tokens required to register a provision in the data service + uint256 public minimumProvisionTokens; + + /// @notice The maximum amount of tokens allowed to register a provision in the data service + uint256 public maximumProvisionTokens; + + /// @notice The minimum thawing period required to register a provision in the data service + uint64 public minimumThawingPeriod; + + /// @notice The maximum thawing period allowed to register a provision in the data service + uint64 public maximumThawingPeriod; + + /// @notice The minimum verifier cut required to register a provision in the data service + uint32 public minimumVerifierCut; + + /// @notice The maximum verifier cut allowed to register a provision in the data service + uint32 public maximumVerifierCut; + + /// @dev Gap to allow adding variables in future upgrades + uint256[50] private __gap; +} diff --git a/packages/subgraph-service/contracts/interfaces/IDisputeManager.sol b/packages/subgraph-service/contracts/interfaces/IDisputeManager.sol new file mode 100644 index 000000000..d40750a55 --- /dev/null +++ b/packages/subgraph-service/contracts/interfaces/IDisputeManager.sol @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.24; +pragma abicoder v2; + +import { Attestation } from "../libraries/Attestation.sol"; + +interface IDisputeManager { + // -- Dispute -- + + enum DisputeType { + Null, + IndexingDispute, + QueryDispute + } + + enum DisputeStatus { + Null, + Accepted, + Rejected, + Drawn, + Pending, + Cancelled + } + + // Disputes contain info necessary for the Arbitrator to verify and resolve + struct Dispute { + address indexer; + address fisherman; + uint256 deposit; + bytes32 relatedDisputeId; + DisputeType disputeType; + DisputeStatus status; + uint256 createdAt; + } + + // -- Attestation -- + + // -- Configuration -- + + function setDisputePeriod(uint64 disputePeriod) external; + + function setArbitrator(address arbitrator) external; + + function setMinimumDeposit(uint256 minimumDeposit) external; + + function setFishermanRewardPercentage(uint32 percentage) external; + + function setMaxSlashingPercentage(uint32 maxPercentage) external; + + // -- Dispute -- + + function createQueryDispute(bytes calldata attestationData, uint256 deposit) external returns (bytes32); + + function createQueryDisputeConflict( + bytes calldata attestationData1, + bytes calldata attestationData2 + ) external returns (bytes32, bytes32); + + function createIndexingDispute(address allocationId, uint256 deposit) external returns (bytes32); + + function acceptDispute(bytes32 disputeId, uint256 slashAmount) external; + + function rejectDispute(bytes32 disputeId) external; + + function drawDispute(bytes32 disputeId) external; + + function cancelDispute(bytes32 disputeId) external; + + // -- Getters -- + + function getVerifierCut() external view returns (uint32); + + function getDisputePeriod() external view returns (uint64); + + function isDisputeCreated(bytes32 disputeId) external view returns (bool); + + function encodeReceipt(Attestation.Receipt memory receipt) external view returns (bytes32); + + function getAttestationIndexer(Attestation.State memory attestation) external view returns (address); + + function areConflictingAttestations( + Attestation.State memory attestation1, + Attestation.State memory attestation2 + ) external pure returns (bool); +} diff --git a/packages/subgraph-service/contracts/interfaces/IGraphEscrow.sol b/packages/subgraph-service/contracts/interfaces/IGraphEscrow.sol new file mode 100644 index 000000000..111d667b2 --- /dev/null +++ b/packages/subgraph-service/contracts/interfaces/IGraphEscrow.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +interface IGraphEscrow { + function getSender(address signer) external view returns (address sender); +} diff --git a/packages/subgraph-service/contracts/interfaces/IGraphPayments.sol b/packages/subgraph-service/contracts/interfaces/IGraphPayments.sol new file mode 100644 index 000000000..0fa08fa63 --- /dev/null +++ b/packages/subgraph-service/contracts/interfaces/IGraphPayments.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +interface IGraphPayments { + enum PaymentTypes { + QueryFee, + IndexingFee + } + + function collect( + address sender, + address receiver, + uint256 tokens, + PaymentTypes paymentType, + uint256 tokensDataService + ) external returns (uint256); +} diff --git a/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol b/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol new file mode 100644 index 000000000..ab62a3d84 --- /dev/null +++ b/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IDataServiceFees } from "../data-service/extensions/IDataServiceFees.sol"; + +import { Allocation } from "../libraries/Allocation.sol"; +import { LegacyAllocation } from "../libraries/LegacyAllocation.sol"; + +interface ISubgraphService is IDataServiceFees { + struct Indexer { + uint256 registeredAt; + string url; + string geoHash; + } + + struct PaymentFee { + uint128 servicePercentage; + uint128 curationPercentage; + } + + function resizeAllocation(address indexer, address allocationId, uint256 tokens) external; + + function migrateLegacyAllocation(address indexer, address allocationId, bytes32 subgraphDeploymentID) external; + + function setPauseGuardian(address pauseGuardian, bool allowed) external; + + function getAllocation(address allocationId) external view returns (Allocation.State memory); + + function getLegacyAllocation(address allocationId) external view returns (LegacyAllocation.State memory); + + function encodeAllocationProof(address _indexer, address _allocationId) external view returns (bytes32); +} diff --git a/packages/subgraph-service/contracts/interfaces/ITAPVerifier.sol b/packages/subgraph-service/contracts/interfaces/ITAPVerifier.sol new file mode 100644 index 000000000..2cbfdf052 --- /dev/null +++ b/packages/subgraph-service/contracts/interfaces/ITAPVerifier.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +interface ITAPVerifier { + struct ReceiptAggregateVoucher { + address dataService; + address serviceProvider; + uint64 timestampNs; + uint128 valueAggregate; + bytes metadata; + } + + struct SignedRAV { + ReceiptAggregateVoucher rav; + bytes signature; // 65 bytes: r (32 Bytes) || s (32 Bytes) || v (1 Byte) + } + + struct SenderAuthorization { + address sender; // Sender the signer is authorized to sign for + uint256 thawEndTimestamp; // Timestamp at which thawing period ends (zero if not thawing) + } + + function verify(SignedRAV calldata rav) external returns (address sender); +} diff --git a/packages/subgraph-service/contracts/libraries/Allocation.sol b/packages/subgraph-service/contracts/libraries/Allocation.sol new file mode 100644 index 000000000..f6e9e0000 --- /dev/null +++ b/packages/subgraph-service/contracts/libraries/Allocation.sol @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +library Allocation { + using Allocation for State; + + struct State { + address indexer; + bytes32 subgraphDeploymentId; + uint256 tokens; + uint256 createdAt; + uint256 closedAt; + uint256 lastPOIPresentedAt; + uint256 accRewardsPerAllocatedToken; + uint256 accRewardsPending; + } + + error AllocationAlreadyExists(address allocationId); + error AllocationDoesNotExist(address allocationId); + error AllocationClosed(address allocationId, uint256 closedAt); + error AllocationZeroTokens(address allocationId); + + function create( + mapping(address => State) storage self, + address indexer, + address allocationId, + bytes32 subgraphDeploymentId, + uint256 tokens, + uint256 accRewardsPerAllocatedToken + ) internal returns (State memory) { + if (self[allocationId].exists()) revert AllocationAlreadyExists(allocationId); + + State memory allocation = State({ + indexer: indexer, + subgraphDeploymentId: subgraphDeploymentId, + tokens: tokens, + createdAt: block.timestamp, + closedAt: 0, + lastPOIPresentedAt: block.timestamp, + accRewardsPerAllocatedToken: accRewardsPerAllocatedToken, + accRewardsPending: 0 + }); + + self[allocationId] = allocation; + + return allocation; + } + + // Update POI timestamp and take rewards snapshot + // For stale POIs this ensures the rewards are not collected with the next valid POI + function presentPOI(mapping(address => State) storage self, address allocationId) internal returns (State memory) { + State storage allocation = _get(self, allocationId); + if (!allocation.isOpen()) revert AllocationClosed(allocationId, allocation.closedAt); + if (allocation.isAltruistic()) revert AllocationZeroTokens(allocationId); + allocation.lastPOIPresentedAt = block.timestamp; + + return allocation; + } + + function snapshotRewards( + mapping(address => State) storage self, + address allocationId, + uint256 accRewardsPerAllocatedToken + ) internal returns (State memory) { + State storage allocation = _get(self, allocationId); + if (!allocation.isOpen()) revert AllocationClosed(allocationId, allocation.closedAt); + allocation.accRewardsPerAllocatedToken = accRewardsPerAllocatedToken; + + return allocation; + } + + function close(mapping(address => State) storage self, address allocationId) internal returns (State memory) { + State storage allocation = _get(self, allocationId); + if (!allocation.isOpen()) revert AllocationClosed(allocationId, allocation.closedAt); + allocation.closedAt = block.timestamp; + + return allocation; + } + + function get(mapping(address => State) storage self, address allocationId) internal view returns (State memory) { + return _get(self, allocationId); + } + + function exists(State memory self) internal pure returns (bool) { + return self.createdAt != 0; + } + + function isOpen(State memory self) internal pure returns (bool) { + return self.exists() && self.closedAt == 0; + } + + function isAltruistic(State memory self) internal pure returns (bool) { + return self.exists() && self.tokens == 0; + } + + function _get(mapping(address => State) storage self, address allocationId) private view returns (State storage) { + State storage allocation = self[allocationId]; + if (!allocation.exists()) revert AllocationDoesNotExist(allocationId); + return allocation; + } +} diff --git a/packages/subgraph-service/contracts/libraries/Attestation.sol b/packages/subgraph-service/contracts/libraries/Attestation.sol new file mode 100644 index 000000000..1ff99b0e3 --- /dev/null +++ b/packages/subgraph-service/contracts/libraries/Attestation.sol @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +library Attestation { + // Receipt content sent from the service provider in response to request + struct Receipt { + bytes32 requestCID; + bytes32 responseCID; + bytes32 subgraphDeploymentId; + } + + // Attestation sent from the service provider in response to a request + struct State { + bytes32 requestCID; + bytes32 responseCID; + bytes32 subgraphDeploymentId; + bytes32 r; + bytes32 s; + uint8 v; + } + + // Attestation size is the sum of the receipt (96) + signature (65) + uint256 private constant ATTESTATION_SIZE_BYTES = RECEIPT_SIZE_BYTES + SIG_SIZE_BYTES; + uint256 private constant RECEIPT_SIZE_BYTES = 96; + + uint256 private constant SIG_R_LENGTH = 32; + uint256 private constant SIG_S_LENGTH = 32; + uint256 private constant SIG_V_LENGTH = 1; + uint256 private constant SIG_R_OFFSET = RECEIPT_SIZE_BYTES; + uint256 private constant SIG_S_OFFSET = RECEIPT_SIZE_BYTES + SIG_R_LENGTH; + uint256 private constant SIG_V_OFFSET = RECEIPT_SIZE_BYTES + SIG_R_LENGTH + SIG_S_LENGTH; + uint256 private constant SIG_SIZE_BYTES = SIG_R_LENGTH + SIG_S_LENGTH + SIG_V_LENGTH; + + uint256 private constant UINT8_BYTE_LENGTH = 1; + uint256 private constant BYTES32_BYTE_LENGTH = 32; + + error AttestationInvalidBytesLength(uint256 length, uint256 expectedLength); + + /** + * @dev Returns if two attestations are conflicting. + * Everything must match except for the responseId. + * @param _attestation1 Attestation + * @param _attestation2 Attestation + * @return True if the two attestations are conflicting + */ + function areConflicting( + Attestation.State memory _attestation1, + Attestation.State memory _attestation2 + ) internal pure returns (bool) { + return (_attestation1.requestCID == _attestation2.requestCID && + _attestation1.subgraphDeploymentId == _attestation2.subgraphDeploymentId && + _attestation1.responseCID != _attestation2.responseCID); + } + + /** + * @dev Parse the bytes attestation into a struct from `_data`. + * @return Attestation struct + */ + function parse(bytes memory _data) internal pure returns (State memory) { + // Check attestation data length + if (_data.length != ATTESTATION_SIZE_BYTES) { + revert AttestationInvalidBytesLength(_data.length, ATTESTATION_SIZE_BYTES); + } + + // Decode receipt + (bytes32 requestCID, bytes32 responseCID, bytes32 subgraphDeploymentId) = abi.decode( + _data, + (bytes32, bytes32, bytes32) + ); + + // Decode signature + // Signature is expected to be in the order defined in the Attestation struct + bytes32 r = _toBytes32(_data, SIG_R_OFFSET); + bytes32 s = _toBytes32(_data, SIG_S_OFFSET); + uint8 v = _toUint8(_data, SIG_V_OFFSET); + + return State(requestCID, responseCID, subgraphDeploymentId, r, s, v); + } + + /** + * @dev Parse a uint8 from `_bytes` starting at offset `_start`. + * @return uint8 value + */ + function _toUint8(bytes memory _bytes, uint256 _start) private pure returns (uint8) { + if (_bytes.length < (_start + UINT8_BYTE_LENGTH)) { + revert AttestationInvalidBytesLength(_bytes.length, _start + UINT8_BYTE_LENGTH); + } + uint8 tempUint; + + // solhint-disable-next-line no-inline-assembly + assembly { + tempUint := mload(add(add(_bytes, 0x1), _start)) + } + + return tempUint; + } + + /** + * @dev Parse a bytes32 from `_bytes` starting at offset `_start`. + * @return bytes32 value + */ + function _toBytes32(bytes memory _bytes, uint256 _start) private pure returns (bytes32) { + if (_bytes.length < (_start + BYTES32_BYTE_LENGTH)) { + revert AttestationInvalidBytesLength(_bytes.length, _start + BYTES32_BYTE_LENGTH); + } + bytes32 tempBytes32; + + // solhint-disable-next-line no-inline-assembly + assembly { + tempBytes32 := mload(add(add(_bytes, 0x20), _start)) + } + + return tempBytes32; + } +} diff --git a/packages/subgraph-service/contracts/libraries/LegacyAllocation.sol b/packages/subgraph-service/contracts/libraries/LegacyAllocation.sol new file mode 100644 index 000000000..bef060e8b --- /dev/null +++ b/packages/subgraph-service/contracts/libraries/LegacyAllocation.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +library LegacyAllocation { + using LegacyAllocation for State; + + struct State { + address indexer; + bytes32 subgraphDeploymentID; + } + + error LegacyAllocationExists(address allocationId); + error LegacyAllocationDoesNotExist(address allocationId); + error LegacyAllocationAlreadyMigrated(address allocationId); + + function migrate( + mapping(address => State) storage self, + address indexer, + address allocationId, + bytes32 subgraphDeploymentID + ) internal { + if (self[allocationId].exists()) revert LegacyAllocationAlreadyMigrated(allocationId); + + State memory allocation = State({ indexer: indexer, subgraphDeploymentID: subgraphDeploymentID }); + + self[allocationId] = allocation; + } + + function get(mapping(address => State) storage self, address allocationId) internal view returns (State memory) { + return _get(self, allocationId); + } + + function revertIfExists(mapping(address => State) storage self, address allocationId) internal view { + if (self[allocationId].exists()) revert LegacyAllocationExists(allocationId); + } + + function exists(State memory self) internal pure returns (bool) { + return self.indexer != address(0); + } + + function _get(mapping(address => State) storage self, address allocationId) private view returns (State storage) { + State storage allocation = self[allocationId]; + if (!allocation.exists()) revert LegacyAllocationDoesNotExist(allocationId); + return allocation; + } +} diff --git a/packages/subgraph-service/contracts/utilities/AllocationManager.sol b/packages/subgraph-service/contracts/utilities/AllocationManager.sol new file mode 100644 index 000000000..bcd7f1097 --- /dev/null +++ b/packages/subgraph-service/contracts/utilities/AllocationManager.sol @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { IGraphPayments } from "../interfaces/IGraphPayments.sol"; + +import { GraphDirectory } from "../data-service/GraphDirectory.sol"; +import { AllocationManagerV1Storage } from "./AllocationManagerStorage.sol"; + +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; +import { Allocation } from "../libraries/Allocation.sol"; +import { LegacyAllocation } from "../libraries/LegacyAllocation.sol"; +import { PPMMath } from "../data-service/libraries/PPMMath.sol"; +import { ProvisionTracker } from "../data-service/libraries/ProvisionTracker.sol"; + +abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManagerV1Storage { + using ProvisionTracker for mapping(address => uint256); + using Allocation for mapping(address => Allocation.State); + using LegacyAllocation for mapping(address => LegacyAllocation.State); + using PPMMath for uint256; + + // -- Immutables -- + bytes32 private immutable EIP712_ALLOCATION_PROOF_TYPEHASH = + keccak256("AllocationIdProof(address indexer,address allocationId)"); + + /** + * @dev Emitted when `indexer` allocated `tokens` amount to `subgraphDeploymentId` + * during `epoch`. + * `allocationId` indexer derived address used to identify the allocation. + */ + event AllocationCreated( + address indexed indexer, + address indexed allocationId, + bytes32 indexed subgraphDeploymentId, + uint256 tokens + ); + + event AllocationCollected( + address indexed indexer, + address indexed allocationId, + bytes32 indexed subgraphDeploymentId, + uint256 tokensRewards, + uint256 tokensIndexerRewards, + uint256 tokensDelegationRewards, + bytes32 poi + ); + + event AllocationResized( + address indexed indexer, + address indexed allocationId, + bytes32 indexed subgraphDeploymentId, + uint256 newTokens, + uint256 oldTokens + ); + + /** + * @dev Emitted when `indexer` closes an allocation with id `allocationId`. + * An amount of `tokens` get unallocated from `subgraphDeploymentId`. + */ + event AllocationClosed( + address indexed indexer, + address indexed allocationId, + bytes32 indexed subgraphDeploymentId, + uint256 tokens + ); + + event LegacyAllocationMigrated( + address indexed indexer, + address indexed allocationId, + bytes32 indexed subgraphDeploymentId + ); + + error AllocationManagerInvalidAllocationProof(address signer, address allocationId); + error AllocationManagerInvalidAllocationId(); + error AllocationManagerZeroTokensAllocation(address allocationId); + error AllocationManagerAllocationClosed(address allocationId); + error AllocationManagerAllocationSameSize(address allocationId, uint256 tokens); + error AllocationManagerInvalidZeroPOI(); + + constructor(string memory name, string memory version) EIP712(name, version) {} + + function _migrateLegacyAllocation(address _indexer, address _allocationId, bytes32 _subgraphDeploymentId) internal { + legacyAllocations.migrate(_indexer, _allocationId, _subgraphDeploymentId); + emit LegacyAllocationMigrated(_indexer, _allocationId, _subgraphDeploymentId); + } + + function _allocate( + address _indexer, + address _allocationId, + bytes32 _subgraphDeploymentId, + uint256 _tokens, + bytes memory _allocationProof + ) internal returns (Allocation.State memory) { + if (_allocationId == address(0)) revert AllocationManagerInvalidAllocationId(); + + _verifyAllocationProof(_indexer, _allocationId, _allocationProof); + + // Ensure allocation id is not reused + // need to check both subgraph service (on create()) and legacy allocations + legacyAllocations.revertIfExists(_allocationId); + Allocation.State memory allocation = allocations.create( + _indexer, + _allocationId, + _subgraphDeploymentId, + _tokens, + // allos can be resized now, so we need to always take snapshot + GRAPH_REWARDS_MANAGER.onSubgraphAllocationUpdate(_subgraphDeploymentId) + ); + + // Check that the indexer has enough tokens available + allocationProvisionTracker.lock(GRAPH_STAKING, _indexer, _tokens); + + // Update total allocated tokens for the subgraph deployment + subgraphAllocatedTokens[allocation.subgraphDeploymentId] = + subgraphAllocatedTokens[allocation.subgraphDeploymentId] + + allocation.tokens; + + emit AllocationCreated(_indexer, _allocationId, _subgraphDeploymentId, allocation.tokens); + return allocation; + } + + // Update POI timestamp and take rewards snapshot even for 0 rewards + // This ensures the rewards are actually skipped and not collected with the next valid POI + function _collectPOIRewards(address _allocationId, bytes32 _poi) internal returns (uint256) { + if (_poi == bytes32(0)) revert AllocationManagerInvalidZeroPOI(); + + Allocation.State memory allocation = allocations.get(_allocationId); + + // Mint indexing rewards, stale POIs get no rewards... + uint256 timeSinceLastPOI = block.number - allocation.lastPOIPresentedAt; + uint256 tokensRewards = timeSinceLastPOI <= maxPOIStaleness + ? GRAPH_REWARDS_MANAGER.takeRewards(_allocationId) + : 0; + + // ... but we still take a snapshot to ensure the rewards are not collected with the next valid POI + allocations.snapshotRewards( + _allocationId, + GRAPH_REWARDS_MANAGER.onSubgraphAllocationUpdate(allocation.subgraphDeploymentId) + ); + allocations.presentPOI(_allocationId); + + if (tokensRewards == 0) { + emit AllocationCollected(allocation.indexer, _allocationId, allocation.subgraphDeploymentId, 0, 0, 0, _poi); + return tokensRewards; + } + + // Distribute rewards to delegators + // TODO: remove the uint8 cast when PRs are merged + uint256 delegatorCut = GRAPH_STAKING.getDelegationCut( + allocation.indexer, + uint8(IGraphPayments.PaymentTypes.IndexingFee) + ); + uint256 tokensDelegationRewards = tokensRewards.mulPPM(delegatorCut); + GRAPH_TOKEN.approve(address(GRAPH_STAKING), tokensDelegationRewards); + GRAPH_STAKING.addToDelegationPool(allocation.indexer, tokensDelegationRewards); + + // Distribute rewards to indexer + uint256 tokensIndexerRewards = tokensRewards - tokensDelegationRewards; + address rewardsDestination = rewardsDestination[allocation.indexer]; + if (rewardsDestination == address(0)) { + GRAPH_TOKEN.approve(address(GRAPH_STAKING), tokensIndexerRewards); + GRAPH_STAKING.stakeToProvision(allocation.indexer, address(this), tokensIndexerRewards); + } else { + GRAPH_TOKEN.transfer(rewardsDestination, tokensIndexerRewards); + } + + emit AllocationCollected( + allocation.indexer, + _allocationId, + allocation.subgraphDeploymentId, + tokensRewards, + tokensIndexerRewards, + tokensDelegationRewards, + _poi + ); + + return tokensRewards; + } + + function _resizeAllocation(address _allocationId, uint256 _tokens) internal returns (Allocation.State memory) { + Allocation.State memory allocation = allocations.get(_allocationId); + + // Exit early if the allocation size is the same + if (_tokens == allocation.tokens) { + revert AllocationManagerAllocationSameSize(_allocationId, _tokens); + } + + // Update provision tracker + uint256 oldTokens = allocation.tokens; + if (_tokens > oldTokens) { + allocationProvisionTracker.lock(GRAPH_STAKING, allocation.indexer, _tokens - oldTokens); + } else { + allocationProvisionTracker.release(allocation.indexer, oldTokens - _tokens); + } + + // Calculate rewards that have been accrued since the last snapshot but not yet issued + uint256 accRewardsPerAllocatedToken = GRAPH_REWARDS_MANAGER.onSubgraphAllocationUpdate( + allocation.subgraphDeploymentId + ); + uint256 accRewardsPending = accRewardsPerAllocatedToken - allocation.accRewardsPerAllocatedToken; + + // Update the allocation + allocations[_allocationId].tokens = _tokens; + allocations[_allocationId].accRewardsPerAllocatedToken = accRewardsPerAllocatedToken; + allocations[_allocationId].accRewardsPending = allocations[_allocationId].accRewardsPending + accRewardsPending; + + // Update total allocated tokens for the subgraph deployment + subgraphAllocatedTokens[allocation.subgraphDeploymentId] = + subgraphAllocatedTokens[allocation.subgraphDeploymentId] + + (_tokens - oldTokens); + + emit AllocationResized(allocation.indexer, _allocationId, allocation.subgraphDeploymentId, _tokens, oldTokens); + return allocations[_allocationId]; + } + + function _closeAllocation(address _allocationId) internal returns (Allocation.State memory) { + Allocation.State memory allocation = allocations.get(_allocationId); + + allocations.close(_allocationId); + allocationProvisionTracker.release(allocation.indexer, allocation.tokens); + + subgraphAllocatedTokens[allocation.subgraphDeploymentId] = + subgraphAllocatedTokens[allocation.subgraphDeploymentId] - + allocation.tokens; + + emit AllocationClosed(allocation.indexer, _allocationId, allocation.subgraphDeploymentId, allocation.tokens); + return allocations[_allocationId]; + } + + function _getAllocation(address _allocationId) internal view returns (Allocation.State memory) { + return allocations.get(_allocationId); + } + + function _getLegacyAllocation(address _allocationId) internal view returns (LegacyAllocation.State memory) { + return legacyAllocations.get(_allocationId); + } + + // -- Allocation Proof Verification -- + // Caller must prove that they own the private key for the allocationId address + // The proof is an EIP712 signed message of (indexer,allocationId) + function _verifyAllocationProof(address _indexer, address _allocationId, bytes memory _proof) internal view { + bytes32 digest = _encodeAllocationProof(_indexer, _allocationId); + address signer = ECDSA.recover(digest, _proof); + if (signer != _allocationId) revert AllocationManagerInvalidAllocationProof(signer, _allocationId); + } + + function _encodeAllocationProof(address _indexer, address _allocationId) internal view returns (bytes32) { + return + EIP712._hashTypedDataV4(keccak256(abi.encode(EIP712_ALLOCATION_PROOF_TYPEHASH, _indexer, _allocationId))); + } +} diff --git a/packages/subgraph-service/contracts/utilities/AllocationManagerStorage.sol b/packages/subgraph-service/contracts/utilities/AllocationManagerStorage.sol new file mode 100644 index 000000000..c737acabf --- /dev/null +++ b/packages/subgraph-service/contracts/utilities/AllocationManagerStorage.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { Allocation } from "../libraries/Allocation.sol"; +import { LegacyAllocation } from "../libraries/LegacyAllocation.sol"; + +abstract contract AllocationManagerV1Storage { + mapping(address allocationId => Allocation.State allocation) public allocations; + mapping(address indexer => uint256 tokens) public allocationProvisionTracker; + mapping(address allocationId => LegacyAllocation.State allocation) public legacyAllocations; + + /// @notice Maximum amount of since last POI was presented to qualify for indexing rewards + uint256 public maxPOIStaleness; + + /// @dev Destination of accrued rewards + mapping(address indexer => address destination) public rewardsDestination; + + /// @notice Track total tokens allocated per subgraph deployment + /// @dev Used to calculate indexing rewards + mapping(bytes32 subgraphDeploymentId => uint256 tokens) public subgraphAllocatedTokens; + + /// @dev Gap to allow adding variables in future upgrades + uint256[50] private __gap; +} diff --git a/packages/subgraph-service/contracts/utilities/AttestationManager.sol b/packages/subgraph-service/contracts/utilities/AttestationManager.sol new file mode 100644 index 000000000..2c1e18150 --- /dev/null +++ b/packages/subgraph-service/contracts/utilities/AttestationManager.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { AttestationManagerV1Storage } from "./AttestationManagerStorage.sol"; + +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import { Attestation } from "../libraries/Attestation.sol"; + +abstract contract AttestationManager is AttestationManagerV1Storage { + bytes32 private constant RECEIPT_TYPE_HASH = + keccak256("Receipt(bytes32 requestCID,bytes32 responseCID,bytes32 subgraphDeploymentID)"); + + bytes32 private constant DOMAIN_TYPE_HASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)"); + bytes32 private constant DOMAIN_NAME_HASH = keccak256("Graph Protocol"); + bytes32 private constant DOMAIN_VERSION_HASH = keccak256("0"); + bytes32 private constant DOMAIN_SALT = 0xa070ffb1cd7409649bf77822cce74495468e06dbfaef09556838bf188679b9c2; + + constructor() { + // EIP-712 domain separator + _domainSeparator = keccak256( + abi.encode( + DOMAIN_TYPE_HASH, + DOMAIN_NAME_HASH, + DOMAIN_VERSION_HASH, + block.chainid, + address(this), + DOMAIN_SALT + ) + ); + } + + /** + * @dev Recover the signer address of the `_attestation`. + * @param _attestation The attestation struct + * @return Signer address + */ + function _recoverSigner(Attestation.State memory _attestation) internal view returns (address) { + // Obtain the hash of the fully-encoded message, per EIP-712 encoding + Attestation.Receipt memory receipt = Attestation.Receipt( + _attestation.requestCID, + _attestation.responseCID, + _attestation.subgraphDeploymentId + ); + bytes32 messageHash = _encodeReceipt(receipt); + + // Obtain the signer of the fully-encoded EIP-712 message hash + // NOTE: The signer of the attestation is the indexer that served the request + return ECDSA.recover(messageHash, abi.encodePacked(_attestation.r, _attestation.s, _attestation.v)); + } + + /** + * @dev Get the message hash that a indexer used to sign the receipt. + * Encodes a receipt using a domain separator, as described on + * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#specification. + * @notice Return the message hash used to sign the receipt + * @param _receipt Receipt returned by indexer and submitted by fisherman + * @return Message hash used to sign the receipt + */ + function _encodeReceipt(Attestation.Receipt memory _receipt) internal view returns (bytes32) { + return + keccak256( + abi.encodePacked( + "\x19\x01", // EIP-191 encoding pad, EIP-712 version 1 + _domainSeparator, + keccak256( + abi.encode( + RECEIPT_TYPE_HASH, + _receipt.requestCID, + _receipt.responseCID, + _receipt.subgraphDeploymentId + ) // EIP 712-encoded message hash + ) + ) + ); + } +} diff --git a/packages/subgraph-service/contracts/utilities/AttestationManagerStorage.sol b/packages/subgraph-service/contracts/utilities/AttestationManagerStorage.sol new file mode 100644 index 000000000..80aa0388f --- /dev/null +++ b/packages/subgraph-service/contracts/utilities/AttestationManagerStorage.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +abstract contract AttestationManagerV1Storage { + bytes32 internal _domainSeparator; + + /// @dev Gap to allow adding variables in future upgrades + uint256[50] private __gap; +} diff --git a/packages/subgraph-service/contracts/utilities/Directory.sol b/packages/subgraph-service/contracts/utilities/Directory.sol new file mode 100644 index 000000000..cd87de102 --- /dev/null +++ b/packages/subgraph-service/contracts/utilities/Directory.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.24; + +import { ITAPVerifier } from "../interfaces/ITAPVerifier.sol"; +import { IDisputeManager } from "../interfaces/IDisputeManager.sol"; +import { ISubgraphService } from "../interfaces/ISubgraphService.sol"; +import { ICuration } from "@graphprotocol/contracts/contracts/curation/ICuration.sol"; + +abstract contract Directory { + ITAPVerifier public immutable TAP_VERIFIER; + IDisputeManager public immutable DISPUTE_MANAGER; + ISubgraphService public immutable SUBGRAPH_SERVICE; + ICuration public immutable CURATION; + + event SubgraphServiceDirectoryInitialized( + address subgraphService, + address tapVerifier, + address disputeManager, + address curation + ); + error DirectoryNotDisputeManager(address caller, address disputeManager); + + modifier onlyDisputeManager() { + if (msg.sender != address(DISPUTE_MANAGER)) { + revert DirectoryNotDisputeManager(msg.sender, address(DISPUTE_MANAGER)); + } + _; + } + + constructor(address subgraphService, address tapVerifier, address disputeManager, address curation) { + SUBGRAPH_SERVICE = ISubgraphService(subgraphService); + TAP_VERIFIER = ITAPVerifier(tapVerifier); + DISPUTE_MANAGER = IDisputeManager(disputeManager); + CURATION = ICuration(curation); + + emit SubgraphServiceDirectoryInitialized(subgraphService, tapVerifier, disputeManager, curation); + } +} diff --git a/packages/subgraph-service/eslint.config.js b/packages/subgraph-service/eslint.config.js new file mode 100644 index 000000000..2cb4335fd --- /dev/null +++ b/packages/subgraph-service/eslint.config.js @@ -0,0 +1,21 @@ +// @ts-check +/* eslint-disable no-undef */ +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ + +const eslintGraphConfig = require('eslint-graph-config') +module.exports = [ + ...eslintGraphConfig.default, + { + rules: { + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + }, + }, + { + ignores: ['typechain-types/*'], + }, +] diff --git a/packages/subgraph-service/foundry.toml b/packages/subgraph-service/foundry.toml new file mode 100644 index 000000000..55f7ffd31 --- /dev/null +++ b/packages/subgraph-service/foundry.toml @@ -0,0 +1,6 @@ +[profile.default] +src = 'contracts' +out = 'build' +libs = ['node_modules', 'lib'] +test = 'test' +cache_path = 'cache_forge' \ No newline at end of file diff --git a/packages/subgraph-service/hardhat.config.ts b/packages/subgraph-service/hardhat.config.ts new file mode 100644 index 000000000..f4a7067b7 --- /dev/null +++ b/packages/subgraph-service/hardhat.config.ts @@ -0,0 +1,37 @@ +// import '@nomicfoundation/hardhat-foundry' +import '@nomicfoundation/hardhat-toolbox' +import 'hardhat-contract-sizer' +import 'hardhat-storage-layout' +import 'solidity-docgen' + +import { HardhatUserConfig } from 'hardhat/config' + +const config: HardhatUserConfig = { + solidity: { + compilers: [ + { + version: '0.8.24', + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + metadata: { + useLiteralContent: true, + }, + outputSelection: { + '*': { + '*': ['storageLayout', 'metadata'], + }, + }, + }, + }, + ], + }, + paths: { + artifacts: './build/contracts', + sources: './contracts', + }, +} + +export default config diff --git a/packages/subgraph-service/lib/forge-std b/packages/subgraph-service/lib/forge-std new file mode 160000 index 000000000..bb4ceea94 --- /dev/null +++ b/packages/subgraph-service/lib/forge-std @@ -0,0 +1 @@ +Subproject commit bb4ceea94d6f10eeb5b41dc2391c6c8bf8e734ef diff --git a/packages/subgraph-service/package.json b/packages/subgraph-service/package.json new file mode 100644 index 000000000..f66d229de --- /dev/null +++ b/packages/subgraph-service/package.json @@ -0,0 +1,63 @@ +{ + "name": "@graphprotocol/subgraph-service", + "version": "0.0.1", + "description": "", + "author": "The Graph Team", + "license": "GPL-2.0-or-later", + "scripts": { + "lint:ts": "eslint '**/*.{js,ts}' --fix", + "lint:sol": "prettier --write contracts/**/*.sol && solhint --noPrompt --fix contracts/**/*.sol --config node_modules/solhint-graph-config/index.js", + "lint": "yarn lint:ts && yarn lint:sol", + "clean": "rm -rf build cache typechain-types", + "build": "forge build && hardhat compile", + "test": "forge test && hardhat test" + }, + "devDependencies": { + "@graphprotocol/contracts": "workspace:^7.0.0", + "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-foundry": "^1.1.1", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomicfoundation/hardhat-toolbox": "^4.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.0", + "@openzeppelin/contracts": "^5.0.2", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.0.0", + "@types/chai": "^4.2.0", + "@types/mocha": ">=9.1.0", + "@types/node": ">=16.0.0", + "chai": "^4.2.0", + "eslint": "^8.56.0", + "eslint-graph-config": "workspace:^0.0.1", + "ethers": "^6.4.0", + "hardhat": "^2.20.1", + "hardhat-contract-sizer": "^2.10.0", + "hardhat-gas-reporter": "^1.0.8", + "hardhat-storage-layout": "^0.1.7", + "lint-staged": "^15.2.2", + "prettier": "^3.2.5", + "prettier-plugin-solidity": "^1.3.1", + "solhint": "^4.5.4", + "solhint-graph-config": "workspace:^0.0.1", + "solhint-plugin-graph": "file:node_modules/solhint-graph-config/plugin", + "solidity-coverage": "^0.8.0", + "solidity-docgen": "^0.6.0-beta.36", + "ts-node": ">=8.0.0", + "typechain": "^8.3.0", + "typescript": "^5.3.3" + }, + "lint-staged": { + "contracts/**/*.sol": [ + "yarn lint:sol" + ], + "**/*.ts": [ + "yarn lint:ts" + ], + "**/*.js": [ + "yarn lint:ts" + ], + "**/*.json": [ + "yarn lint:ts" + ] + } +} diff --git a/packages/subgraph-service/prettier.config.js b/packages/subgraph-service/prettier.config.js new file mode 100644 index 000000000..5b8e866f2 --- /dev/null +++ b/packages/subgraph-service/prettier.config.js @@ -0,0 +1,2 @@ +const prettierGraphConfig = require('solhint-graph-config/prettier') +module.exports = prettierGraphConfig diff --git a/packages/subgraph-service/remappings.txt b/packages/subgraph-service/remappings.txt new file mode 100644 index 000000000..1bd6482cd --- /dev/null +++ b/packages/subgraph-service/remappings.txt @@ -0,0 +1,5 @@ +@graphprotocol/contracts/=node_modules/@graphprotocol/contracts/ +forge-std/=lib/forge-std/src/ +ds-test/=lib/forge-std/lib/ds-test/src/ +eth-gas-reporter/=node_modules/eth-gas-reporter/ +hardhat/=node_modules/hardhat/ diff --git a/packages/subgraph-service/scripts/deploy.ts b/packages/subgraph-service/scripts/deploy.ts new file mode 100644 index 000000000..cf87ff10f --- /dev/null +++ b/packages/subgraph-service/scripts/deploy.ts @@ -0,0 +1,28 @@ +import { ethers } from 'hardhat' + +async function main() { + const currentTimestampInSeconds = Math.round(Date.now() / 1000) + const unlockTime = currentTimestampInSeconds + 60 + + const lockedAmount = ethers.parseEther('0.001') + const a = 1 + console.log(a) + const lock = await ethers.deployContract('Lock', [unlockTime], { + value: lockedAmount, + }) + + await lock.waitForDeployment() + + console.log( + `Lock with ${ethers.formatEther( + lockedAmount, + )}ETH and unlock timestamp ${unlockTime} deployed to ${typeof lock.target == 'string' ? lock.target : ''}`, + ) +} + +// We recommend this pattern to be able to use async/await everywhere +// and properly handle errors. +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/packages/subgraph-service/test/DisputeManager.t.sol b/packages/subgraph-service/test/DisputeManager.t.sol new file mode 100644 index 000000000..bc8e8f42d --- /dev/null +++ b/packages/subgraph-service/test/DisputeManager.t.sol @@ -0,0 +1,501 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import "forge-std/Test.sol"; + +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import { TokenUtils } from "@graphprotocol/contracts/contracts/utils/TokenUtils.sol"; +import { Controller } from "@graphprotocol/contracts/contracts/governance/Controller.sol"; + +import { DisputeManager } from "../contracts/DisputeManager.sol"; +import { IDisputeManager } from "../contracts/interfaces/IDisputeManager.sol"; +import { Attestation } from "../contracts/libraries/Attestation.sol"; + +import { SubgraphService } from "../contracts/SubgraphService.sol"; + +// Mocks + +import "./mocks/MockGRTToken.sol"; +import "./mocks/MockHorizonStaking.sol"; +import "./mocks/MockRewardsManager.sol"; + +contract DisputeManagerTest is Test { + DisputeManager disputeManager; + + address governor; + address arbitrator; + + uint256 indexerPrivateKey; + address indexer; + + uint256 fishermanPrivateKey; + address fisherman; + + uint256 allocationIDPrivateKey; + address allocationID; + + uint64 disputePeriod = 300; // 5 minutes + uint256 minimumDeposit = 100 ether; // 100 GRT + uint32 fishermanRewardPercentage = 100000; // 10% + uint32 maxSlashingPercentage = 500000; // 50% + + Controller controller; + MockGRTToken graphToken; + SubgraphService subgraphService; + MockHorizonStaking staking; + MockRewardsManager rewardsManager; + + // Setup + + function setUp() public { + governor = address(0xA1); + arbitrator = address(0xA2); + + indexerPrivateKey = 0xB1; + indexer = vm.addr(indexerPrivateKey); + + fishermanPrivateKey = 0xC1; + fisherman = vm.addr(fishermanPrivateKey); + + allocationIDPrivateKey = 0xD1; + allocationID = vm.addr(allocationIDPrivateKey); + + graphToken = new MockGRTToken(); + staking = new MockHorizonStaking(address(graphToken)); + rewardsManager = new MockRewardsManager(); + + address payments = address(0xE2); + address tapVerifier = address(0xE3); + address curation = address(0xE4); + + vm.startPrank(governor); + controller = new Controller(); + controller.setContractProxy(keccak256("GraphToken"), address(graphToken)); + controller.setContractProxy(keccak256("Staking"), address(staking)); + controller.setContractProxy(keccak256("RewardsManager"), address(rewardsManager)); + vm.stopPrank(); + + disputeManager = new DisputeManager( + address(controller), + arbitrator, + disputePeriod, + minimumDeposit, + fishermanRewardPercentage, + maxSlashingPercentage + ); + + subgraphService = new SubgraphService( + address(controller), + address(disputeManager), + tapVerifier, + curation, + 1000 ether + ); + + disputeManager.setSubgraphService(address(subgraphService)); + } + + // Helper functions + + function createProvisionAndAllocate(address _allocationID, uint256 tokens) private { + vm.startPrank(indexer); + graphToken.mint(indexer, tokens); + staking.provision(tokens, address(subgraphService), 500000, 300); + bytes32 subgraphDeployment = keccak256(abi.encodePacked("Subgraph Deployment ID")); + bytes32 digest = subgraphService.encodeAllocationProof(indexer, _allocationID); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(allocationIDPrivateKey, digest); + + subgraphService.register( + indexer, + abi.encode("url", "geoHash") + ); + + bytes memory data = abi.encode( + subgraphDeployment, + tokens, + _allocationID, + abi.encodePacked(r, s, v) + ); + subgraphService.startService(indexer, data); + vm.stopPrank(); + } + + function createIndexingDispute(address _allocationID, uint256 tokens) private returns (bytes32 disputeID) { + vm.startPrank(fisherman); + graphToken.mint(fisherman, tokens); + graphToken.approve(address(disputeManager), tokens); + bytes32 _disputeID = disputeManager.createIndexingDispute(_allocationID, tokens); + vm.stopPrank(); + return _disputeID; + } + + function createQueryDispute(uint256 tokens) private returns (bytes32 disputeID) { + Attestation.Receipt memory receipt = Attestation.Receipt({ + requestCID: keccak256(abi.encodePacked("Request CID")), + responseCID: keccak256(abi.encodePacked("Response CID")), + subgraphDeploymentId: keccak256(abi.encodePacked("Subgraph Deployment ID")) + }); + bytes memory attestationData = createAtestationData(receipt, allocationIDPrivateKey); + + vm.startPrank(fisherman); + graphToken.mint(fisherman, tokens); + graphToken.approve(address(disputeManager), tokens); + bytes32 _disputeID = disputeManager.createQueryDispute(attestationData, tokens); + vm.stopPrank(); + return _disputeID; + } + + function createConflictingAttestations( + bytes32 responseCID1, + bytes32 subgraphDeploymentId1, + bytes32 responseCID2, + bytes32 subgraphDeploymentId2 + ) private view returns (bytes memory attestationData1, bytes memory attestationData2) { + bytes32 requestCID = keccak256(abi.encodePacked("Request CID")); + Attestation.Receipt memory receipt1 = Attestation.Receipt({ + requestCID: requestCID, + responseCID: responseCID1, + subgraphDeploymentId: subgraphDeploymentId1 + }); + + Attestation.Receipt memory receipt2 = Attestation.Receipt({ + requestCID: requestCID, + responseCID: responseCID2, + subgraphDeploymentId: subgraphDeploymentId2 + }); + + bytes memory _attestationData1 = createAtestationData(receipt1, allocationIDPrivateKey); + bytes memory _attestationData2 = createAtestationData(receipt2, allocationIDPrivateKey); + return (_attestationData1, _attestationData2); + } + + function createAtestationData(Attestation.Receipt memory receipt, uint256 signer) private view returns (bytes memory attestationData) { + bytes32 digest = disputeManager.encodeReceipt(receipt); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signer, digest); + + return abi.encodePacked(receipt.requestCID, receipt.responseCID, receipt.subgraphDeploymentId, r, s, v); + } + + // Tests + + // Create dispute + + function testCreateIndexingDispute() public { + createProvisionAndAllocate(allocationID, 10000 ether); + + bytes32 disputeID = createIndexingDispute(allocationID, 200 ether); + assertTrue(disputeManager.isDisputeCreated(disputeID), "Dispute should be created."); + } + + function testCreateQueryDispute() public { + createProvisionAndAllocate(allocationID, 10000 ether); + + bytes32 disputeID = createQueryDispute(200 ether); + assertTrue(disputeManager.isDisputeCreated(disputeID), "Dispute should be created."); + } + + function testCreateQueryDisputeConflict() public { + createProvisionAndAllocate(allocationID, 10000 ether); + + bytes32 responseCID1 = keccak256(abi.encodePacked("Response CID 1")); + bytes32 responseCID2 = keccak256(abi.encodePacked("Response CID 2")); + bytes32 subgraphDeploymentId = keccak256(abi.encodePacked("Subgraph Deployment ID")); + + (bytes memory attestationData1, bytes memory attestationData2) = + createConflictingAttestations( + responseCID1, + subgraphDeploymentId, + responseCID2, + subgraphDeploymentId + ); + + vm.prank(fisherman); + (bytes32 disputeID1, bytes32 disputeID2) = + disputeManager.createQueryDisputeConflict(attestationData1, attestationData2); + assertTrue(disputeManager.isDisputeCreated(disputeID1), "Dispute 1 should be created."); + assertTrue(disputeManager.isDisputeCreated(disputeID2), "Dispute 2 should be created."); + } + + function test_RevertWhen_DisputeAlreadyCreated() public { + createProvisionAndAllocate(allocationID, 10000 ether); + bytes32 disputeID = createIndexingDispute(allocationID, 200 ether); + + // Create another dispute with different fisherman + address otherFisherman = address(0x5); + uint256 tokens = 200 ether; + vm.startPrank(otherFisherman); + graphToken.mint(otherFisherman, tokens); + graphToken.approve(address(disputeManager), tokens); + bytes memory expectedError = abi.encodeWithSignature("DisputeManagerDisputeAlreadyCreated(bytes32)", disputeID); + vm.expectRevert(expectedError); + disputeManager.createIndexingDispute(allocationID, tokens); + vm.stopPrank(); + } + + function test_RevertIf_DepositUnderMinimum() public { + // minimum deposit is 100 ether + vm.startPrank(fisherman); + graphToken.mint(fisherman, 50 ether); + bytes memory expectedError = abi.encodeWithSignature("DisputeManagerInsufficientDeposit(uint256,uint256)", 50 ether, 100 ether); + vm.expectRevert(expectedError); + disputeManager.createIndexingDispute(allocationID, 50 ether); + vm.stopPrank(); + } + + function test_RevertIf_AllocationDoesNotExist() public { + // create dispute without an existing allocation + uint256 tokens = 200 ether; + vm.startPrank(fisherman); + graphToken.mint(fisherman, tokens); + graphToken.approve(address(disputeManager), tokens); + bytes memory expectedError = abi.encodeWithSignature("DisputeManagerIndexerNotFound(address)", allocationID); + vm.expectRevert(expectedError); + disputeManager.createIndexingDispute(allocationID, tokens); + vm.stopPrank(); + } + + function test_RevertIf_ConflictingAttestationsResponsesAreTheSame() public { + bytes32 requestCID = keccak256(abi.encodePacked("Request CID")); + bytes32 responseCID = keccak256(abi.encodePacked("Response CID")); + bytes32 subgraphDeploymentId = keccak256(abi.encodePacked("Subgraph Deployment ID")); + + (bytes memory attestationData1, bytes memory attestationData2) = + createConflictingAttestations( + responseCID, + subgraphDeploymentId, + responseCID, + subgraphDeploymentId + ); + + vm.prank(fisherman); + + bytes memory expectedError = abi.encodeWithSignature( + "DisputeManagerNonConflictingAttestations(bytes32,bytes32,bytes32,bytes32,bytes32,bytes32)", + requestCID, + responseCID, + subgraphDeploymentId, + requestCID, + responseCID, + subgraphDeploymentId + ); + vm.expectRevert(expectedError); + disputeManager.createQueryDisputeConflict(attestationData1, attestationData2); + } + + function test_RevertIf_ConflictingAttestationsHaveDifferentSubgraph() public { + bytes32 requestCID = keccak256(abi.encodePacked("Request CID")); + bytes32 responseCID1 = keccak256(abi.encodePacked("Response CID 1")); + bytes32 responseCID2 = keccak256(abi.encodePacked("Response CID 2")); + bytes32 subgraphDeploymentId1 = keccak256(abi.encodePacked("Subgraph Deployment ID 1")); + bytes32 subgraphDeploymentId2 = keccak256(abi.encodePacked("Subgraph Deployment ID 2")); + + (bytes memory attestationData1, bytes memory attestationData2) = + createConflictingAttestations( + responseCID1, + subgraphDeploymentId1, + responseCID2, + subgraphDeploymentId2 + ); + + vm.prank(fisherman); + bytes memory expectedError = abi.encodeWithSignature( + "DisputeManagerNonConflictingAttestations(bytes32,bytes32,bytes32,bytes32,bytes32,bytes32)", + requestCID, + responseCID1, + subgraphDeploymentId1, + requestCID, + responseCID2, + subgraphDeploymentId2 + ); + vm.expectRevert(expectedError); + disputeManager.createQueryDisputeConflict(attestationData1, attestationData2); + } + + // Accept dispute + + function testAcceptIndexingDispute() public { + createProvisionAndAllocate(allocationID, 10000 ether); + bytes32 disputeID = createIndexingDispute(allocationID, 200 ether); + + vm.prank(arbitrator); + disputeManager.acceptDispute(disputeID, 5000 ether); + + assertEq(graphToken.balanceOf(fisherman), 700 ether, "Fisherman should receive 50% of slashed tokens."); + assertEq(graphToken.balanceOf(indexer), 5000 ether, "Service provider should have 5000 GRT slashed."); + } + + function testAcceptQueryDispute() public { + createProvisionAndAllocate(allocationID, 10000 ether); + bytes32 disputeID = createQueryDispute(200 ether); + + vm.prank(arbitrator); + disputeManager.acceptDispute(disputeID, 5000 ether); + + assertEq(graphToken.balanceOf(fisherman), 700 ether, "Fisherman should receive 50% of slashed tokens."); + assertEq(graphToken.balanceOf(indexer), 5000 ether, "Service provider should have 5000 GRT slashed."); + } + + function testAcceptQueryDisputeConflicting() public { + createProvisionAndAllocate(allocationID, 10000 ether); + + bytes32 responseCID1 = keccak256(abi.encodePacked("Response CID 1")); + bytes32 responseCID2 = keccak256(abi.encodePacked("Response CID 2")); + bytes32 subgraphDeploymentId = keccak256(abi.encodePacked("Subgraph Deployment ID")); + + (bytes memory attestationData1, bytes memory attestationData2) = + createConflictingAttestations( + responseCID1, + subgraphDeploymentId, + responseCID2, + subgraphDeploymentId + ); + + vm.prank(fisherman); + (bytes32 disputeID1, bytes32 disputeID2) = + disputeManager.createQueryDisputeConflict(attestationData1, attestationData2); + + vm.prank(arbitrator); + disputeManager.acceptDispute(disputeID1, 5000 ether); + + assertEq(graphToken.balanceOf(fisherman), 500 ether, "Fisherman should receive 50% of slashed tokens."); + assertEq(graphToken.balanceOf(indexer), 5000 ether, "Service provider should have 5000 GRT slashed."); + + (, , , , , IDisputeManager.DisputeStatus status1, ) = disputeManager.disputes(disputeID1); + (, , , , , IDisputeManager.DisputeStatus status2, ) = disputeManager.disputes(disputeID2); + assertTrue(status1 == IDisputeManager.DisputeStatus.Accepted, "Dispute 1 should be accepted."); + assertTrue(status2 == IDisputeManager.DisputeStatus.Rejected, "Dispute 2 should be rejected."); + } + + function test_RevertIf_CallerIsNotArbitrator_AcceptDispute() public { + createProvisionAndAllocate(allocationID, 10000 ether); + + bytes32 disputeID = createIndexingDispute(allocationID, 200 ether); + + // attempt to accept dispute as fisherman + vm.prank(fisherman); + vm.expectRevert(bytes4(keccak256("DisputeManagerNotArbitrator()"))); + disputeManager.acceptDispute(disputeID, 5000 ether); + } + + function test_RevertIf_SlashingOverMaxSlashPercentage() public { + createProvisionAndAllocate(allocationID, 10000 ether); + bytes32 disputeID = createIndexingDispute(allocationID, 200 ether); + + // max slashing percentage is 50% + vm.prank(arbitrator); + bytes memory expectedError = abi.encodeWithSignature("DisputeManagerInvalidSlashAmount(uint256)", 6000 ether); + vm.expectRevert(expectedError); + disputeManager.acceptDispute(disputeID, 6000 ether); + } + + // Cancel dispute + + function testCancelDispute() public { + createProvisionAndAllocate(allocationID, 10000 ether); + bytes32 disputeID = createIndexingDispute(allocationID, 200 ether); + + // skip to end of dispute period + skip(disputePeriod + 1); + + vm.prank(fisherman); + disputeManager.cancelDispute(disputeID); + + assertEq(graphToken.balanceOf(fisherman), 200 ether, "Fisherman should receive their deposit back."); + assertEq(graphToken.balanceOf(indexer), 10000 ether, "There's no slashing to the indexer."); + } + + function testCancelQueryDisputeConflicting() public { + createProvisionAndAllocate(allocationID, 10000 ether); + + bytes32 responseCID1 = keccak256(abi.encodePacked("Response CID 1")); + bytes32 responseCID2 = keccak256(abi.encodePacked("Response CID 2")); + bytes32 subgraphDeploymentId = keccak256(abi.encodePacked("Subgraph Deployment ID")); + + (bytes memory attestationData1, bytes memory attestationData2) = + createConflictingAttestations( + responseCID1, + subgraphDeploymentId, + responseCID2, + subgraphDeploymentId + ); + + vm.prank(fisherman); + (bytes32 disputeID1, bytes32 disputeID2) = + disputeManager.createQueryDisputeConflict(attestationData1, attestationData2); + + // skip to end of dispute period + skip(disputePeriod + 1); + + vm.prank(fisherman); + disputeManager.cancelDispute(disputeID1); + + assertEq(graphToken.balanceOf(indexer), 10000 ether, "There's no slashing to the indexer."); + + (, , , , , IDisputeManager.DisputeStatus status1, ) = disputeManager.disputes(disputeID1); + (, , , , , IDisputeManager.DisputeStatus status2, ) = disputeManager.disputes(disputeID2); + assertTrue(status1 == IDisputeManager.DisputeStatus.Cancelled, "Dispute 1 should be cancelled."); + assertTrue(status2 == IDisputeManager.DisputeStatus.Cancelled, "Dispute 2 should be cancelled."); + } + + function test_RevertIf_CallerIsNotFisherman_CancelDispute() public { + createProvisionAndAllocate(allocationID, 10000 ether); + bytes32 disputeID = createIndexingDispute(allocationID, 200 ether); + + vm.prank(arbitrator); + vm.expectRevert(bytes4(keccak256("DisputeManagerNotFisherman()"))); + disputeManager.cancelDispute(disputeID); + } + + // Draw dispute + + function testDrawDispute() public { + createProvisionAndAllocate(allocationID, 10000 ether); + bytes32 disputeID = createIndexingDispute(allocationID, 200 ether); + + vm.prank(arbitrator); + disputeManager.drawDispute(disputeID); + + assertEq(graphToken.balanceOf(fisherman), 200 ether, "Fisherman should receive their deposit back."); + assertEq(graphToken.balanceOf(indexer), 10000 ether, "There's no slashing to the indexer."); + } + + function testDrawQueryDisputeConflicting() public { + createProvisionAndAllocate(allocationID, 10000 ether); + + bytes32 responseCID1 = keccak256(abi.encodePacked("Response CID 1")); + bytes32 responseCID2 = keccak256(abi.encodePacked("Response CID 2")); + bytes32 subgraphDeploymentId = keccak256(abi.encodePacked("Subgraph Deployment ID")); + + (bytes memory attestationData1, bytes memory attestationData2) = + createConflictingAttestations( + responseCID1, + subgraphDeploymentId, + responseCID2, + subgraphDeploymentId + ); + + vm.prank(fisherman); + (bytes32 disputeID1, bytes32 disputeID2) = + disputeManager.createQueryDisputeConflict(attestationData1, attestationData2); + + vm.prank(arbitrator); + disputeManager.drawDispute(disputeID1); + + assertEq(graphToken.balanceOf(indexer), 10000 ether, "There's no slashing to the indexer."); + + (, , , , , IDisputeManager.DisputeStatus status1, ) = disputeManager.disputes(disputeID1); + (, , , , , IDisputeManager.DisputeStatus status2, ) = disputeManager.disputes(disputeID2); + assertTrue(status1 == IDisputeManager.DisputeStatus.Drawn, "Dispute 1 should be drawn."); + assertTrue(status2 == IDisputeManager.DisputeStatus.Drawn, "Dispute 2 should be drawn."); + } + + function test_RevertIf_CallerIsNotArbitrator_DrawDispute() public { + createProvisionAndAllocate(allocationID, 10000 ether); + bytes32 disputeID = createIndexingDispute(allocationID, 200 ether); + + // attempt to draw dispute as fisherman + vm.prank(fisherman); + vm.expectRevert(bytes4(keccak256("DisputeManagerNotArbitrator()"))); + disputeManager.drawDispute(disputeID); + } +} diff --git a/packages/subgraph-service/test/mocks/MockGRTToken.sol b/packages/subgraph-service/test/mocks/MockGRTToken.sol new file mode 100644 index 000000000..11cf5c0f8 --- /dev/null +++ b/packages/subgraph-service/test/mocks/MockGRTToken.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@graphprotocol/contracts/contracts/token/IGraphToken.sol"; + +contract MockGRTToken is ERC20, IGraphToken { + constructor() ERC20("Graph Token", "GRT") {} + + function burn(uint256 amount) external {} + + function burnFrom(address _from, uint256 amount) external { + _burn(_from, amount); + } + + function mint(address to, uint256 amount) public { + _mint(to, amount); + } + + // -- Mint Admin -- + + function addMinter(address _account) external {} + + function removeMinter(address _account) external {} + + function renounceMinter() external {} + + function isMinter(address _account) external view returns (bool) {} + + // -- Permit -- + + function permit( + address _owner, + address _spender, + uint256 _value, + uint256 _deadline, + uint8 _v, + bytes32 _r, + bytes32 _s + ) external {} + + // -- Allowance -- + + function increaseAllowance(address spender, uint256 addedValue) external returns (bool) {} + function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) {} +} \ No newline at end of file diff --git a/packages/subgraph-service/test/mocks/MockHorizonStaking.sol b/packages/subgraph-service/test/mocks/MockHorizonStaking.sol new file mode 100644 index 000000000..bd67a980c --- /dev/null +++ b/packages/subgraph-service/test/mocks/MockHorizonStaking.sol @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import "forge-std/Test.sol"; + +import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; +import { MockGRTToken } from "./MockGRTToken.sol"; + +contract MockHorizonStaking is IHorizonStaking { + mapping (address verifier => mapping (address serviceProvider => IHorizonStaking.Provision provision)) public _provisions; + MockGRTToken public grtToken; + + constructor(address _grtTokenAddress) { + grtToken = MockGRTToken(_grtTokenAddress); + } + + // whitelist/deny a verifier + function allowVerifier(address verifier, bool allow) external {} + + // deposit stake + function stake(uint256 tokens) external {} + + // create a provision + function provision(uint256 tokens, address verifier, uint32 maxVerifierCut, uint64 thawingPeriod) external { + IHorizonStaking.Provision memory newProvision = IHorizonStaking.Provision({ + serviceProvider: msg.sender, + tokens: tokens, + delegatedTokens: 0, + tokensThawing: 0, + createdAt: uint64(block.timestamp), + verifier: verifier, + maxVerifierCut: maxVerifierCut, + thawingPeriod: thawingPeriod + }); + _provisions[verifier][msg.sender] = newProvision; + } + + function acceptProvision(address serviceProvider) external {} + + // initiate a thawing to remove tokens from a provision + function thaw(bytes32 provisionId, uint256 tokens) external returns (bytes32 thawRequestId) {} + + // moves thawed stake from a provision back into the provider's available stake + function deprovision(bytes32 thawRequestId) external {} + + // moves thawed stake from one provision into another provision + function reprovision(bytes32 thawRequestId, bytes32 provisionId) external {} + + // moves thawed stake back to the owner's account - stake is removed from the protocol + function withdraw(bytes32 thawRequestId) external {} + + // delegate tokens to a provider + function delegate(address serviceProvider, uint256 tokens) external {} + + // undelegate tokens + function undelegate( + address serviceProvider, + uint256 tokens, + bytes32[] calldata provisions + ) external returns (bytes32 thawRequestId) {} + + // slash a service provider + function slash(address serviceProvider, uint256 tokens, uint256 reward, address rewardsDestination) external { + grtToken.mint(rewardsDestination, reward); + grtToken.burnFrom(serviceProvider, tokens); + } + + // set the Service Provider's preferred provisions to be force thawed + function setForceThawProvisions(bytes32[] calldata provisions) external {} + + // total staked tokens to the provider + // `ServiceProvider.tokensStaked + DelegationPool.serviceProvider.tokens` + function getStake(address serviceProvider) external view returns (uint256 tokens) {} + + // staked tokens that are currently not provisioned, aka idle stake + // `getStake(serviceProvider) - ServiceProvider.tokensProvisioned` + function getIdleStake(address serviceProvider) external view returns (uint256 tokens) {} + + // staked tokens the provider can provision before hitting the delegation cap + // `ServiceProvider.tokensStaked * Staking.delegationRatio - Provision.tokensProvisioned` + function getCapacity(address serviceProvider) external view returns (uint256 tokens) {} + + // provisioned tokens that are not being used + // `Provision.tokens - Provision.tokensThawing` + function getTokensAvailable(address serviceProvider, address verifier) external view returns (uint256 tokens) { + return _provisions[verifier][serviceProvider].tokens; + } + + function getServiceProvider(address serviceProvider) external view returns (ServiceProvider memory) {} + + function getProvision(address serviceProvider, address verifier) external view returns (Provision memory) { + return _provisions[verifier][serviceProvider]; + } + + /** + * @notice Check if an operator is authorized for the caller on a specific verifier / data service. + * @param _operator The address to check for auth + * @param _serviceProvider The service provider on behalf of whom they're claiming to act + * @param _verifier The verifier / data service on which they're claiming to act + */ + function isAuthorized(address _operator, address _serviceProvider, address _verifier) external view returns (bool) { + return true; + } + + function getDelegationCut(address serviceProvider, uint8 paymentType) external view returns (uint256 delegationCut) {} + function addToDelegationPool(address serviceProvider, uint256 tokens) external {} + function stakeToProvision(address _serviceProvider, address _verifier, uint256 _tokens) external {} +} \ No newline at end of file diff --git a/packages/subgraph-service/test/mocks/MockRewardsManager.sol b/packages/subgraph-service/test/mocks/MockRewardsManager.sol new file mode 100644 index 000000000..6d15d2b3c --- /dev/null +++ b/packages/subgraph-service/test/mocks/MockRewardsManager.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import "forge-std/Test.sol"; + +import { IRewardsManager } from "@graphprotocol/contracts/contracts/rewards/IRewardsManager.sol"; + +contract MockRewardsManager is IRewardsManager { + // -- Config -- + + function setIssuancePerBlock(uint256 _issuancePerBlock) external {} + + function setMinimumSubgraphSignal(uint256 _minimumSubgraphSignal) external {} + + // -- Denylist -- + + function setSubgraphAvailabilityOracle(address _subgraphAvailabilityOracle) external {} + + function setDenied(bytes32 _subgraphDeploymentID, bool _deny) external {} + + function setDeniedMany(bytes32[] calldata _subgraphDeploymentID, bool[] calldata _deny) external {} + + function isDenied(bytes32 _subgraphDeploymentID) external view returns (bool) {} + + // -- Getters -- + + function getNewRewardsPerSignal() external view returns (uint256) {} + + function getAccRewardsPerSignal() external view returns (uint256) {} + + function getAccRewardsForSubgraph(bytes32 _subgraphDeploymentID) external view returns (uint256) {} + + function getAccRewardsPerAllocatedToken(bytes32 _subgraphDeploymentID) external view returns (uint256, uint256) {} + + function getRewards(address _allocationID) external view returns (uint256) {} + + // -- Updates -- + + function updateAccRewardsPerSignal() external returns (uint256) {} + + function takeRewards(address _allocationID) external returns (uint256) {} + + // -- Hooks -- + + function onSubgraphSignalUpdate(bytes32 _subgraphDeploymentID) external returns (uint256) {} + + function onSubgraphAllocationUpdate(bytes32 _subgraphDeploymentID) external returns (uint256) { + return 0; + } +} \ No newline at end of file diff --git a/packages/subgraph-service/tsconfig.json b/packages/subgraph-service/tsconfig.json new file mode 100644 index 000000000..adee669ce --- /dev/null +++ b/packages/subgraph-service/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + }, + "include": [ + "hardhat.config.ts", + "prettier.config.js", + "scripts/**/*.ts", + "test/**/*.ts", + "eslint.config.js" + ] +} diff --git a/yarn.lock b/yarn.lock index 00e728326..1e14c7d52 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,22 +5,15 @@ __metadata: version: 8 cacheKey: 10c0 -"@0no-co/graphql.web@npm:^1.0.1": - version: 1.0.4 - resolution: "@0no-co/graphql.web@npm:1.0.4" +"@0no-co/graphql.web@npm:^1.0.5": + version: 1.0.7 + resolution: "@0no-co/graphql.web@npm:1.0.7" peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 peerDependenciesMeta: graphql: optional: true - checksum: bf63cb5b017063363c9a9e06dc17532abc1c2da402c7ebcbc7b5ab2a0601ec93b02de93af9e50d9daffb3b747eddcf0b1e5418a46d1182c5b8087b7d7a1768ad - languageName: node - linkType: hard - -"@aashutoshrathi/word-wrap@npm:^1.2.3": - version: 1.2.6 - resolution: "@aashutoshrathi/word-wrap@npm:1.2.6" - checksum: 53c2b231a61a46792b39a0d43bc4f4f776bb4542aa57ee04930676802e5501282c2fc8aac14e4cd1f1120ff8b52616b6ff5ab539ad30aa2277d726444b71619f + checksum: 4744a6c327e0a2d564c8f4720ef08dcece6c3b8373f52208ff29f7086f90e18d211c59cc222c229f1e3241abd1fc6e30377dc1dadac491bbb25706f29dea626a languageName: node linkType: hard @@ -32,12 +25,12 @@ __metadata: linkType: hard "@ampproject/remapping@npm:^2.2.0": - version: 2.2.1 - resolution: "@ampproject/remapping@npm:2.2.1" + version: 2.3.0 + resolution: "@ampproject/remapping@npm:2.3.0" dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.0" - "@jridgewell/trace-mapping": "npm:^0.3.9" - checksum: 92ce5915f8901d8c7cd4f4e6e2fe7b9fd335a29955b400caa52e0e5b12ca3796ada7c2f10e78c9c5b0f9c2539dff0ffea7b19850a56e1487aa083531e1e46d43 + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 81d63cca5443e0f0c72ae18b544cc28c7c0ec2cea46e7cb888bb0e0f411a1191d0d6b7af798d54e30777d8d1488b2ec0732aac2be342d3d7d3ffd271c6f489ed languageName: node linkType: hard @@ -129,12 +122,12 @@ __metadata: linkType: hard "@aws-sdk/types@npm:^3.1.0": - version: 3.515.0 - resolution: "@aws-sdk/types@npm:3.515.0" + version: 3.577.0 + resolution: "@aws-sdk/types@npm:3.577.0" dependencies: - "@smithy/types": "npm:^2.9.1" - tslib: "npm:^2.5.0" - checksum: 47afecf060dec7e7db5073dfec7d6815582f66266cfb31111af4a80fc10bc56bf5c7a5dc096780849efa982a9b097e69b1b3bebf23d82521763b04ae17cc7202 + "@smithy/types": "npm:^3.0.0" + tslib: "npm:^2.6.2" + checksum: ae31757b05c2445f52b3f3268d7e9cbae765cae24f088afb8f967c8e3a268b425794a8e99fab3e0428dc6491ccca99b6c57ab5ca69e2d1cc2878ec85ff9643f7 languageName: node linkType: hard @@ -147,55 +140,55 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/code-frame@npm:7.23.5" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.2": + version: 7.24.2 + resolution: "@babel/code-frame@npm:7.24.2" dependencies: - "@babel/highlight": "npm:^7.23.4" - chalk: "npm:^2.4.2" - checksum: a10e843595ddd9f97faa99917414813c06214f4d9205294013e20c70fbdf4f943760da37dec1d998bf3e6fc20fa2918a47c0e987a7e458663feb7698063ad7c6 + "@babel/highlight": "npm:^7.24.2" + picocolors: "npm:^1.0.0" + checksum: d1d4cba89475ab6aab7a88242e1fd73b15ecb9f30c109b69752956434d10a26a52cbd37727c4eca104b6d45227bd1dfce39a6a6f4a14c9b2f07f871e968cf406 languageName: node linkType: hard "@babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/compat-data@npm:7.23.5" - checksum: 081278ed46131a890ad566a59c61600a5f9557bd8ee5e535890c8548192532ea92590742fd74bd9db83d74c669ef8a04a7e1c85cdea27f960233e3b83c3a957c + version: 7.24.4 + resolution: "@babel/compat-data@npm:7.24.4" + checksum: 9cd8a9cd28a5ca6db5d0e27417d609f95a8762b655e8c9c97fd2de08997043ae99f0139007083c5e607601c6122e8432c85fe391731b19bf26ad458fa0c60dd3 languageName: node linkType: hard "@babel/core@npm:^7.14.0": - version: 7.23.9 - resolution: "@babel/core@npm:7.23.9" + version: 7.24.5 + resolution: "@babel/core@npm:7.24.5" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.23.5" - "@babel/generator": "npm:^7.23.6" + "@babel/code-frame": "npm:^7.24.2" + "@babel/generator": "npm:^7.24.5" "@babel/helper-compilation-targets": "npm:^7.23.6" - "@babel/helper-module-transforms": "npm:^7.23.3" - "@babel/helpers": "npm:^7.23.9" - "@babel/parser": "npm:^7.23.9" - "@babel/template": "npm:^7.23.9" - "@babel/traverse": "npm:^7.23.9" - "@babel/types": "npm:^7.23.9" + "@babel/helper-module-transforms": "npm:^7.24.5" + "@babel/helpers": "npm:^7.24.5" + "@babel/parser": "npm:^7.24.5" + "@babel/template": "npm:^7.24.0" + "@babel/traverse": "npm:^7.24.5" + "@babel/types": "npm:^7.24.5" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 03883300bf1252ab4c9ba5b52f161232dd52873dbe5cde9289bb2bb26e935c42682493acbac9194a59a3b6cbd17f4c4c84030db8d6d482588afe64531532ff9b + checksum: e26ba810a77bc8e21579a12fc36c79a0a60554404dc9447f2d64eb1f26d181c48d3b97d39d9f158e9911ec7162a8280acfaf2b4b210e975f0dd4bd4dbb1ee159 languageName: node linkType: hard -"@babel/generator@npm:^7.14.0, @babel/generator@npm:^7.23.6": - version: 7.23.6 - resolution: "@babel/generator@npm:7.23.6" +"@babel/generator@npm:^7.14.0, @babel/generator@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/generator@npm:7.24.5" dependencies: - "@babel/types": "npm:^7.23.6" - "@jridgewell/gen-mapping": "npm:^0.3.2" - "@jridgewell/trace-mapping": "npm:^0.3.17" + "@babel/types": "npm:^7.24.5" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^2.5.1" - checksum: 53540e905cd10db05d9aee0a5304e36927f455ce66f95d1253bb8a179f286b88fa7062ea0db354c566fe27f8bb96567566084ffd259f8feaae1de5eccc8afbda + checksum: 0d64f880150e7dfb92ceff2b4ac865f36aa1e295120920246492ffd0146562dabf79ba8699af1c8833f8a7954818d4d146b7b02f808df4d6024fb99f98b2f78d languageName: node linkType: hard @@ -208,7 +201,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.20.7, @babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.23.6": +"@babel/helper-compilation-targets@npm:^7.20.7, @babel/helper-compilation-targets@npm:^7.23.6": version: 7.23.6 resolution: "@babel/helper-compilation-targets@npm:7.23.6" dependencies: @@ -222,21 +215,21 @@ __metadata: linkType: hard "@babel/helper-create-class-features-plugin@npm:^7.18.6": - version: 7.23.10 - resolution: "@babel/helper-create-class-features-plugin@npm:7.23.10" + version: 7.24.5 + resolution: "@babel/helper-create-class-features-plugin@npm:7.24.5" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.22.5" "@babel/helper-environment-visitor": "npm:^7.22.20" "@babel/helper-function-name": "npm:^7.23.0" - "@babel/helper-member-expression-to-functions": "npm:^7.23.0" + "@babel/helper-member-expression-to-functions": "npm:^7.24.5" "@babel/helper-optimise-call-expression": "npm:^7.22.5" - "@babel/helper-replace-supers": "npm:^7.22.20" + "@babel/helper-replace-supers": "npm:^7.24.1" "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" - "@babel/helper-split-export-declaration": "npm:^7.22.6" + "@babel/helper-split-export-declaration": "npm:^7.24.5" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: f30437aa16f3585cc3382ea630f24457ef622c22f5e4eccffbc03f6a81efbef0b6714fb5a78baa64c838884ba7e1427e3280d7b27481b9f587bc8fbbed05dd36 + checksum: afc72e8075a249663f8024ef1760de4c0b9252bdde16419ac955fa7e15b8d4096ca1e01f796df4fa8cfdb056708886f60b631ad492242a8e47307974fc305920 languageName: node linkType: hard @@ -266,36 +259,36 @@ __metadata: languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.22.15, @babel/helper-member-expression-to-functions@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/helper-member-expression-to-functions@npm:7.23.0" +"@babel/helper-member-expression-to-functions@npm:^7.23.0, @babel/helper-member-expression-to-functions@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/helper-member-expression-to-functions@npm:7.24.5" dependencies: - "@babel/types": "npm:^7.23.0" - checksum: b810daddf093ffd0802f1429052349ed9ea08ef7d0c56da34ffbcdecbdafac86f95bdea2fe30e0e0e629febc7dd41b56cb5eacc10d1a44336d37b755dac31fa4 + "@babel/types": "npm:^7.24.5" + checksum: a3c0276a1ede8648a0e6fd86ad846cd57421d05eddfa29446b8b5a013db650462022b9ec1e65ea32c747d0542d729c80866830697f94fb12d603e87c51f080a5 languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/helper-module-imports@npm:7.22.15" +"@babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.24.3": + version: 7.24.3 + resolution: "@babel/helper-module-imports@npm:7.24.3" dependencies: - "@babel/types": "npm:^7.22.15" - checksum: 4e0d7fc36d02c1b8c8b3006dfbfeedf7a367d3334a04934255de5128115ea0bafdeb3e5736a2559917f0653e4e437400d54542da0468e08d3cbc86d3bbfa8f30 + "@babel/types": "npm:^7.24.0" + checksum: 052c188adcd100f5e8b6ff0c9643ddaabc58b6700d3bbbc26804141ad68375a9f97d9d173658d373d31853019e65f62610239e3295cdd58e573bdcb2fded188d languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/helper-module-transforms@npm:7.23.3" +"@babel/helper-module-transforms@npm:^7.23.3, @babel/helper-module-transforms@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/helper-module-transforms@npm:7.24.5" dependencies: "@babel/helper-environment-visitor": "npm:^7.22.20" - "@babel/helper-module-imports": "npm:^7.22.15" - "@babel/helper-simple-access": "npm:^7.22.5" - "@babel/helper-split-export-declaration": "npm:^7.22.6" - "@babel/helper-validator-identifier": "npm:^7.22.20" + "@babel/helper-module-imports": "npm:^7.24.3" + "@babel/helper-simple-access": "npm:^7.24.5" + "@babel/helper-split-export-declaration": "npm:^7.24.5" + "@babel/helper-validator-identifier": "npm:^7.24.5" peerDependencies: "@babel/core": ^7.0.0 - checksum: 211e1399d0c4993671e8e5c2b25383f08bee40004ace5404ed4065f0e9258cc85d99c1b82fd456c030ce5cfd4d8f310355b54ef35de9924eabfc3dff1331d946 + checksum: 6e77d72f62b7e87abaea800ea0bccd4d54cde26485750969f5f493c032eb63251eb50c3522cace557781565d51c1d0c4bcc866407d24becfb109c18fb92c978d languageName: node linkType: hard @@ -308,32 +301,32 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0": - version: 7.22.5 - resolution: "@babel/helper-plugin-utils@npm:7.22.5" - checksum: d2c4bfe2fa91058bcdee4f4e57a3f4933aed7af843acfd169cd6179fab8d13c1d636474ecabb2af107dc77462c7e893199aa26632bac1c6d7e025a17cbb9d20d +"@babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0, @babel/helper-plugin-utils@npm:^7.24.5, @babel/helper-plugin-utils@npm:^7.8.0": + version: 7.24.5 + resolution: "@babel/helper-plugin-utils@npm:7.24.5" + checksum: 4ae40094e6a2f183281213344f4df60c66b16b19a2bc38d2bb11810a6dc0a0e7ec638957d0e433ff8b615775b8f3cd1b7edbf59440d1b50e73c389fc22913377 languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-replace-supers@npm:7.22.20" +"@babel/helper-replace-supers@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/helper-replace-supers@npm:7.24.1" dependencies: "@babel/helper-environment-visitor": "npm:^7.22.20" - "@babel/helper-member-expression-to-functions": "npm:^7.22.15" + "@babel/helper-member-expression-to-functions": "npm:^7.23.0" "@babel/helper-optimise-call-expression": "npm:^7.22.5" peerDependencies: "@babel/core": ^7.0.0 - checksum: 6b0858811ad46873817c90c805015d63300e003c5a85c147a17d9845fa2558a02047c3cc1f07767af59014b2dd0fa75b503e5bc36e917f360e9b67bb6f1e79f4 + checksum: d39a3df7892b7c3c0e307fb229646168a9bd35e26a72080c2530729322600e8cff5f738f44a14860a2358faffa741b6a6a0d6749f113387b03ddbfa0ec10e1a0 languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-simple-access@npm:7.22.5" +"@babel/helper-simple-access@npm:^7.22.5, @babel/helper-simple-access@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/helper-simple-access@npm:7.24.5" dependencies: - "@babel/types": "npm:^7.22.5" - checksum: f0cf81a30ba3d09a625fd50e5a9069e575c5b6719234e04ee74247057f8104beca89ed03e9217b6e9b0493434cedc18c5ecca4cea6244990836f1f893e140369 + "@babel/types": "npm:^7.24.5" + checksum: d96a0ab790a400f6c2dcbd9457b9ca74b9ba6d0f67ff9cd5bcc73792c8fbbd0847322a0dddbd8987dd98610ee1637c680938c7d83d3ffce7d06d7519d823d996 languageName: node linkType: hard @@ -346,26 +339,26 @@ __metadata: languageName: node linkType: hard -"@babel/helper-split-export-declaration@npm:^7.22.6": - version: 7.22.6 - resolution: "@babel/helper-split-export-declaration@npm:7.22.6" +"@babel/helper-split-export-declaration@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/helper-split-export-declaration@npm:7.24.5" dependencies: - "@babel/types": "npm:^7.22.5" - checksum: d83e4b623eaa9622c267d3c83583b72f3aac567dc393dda18e559d79187961cb29ae9c57b2664137fc3d19508370b12ec6a81d28af73a50e0846819cb21c6e44 + "@babel/types": "npm:^7.24.5" + checksum: d7a812d67d031a348f3fb0e6263ce2dbe6038f81536ba7fb16db385383bcd6542b71833194303bf6d3d0e4f7b6b584c9c8fae8772122e2ce68fc9bdf07f4135d languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/helper-string-parser@npm:7.23.4" - checksum: f348d5637ad70b6b54b026d6544bd9040f78d24e7ec245a0fc42293968181f6ae9879c22d89744730d246ce8ec53588f716f102addd4df8bbc79b73ea10004ac +"@babel/helper-string-parser@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/helper-string-parser@npm:7.24.1" + checksum: 2f9bfcf8d2f9f083785df0501dbab92770111ece2f90d120352fda6dd2a7d47db11b807d111e6f32aa1ba6d763fe2dc6603d153068d672a5d0ad33ca802632b2 languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-validator-identifier@npm:7.22.20" - checksum: dcad63db345fb110e032de46c3688384b0008a42a4845180ce7cd62b1a9c0507a1bed727c4d1060ed1a03ae57b4d918570259f81724aaac1a5b776056f37504e +"@babel/helper-validator-identifier@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/helper-validator-identifier@npm:7.24.5" + checksum: 05f957229d89ce95a137d04e27f7d0680d84ae48b6ad830e399db0779341f7d30290f863a93351b4b3bde2166737f73a286ea42856bb07c8ddaa95600d38645c languageName: node linkType: hard @@ -376,34 +369,35 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/helpers@npm:7.23.9" +"@babel/helpers@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/helpers@npm:7.24.5" dependencies: - "@babel/template": "npm:^7.23.9" - "@babel/traverse": "npm:^7.23.9" - "@babel/types": "npm:^7.23.9" - checksum: f69fd0aca96a6fb8bd6dd044cd8a5c0f1851072d4ce23355345b9493c4032e76d1217f86b70df795e127553cf7f3fcd1587ede9d1b03b95e8b62681ca2165b87 + "@babel/template": "npm:^7.24.0" + "@babel/traverse": "npm:^7.24.5" + "@babel/types": "npm:^7.24.5" + checksum: 0630b0223c3a9a34027ddc05b3bac54d68d5957f84e92d2d4814b00448a76e12f9188f9c85cfce2011696d82a8ffcbd8189da097c0af0181d32eb27eca34185e languageName: node linkType: hard -"@babel/highlight@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/highlight@npm:7.23.4" +"@babel/highlight@npm:^7.24.2": + version: 7.24.5 + resolution: "@babel/highlight@npm:7.24.5" dependencies: - "@babel/helper-validator-identifier": "npm:^7.22.20" + "@babel/helper-validator-identifier": "npm:^7.24.5" chalk: "npm:^2.4.2" js-tokens: "npm:^4.0.0" - checksum: fbff9fcb2f5539289c3c097d130e852afd10d89a3a08ac0b5ebebbc055cc84a4bcc3dcfed463d488cde12dd0902ef1858279e31d7349b2e8cee43913744bda33 + picocolors: "npm:^1.0.0" + checksum: e98047d3ad24608bfa596d000c861a2cc875af897427f2833b91a4e0d4cead07301a7ec15fa26093dcd61e036e2eed2db338ae54f93016fe0dc785fadc4159db languageName: node linkType: hard -"@babel/parser@npm:^7.14.0, @babel/parser@npm:^7.16.8, @babel/parser@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/parser@npm:7.23.9" +"@babel/parser@npm:^7.14.0, @babel/parser@npm:^7.16.8, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/parser@npm:7.24.5" bin: parser: ./bin/babel-parser.js - checksum: 7df97386431366d4810538db4b9ec538f4377096f720c0591c7587a16f6810e62747e9fbbfa1ff99257fd4330035e4fb1b5b77c7bd3b97ce0d2e3780a6618975 + checksum: 8333a6ad5328bad34fa0e12bcee147c3345ea9a438c0909e7c68c6cfbea43c464834ffd7eabd1cbc1c62df0a558e22ffade9f5b29440833ba7b33d96a71f88c0 languageName: node linkType: hard @@ -445,36 +439,36 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-flow@npm:^7.0.0, @babel/plugin-syntax-flow@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-syntax-flow@npm:7.23.3" +"@babel/plugin-syntax-flow@npm:^7.0.0, @babel/plugin-syntax-flow@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-flow@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8a5e1e8b6a3728a2c8fe6d70c09a43642e737d9c0485e1b041cd3a6021ef05376ec3c9137be3b118c622ba09b5770d26fdc525473f8d06d4ab9e46de2783dd0a + checksum: 618de04360a96111408abdaafaba2efbaef0d90faad029d50e0281eaad5d7c7bd2ce4420bbac0ee27ad84c2b7bbc3e48f782064f81ed5bc40c398637991004c7 languageName: node linkType: hard "@babel/plugin-syntax-import-assertions@npm:^7.20.0": - version: 7.23.3 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7db8b59f75667bada2293353bb66b9d5651a673b22c72f47da9f5c46e719142481601b745f9822212fd7522f92e26e8576af37116f85dae1b5e5967f80d0faab + checksum: 72f0340d73e037f0702c61670054e0af66ece7282c5c2f4ba8de059390fee502de282defdf15959cd9f71aa18dc5c5e4e7a0fde317799a0600c6c4e0a656d82b languageName: node linkType: hard "@babel/plugin-syntax-jsx@npm:^7.0.0, @babel/plugin-syntax-jsx@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-syntax-jsx@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-syntax-jsx@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 563bb7599b868773f1c7c1d441ecc9bc53aeb7832775da36752c926fc402a1fa5421505b39e724f71eb217c13e4b93117e081cac39723b0e11dac4c897f33c3e + checksum: 6cec76fbfe6ca81c9345c2904d8d9a8a0df222f9269f0962ed6eb2eb8f3f10c2f15e993d1ef09dbaf97726bf1792b5851cf5bd9a769f966a19448df6be95d19a languageName: node linkType: hard @@ -490,193 +484,193 @@ __metadata: linkType: hard "@babel/plugin-transform-arrow-functions@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b128315c058f5728d29b0b78723659b11de88247ea4d0388f0b935cddf60a80c40b9067acf45cbbe055bd796928faef152a09d9e4a0695465aca4394d9f109ca + checksum: f44bfacf087dc21b422bab99f4e9344ee7b695b05c947dacae66de05c723ab9d91800be7edc1fa016185e8c819f3aca2b4a5f66d8a4d1e47d9bad80b8fa55b8e languageName: node linkType: hard "@babel/plugin-transform-block-scoped-functions@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 82c12a11277528184a979163de7189ceb00129f60dd930b0d5313454310bf71205f302fb2bf0430247161c8a22aaa9fb9eec1459f9f7468206422c191978fd59 + checksum: 6fbaa85f5204f34845dfc0bebf62fdd3ac5a286241c85651e59d426001e7a1785ac501f154e093e0b8ee49e1f51e3f8b06575a5ae8d4a9406d43e4816bf18c37 languageName: node linkType: hard "@babel/plugin-transform-block-scoping@npm:^7.0.0": - version: 7.23.4 - resolution: "@babel/plugin-transform-block-scoping@npm:7.23.4" + version: 7.24.5 + resolution: "@babel/plugin-transform-block-scoping@npm:7.24.5" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 83006804dddf980ab1bcd6d67bc381e24b58c776507c34f990468f820d0da71dba3697355ca4856532fa2eeb2a1e3e73c780f03760b5507a511cbedb0308e276 + checksum: 85997fc8179b7d26e8af30865aeb91789f3bc1f0cd5643ed25f25891ff9c071460ec1220599b19070b424a3b902422f682e9b02e515872540173eae2e25f760c languageName: node linkType: hard "@babel/plugin-transform-classes@npm:^7.0.0": - version: 7.23.8 - resolution: "@babel/plugin-transform-classes@npm:7.23.8" + version: 7.24.5 + resolution: "@babel/plugin-transform-classes@npm:7.24.5" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.22.5" "@babel/helper-compilation-targets": "npm:^7.23.6" "@babel/helper-environment-visitor": "npm:^7.22.20" "@babel/helper-function-name": "npm:^7.23.0" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-replace-supers": "npm:^7.22.20" - "@babel/helper-split-export-declaration": "npm:^7.22.6" + "@babel/helper-plugin-utils": "npm:^7.24.5" + "@babel/helper-replace-supers": "npm:^7.24.1" + "@babel/helper-split-export-declaration": "npm:^7.24.5" globals: "npm:^11.1.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 227ac5166501e04d9e7fbd5eda6869b084ffa4af6830ac12544ac6ea14953ca00eb1762b0df9349c0f6c8d2a799385910f558066cd0fb85b9ca437b1131a6043 + checksum: 4affcbb7cb01fa4764c7a4b534c30fd24a4b68e680a2d6e242dd7ca8726490f0f1426c44797deff84a38a162e0629718900c68d28daffe2b12adf5b4194156a7 languageName: node linkType: hard "@babel/plugin-transform-computed-properties@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-computed-properties@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-computed-properties@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/template": "npm:^7.22.15" + "@babel/helper-plugin-utils": "npm:^7.24.0" + "@babel/template": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3ca8a006f8e652b58c21ecb84df1d01a73f0a96b1d216fd09a890b235dd90cb966b152b603b88f7e850ae238644b1636ce5c30b7c029c0934b43383932372e4a + checksum: 8292c508b656b7722e2c2ca0f6f31339852e3ed2b9b80f6e068a4010e961b431ca109ecd467fc906283f4b1574c1e7b1cb68d35a4dea12079d386c15ff7e0eac languageName: node linkType: hard "@babel/plugin-transform-destructuring@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-destructuring@npm:7.23.3" + version: 7.24.5 + resolution: "@babel/plugin-transform-destructuring@npm:7.24.5" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 717e9a62c1b0c93c507f87b4eaf839ec08d3c3147f14d74ae240d8749488d9762a8b3950132be620a069bde70f4b3e4ee9867b226c973fcc40f3cdec975cde71 + checksum: 6a37953a95f04b335bf3e2118fb93f50dd9593c658d1b2f8918a380a2ee30f1b420139eccf7ec3873c86a8208527895fcf6b7e21c0e734a6ad6e5d5042eace4d languageName: node linkType: hard "@babel/plugin-transform-flow-strip-types@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-flow-strip-types@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-flow-strip-types@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-flow": "npm:^7.23.3" + "@babel/helper-plugin-utils": "npm:^7.24.0" + "@babel/plugin-syntax-flow": "npm:^7.24.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 9ab627f9668fc1f95564b26bffd6706f86205960d9ccc168236752fbef65dbe10aa0ce74faae12f48bb3b72ec7f38ef2a78b4874c222c1e85754e981639f3b33 + checksum: e6aa9cbad0441867598d390d4df65bc8c6b797574673e4eedbdae0cc528e81e00f4b2cd38f7d138b0f04bcdd2540384a9812d5d76af5abfa06aee1c7fc20ca58 languageName: node linkType: hard "@babel/plugin-transform-for-of@npm:^7.0.0": - version: 7.23.6 - resolution: "@babel/plugin-transform-for-of@npm:7.23.6" + version: 7.24.1 + resolution: "@babel/plugin-transform-for-of@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 46681b6ab10f3ca2d961f50d4096b62ab5d551e1adad84e64be1ee23e72eb2f26a1e30e617e853c74f1349fffe4af68d33921a128543b6f24b6d46c09a3e2aec + checksum: e4bc92b1f334246e62d4bde079938df940794db564742034f6597f2e38bd426e11ae8c5670448e15dd6e45c462f2a9ab3fa87259bddf7c08553ffd9457fc2b2c languageName: node linkType: hard "@babel/plugin-transform-function-name@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-function-name@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-function-name@npm:7.24.1" dependencies: - "@babel/helper-compilation-targets": "npm:^7.22.15" + "@babel/helper-compilation-targets": "npm:^7.23.6" "@babel/helper-function-name": "npm:^7.23.0" - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 89cb9747802118048115cf92a8f310752f02030549b26f008904990cbdc86c3d4a68e07ca3b5c46de8a46ed4df2cb576ac222c74c56de67253d2a3ddc2956083 + checksum: 65c1735ec3b5e43db9b5aebf3c16171c04b3050c92396b9e22dda0d2aaf51f43fdcf147f70a40678fd9a4ee2272a5acec4826e9c21bcf968762f4c184897ad75 languageName: node linkType: hard "@babel/plugin-transform-literals@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-literals@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-literals@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8292106b106201464c2bfdd5c014fe6a9ca1c0256eb0a8031deb20081e21906fe68b156186f77d993c23eeab6d8d6f5f66e8895eec7ed97ce6de5dbcafbcd7f4 + checksum: a27cc7d565ee57b5a2bf136fa889c5c2f5988545ae7b3b2c83a7afe5dd37dfac80dca88b1c633c65851ce6af7d2095c04c01228657ce0198f918e64b5ccd01fa languageName: node linkType: hard "@babel/plugin-transform-member-expression-literals@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 687f24f3ec60b627fef6e87b9e2770df77f76727b9d5f54fa4c84a495bb24eb4a20f1a6240fa22d339d45aac5eaeb1b39882e941bfd00cf498f9c53478d1ec88 + checksum: 2af731d02aa4c757ef80c46df42264128cbe45bfd15e1812d1a595265b690a44ad036041c406a73411733540e1c4256d8174705ae6b8cfaf757fc175613993fd languageName: node linkType: hard "@babel/plugin-transform-modules-commonjs@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.1" dependencies: "@babel/helper-module-transforms": "npm:^7.23.3" - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" "@babel/helper-simple-access": "npm:^7.22.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5c8840c5c9ecba39367ae17c973ed13dbc43234147b77ae780eec65010e2a9993c5d717721b23e8179f7cf49decdd325c509b241d69cfbf92aa647a1d8d5a37d + checksum: efb3ea2047604a7eb44a9289311ebb29842fe6510ff8b66a77a60440448c65e1312a60dc48191ed98246bdbd163b5b6f3348a0669bcc0e3809e69c7c776b20fa languageName: node linkType: hard "@babel/plugin-transform-object-super@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-object-super@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-object-super@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-replace-supers": "npm:^7.22.20" + "@babel/helper-plugin-utils": "npm:^7.24.0" + "@babel/helper-replace-supers": "npm:^7.24.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a6856fd8c0afbe5b3318c344d4d201d009f4051e2f6ff6237ff2660593e93c5997a58772b13d639077c3e29ced3440247b29c496cd77b13af1e7559a70009775 + checksum: d30e6b9e59a707efd7ed524fc0a8deeea046011a6990250f2e9280516683138e2d13d9c52daf41d78407bdab0378aef7478326f2a15305b773d851cb6e106157 languageName: node linkType: hard "@babel/plugin-transform-parameters@npm:^7.0.0, @babel/plugin-transform-parameters@npm:^7.20.7": - version: 7.23.3 - resolution: "@babel/plugin-transform-parameters@npm:7.23.3" + version: 7.24.5 + resolution: "@babel/plugin-transform-parameters@npm:7.24.5" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a8d4cbe0f6ba68d158f5b4215c63004fc37a1fdc539036eb388a9792017c8496ea970a1932ccb929308f61e53dc56676ed01d8df6f42bc0a85c7fd5ba82482b7 + checksum: e08b8c46a24b1b21dde7783cb0aeb56ffe9ef6d6f1795649ce76273657158d3bfa5370c6594200ed7d371983b599c8e194b76108dffed9ab5746fe630ef2e8f5 languageName: node linkType: hard "@babel/plugin-transform-property-literals@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-property-literals@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-property-literals@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b2549f23f90cf276c2e3058c2225c3711c2ad1c417e336d3391199445a9776dd791b83be47b2b9a7ae374b40652d74b822387e31fa5267a37bf49c122e1a9747 + checksum: 3bf3e01f7bb8215a8b6d0081b6f86fea23e3a4543b619e059a264ede028bc58cdfb0acb2c43271271915a74917effa547bc280ac636a9901fa9f2fb45623f87e languageName: node linkType: hard "@babel/plugin-transform-react-display-name@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-react-display-name@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-react-display-name@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3aed142af7bd1aed1df2bdad91ed33ba1cdd5c3c67ce6eafba821ff72f129162a197ffb55f1eb1775af276abd5545934489a8257fef6c6665ddf253a4f39a939 + checksum: adf1a3cb0df8134533a558a9072a67e34127fd489dfe431c3348a86dd41f3e74861d5d5134bbb68f61a9cdb3f7e79b2acea1346be94ce4d3328a64e5a9e09be1 languageName: node linkType: hard @@ -696,85 +690,85 @@ __metadata: linkType: hard "@babel/plugin-transform-shorthand-properties@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c423c66fec0b6503f50561741754c84366ef9e9818442c8881fbaa90cc363fd137084b9431cdc00ed2f1fd8c8a1a5982c4a7e1f2af3769db4caf2ac7ea55d4f0 + checksum: 8273347621183aada3cf1f3019d8d5f29467ba13a75b72cb405bc7f23b7e05fd85f4edb1e4d9f0103153dddb61826a42dc24d466480d707f8932c1923a4c25fa languageName: node linkType: hard "@babel/plugin-transform-spread@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-spread@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-spread@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a348e4ae47e4ceeceb760506ec7bf835ccc18a2cf70ec74ebfbe41bc172fa2412b05b7d1b86836f8aee375e41a04ff20486074778d0e2d19d668b33dc52e9dbb + checksum: 50a0302e344546d57e5c9f4dea575f88e084352eeac4e9a3e238c41739eef2df1daf4a7ebbb3ccb7acd3447f6a5ce9938405f98bf5f5583deceb8257f5a673c9 languageName: node linkType: hard "@babel/plugin-transform-template-literals@npm:^7.0.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-template-literals@npm:7.23.3" + version: 7.24.1 + resolution: "@babel/plugin-transform-template-literals@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 9b5f43788b9ffcb8f2b445a16b1aa40fcf23cb0446a4649445f098ec6b4cb751f243a535da623d59fefe48f4c40552f5621187a61811779076bab26863e3373d + checksum: f73bcda5488eb81c6e7a876498d9e6b72be32fca5a4d9db9053491a2d1300cd27b889b463fd2558f3cd5826a85ed00f61d81b234aa55cb5a0abf1b6fa1bd5026 languageName: node linkType: hard "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.5.5": - version: 7.23.9 - resolution: "@babel/runtime@npm:7.23.9" + version: 7.24.5 + resolution: "@babel/runtime@npm:7.24.5" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: e71205fdd7082b2656512cc98e647d9ea7e222e4fe5c36e9e5adc026446fcc3ba7b3cdff8b0b694a0b78bb85db83e7b1e3d4c56ef90726682b74f13249cf952d + checksum: 05730e43e8ba6550eae9fd4fb5e7d9d3cb91140379425abcb2a1ff9cebad518a280d82c4c4b0f57ada26a863106ac54a748d90c775790c0e2cd0ddd85ccdf346 languageName: node linkType: hard -"@babel/template@npm:^7.22.15, @babel/template@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/template@npm:7.23.9" +"@babel/template@npm:^7.22.15, @babel/template@npm:^7.24.0": + version: 7.24.0 + resolution: "@babel/template@npm:7.24.0" dependencies: "@babel/code-frame": "npm:^7.23.5" - "@babel/parser": "npm:^7.23.9" - "@babel/types": "npm:^7.23.9" - checksum: 0e8b60119433787742bc08ae762bbd8d6755611c4cabbcb7627b292ec901a55af65d93d1c88572326069efb64136ef151ec91ffb74b2df7689bbab237030833a + "@babel/parser": "npm:^7.24.0" + "@babel/types": "npm:^7.24.0" + checksum: 9d3dd8d22fe1c36bc3bdef6118af1f4b030aaf6d7d2619f5da203efa818a2185d717523486c111de8d99a8649ddf4bbf6b2a7a64962d8411cf6a8fa89f010e54 languageName: node linkType: hard -"@babel/traverse@npm:^7.14.0, @babel/traverse@npm:^7.16.8, @babel/traverse@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/traverse@npm:7.23.9" +"@babel/traverse@npm:^7.14.0, @babel/traverse@npm:^7.16.8, @babel/traverse@npm:^7.24.5": + version: 7.24.5 + resolution: "@babel/traverse@npm:7.24.5" dependencies: - "@babel/code-frame": "npm:^7.23.5" - "@babel/generator": "npm:^7.23.6" + "@babel/code-frame": "npm:^7.24.2" + "@babel/generator": "npm:^7.24.5" "@babel/helper-environment-visitor": "npm:^7.22.20" "@babel/helper-function-name": "npm:^7.23.0" "@babel/helper-hoist-variables": "npm:^7.22.5" - "@babel/helper-split-export-declaration": "npm:^7.22.6" - "@babel/parser": "npm:^7.23.9" - "@babel/types": "npm:^7.23.9" + "@babel/helper-split-export-declaration": "npm:^7.24.5" + "@babel/parser": "npm:^7.24.5" + "@babel/types": "npm:^7.24.5" debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: d1615d1d02f04d47111a7ea4446a1a6275668ca39082f31d51f08380de9502e19862be434eaa34b022ce9a17dbb8f9e2b73a746c654d9575f3a680a7ffdf5630 + checksum: 3f22534bc2b2ed9208e55ef48af3b32939032b23cb9dc4037447cb108640df70bbb0b9fea86e9c58648949fdc2cb14e89aa79ffa3c62a5dd43459a52fe8c01d1 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.16.8, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.23.6, @babel/types@npm:^7.23.9, @babel/types@npm:^7.8.3": - version: 7.23.9 - resolution: "@babel/types@npm:7.23.9" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.16.8, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.0, @babel/types@npm:^7.24.5, @babel/types@npm:^7.8.3": + version: 7.24.5 + resolution: "@babel/types@npm:7.24.5" dependencies: - "@babel/helper-string-parser": "npm:^7.23.4" - "@babel/helper-validator-identifier": "npm:^7.22.20" + "@babel/helper-string-parser": "npm:^7.24.1" + "@babel/helper-validator-identifier": "npm:^7.24.5" to-fast-properties: "npm:^2.0.0" - checksum: edc7bb180ce7e4d2aea10c6972fb10474341ac39ba8fdc4a27ffb328368dfdfbf40fca18e441bbe7c483774500d5c05e222cec276c242e952853dcaf4eb884f7 + checksum: e1284eb046c5e0451b80220d1200e2327e0a8544a2fe45bb62c952e5fdef7099c603d2336b17b6eac3cc046b7a69bfbce67fe56e1c0ea48cd37c65cb88638f2a languageName: node linkType: hard @@ -824,9 +818,9 @@ __metadata: languageName: node linkType: hard -"@changesets/apply-release-plan@npm:^7.0.0": - version: 7.0.0 - resolution: "@changesets/apply-release-plan@npm:7.0.0" +"@changesets/apply-release-plan@npm:^7.0.1": + version: 7.0.1 + resolution: "@changesets/apply-release-plan@npm:7.0.1" dependencies: "@babel/runtime": "npm:^7.20.1" "@changesets/config": "npm:^3.0.0" @@ -841,7 +835,7 @@ __metadata: prettier: "npm:^2.7.1" resolve-from: "npm:^5.0.0" semver: "npm:^7.5.3" - checksum: 5f4c2d6b500d0ade51b31bc03b2475dd0bcaf3a31995f2ad953a6c3b05d3fb588568470bad3093d052f351ecdc6f8e2124d38941210361692b81bf62afbba7d7 + checksum: ca41f84a22a1fd25af4b195956afd393000139581a84528b6d21871e4ce417abf884ad2ef8a8ed7abb49031fed7cbb69226a158df36050aa70ed295636a42369 languageName: node linkType: hard @@ -869,11 +863,11 @@ __metadata: linkType: hard "@changesets/cli@npm:^2.27.1": - version: 2.27.1 - resolution: "@changesets/cli@npm:2.27.1" + version: 2.27.2 + resolution: "@changesets/cli@npm:2.27.2" dependencies: "@babel/runtime": "npm:^7.20.1" - "@changesets/apply-release-plan": "npm:^7.0.0" + "@changesets/apply-release-plan": "npm:^7.0.1" "@changesets/assemble-release-plan": "npm:^6.0.0" "@changesets/changelog-git": "npm:^0.2.0" "@changesets/config": "npm:^3.0.0" @@ -885,7 +879,7 @@ __metadata: "@changesets/pre": "npm:^2.0.0" "@changesets/read": "npm:^0.6.0" "@changesets/types": "npm:^6.0.0" - "@changesets/write": "npm:^0.3.0" + "@changesets/write": "npm:^0.3.1" "@manypkg/get-packages": "npm:^1.1.3" "@types/semver": "npm:^7.5.0" ansi-colors: "npm:^4.1.3" @@ -906,7 +900,7 @@ __metadata: tty-table: "npm:^4.1.5" bin: changeset: bin.js - checksum: c7adc35f22983be9b0f6a8e4c3bc7013208ddf341b637530b88267e78469f0b7af9e36b138bea9f2fe29bb7b44294cd08aa0301a5cba0c6a928824f11d024e04 + checksum: c2fd356b235bb27de0267389af38bca356d1c61892d0d3e114cec2e628aa6e7aadfe1828d9024b9c7d8005c3b968760ab4d781d4ce3a04309d5263d710341bec languageName: node linkType: hard @@ -1046,16 +1040,16 @@ __metadata: languageName: node linkType: hard -"@changesets/write@npm:^0.3.0": - version: 0.3.0 - resolution: "@changesets/write@npm:0.3.0" +"@changesets/write@npm:^0.3.1": + version: 0.3.1 + resolution: "@changesets/write@npm:0.3.1" dependencies: "@babel/runtime": "npm:^7.20.1" "@changesets/types": "npm:^6.0.0" fs-extra: "npm:^7.0.1" human-id: "npm:^1.0.2" prettier: "npm:^2.7.1" - checksum: 537f419d854946cce5694696b6a48ffee0ea1f7b5c97c5246836931886db18153c42a7dea1e74b0e8bf571fcded527e2f443ab362fdb1e4129bd95a61b2d0fe5 + checksum: 6c6ef4c12f93ae10706eea96fae73ab05fddeaa1870102681106a29e4e92c37be9643f214c56187141ab5cf3a4cccb4e8a59212d0fa6c7c26083c5d613878c9a languageName: node linkType: hard @@ -1122,12 +1116,12 @@ __metadata: linkType: hard "@commitlint/config-conventional@npm:^18.4.3": - version: 18.6.2 - resolution: "@commitlint/config-conventional@npm:18.6.2" + version: 18.6.3 + resolution: "@commitlint/config-conventional@npm:18.6.3" dependencies: "@commitlint/types": "npm:^18.6.1" conventional-changelog-conventionalcommits: "npm:^7.0.2" - checksum: ff4ccff3c2992c209703eb7d08f8e1c6d8471d4f0778f384dc0fef490cc023227f1b662f7136a301804d650518e00c7f859aa3eb1a156448f837b2a50206430d + checksum: 047f84598f80f7f793bdb0ffc9cf9059c199da6c5bc12ab87084fa933faee08c9290e3331f6f0d7e07c4f0ffb0b5c678e5036025aeabb8e74af296b9146c6354 languageName: node linkType: hard @@ -1476,12 +1470,10 @@ __metadata: linkType: hard "@defi-wonderland/smock@npm:^2.0.7": - version: 2.3.5 - resolution: "@defi-wonderland/smock@npm:2.3.5" + version: 2.4.0 + resolution: "@defi-wonderland/smock@npm:2.4.0" dependencies: - "@nomicfoundation/ethereumjs-evm": "npm:^1.0.0-rc.3" - "@nomicfoundation/ethereumjs-util": "npm:^8.0.0-rc.3" - "@nomicfoundation/ethereumjs-vm": "npm:^6.0.0-rc.3" + "@nomicfoundation/ethereumjs-util": "npm:^9.0.4" diff: "npm:^5.0.0" lodash.isequal: "npm:^4.5.0" lodash.isequalwith: "npm:^4.4.0" @@ -1493,8 +1485,8 @@ __metadata: "@ethersproject/abstract-signer": ^5 "@nomiclabs/hardhat-ethers": ^2 ethers: ^5 - hardhat: ^2 - checksum: c831563fe6607841d69f5936011398a492f760f52f9cb17626b2949ff3ef7668729acc4a3a944f739417b2d1b99bc6c83580f236189f27431224021c66ac1821 + hardhat: ^2.21.0 + checksum: 166dfb4b9e00c29466f0cf27dc2009e8139f9e6a31e42b74d55f5e6ac690d5f7137ae5acf1b8ff846ae46915608f6de921f2bef47a485088e57d951cac72b054 languageName: node linkType: hard @@ -1575,7 +1567,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": version: 4.10.0 resolution: "@eslint-community/regexpp@npm:4.10.0" checksum: c5f60ef1f1ea7649fa7af0e80a5a79f64b55a8a8fa5086de4727eb4c86c652aedee407a9c143b8995d2c0b2d75c1222bec9ba5d73dbfc1f314550554f0979ef4 @@ -1599,13 +1591,6 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.56.0": - version: 8.56.0 - resolution: "@eslint/js@npm:8.56.0" - checksum: 60b3a1cf240e2479cec9742424224465dc50e46d781da1b7f5ef240501b2d1202c225bd456207faac4b34a64f4765833345bc4ddffd00395e1db40fa8c426f5a - languageName: node - linkType: hard - "@eslint/js@npm:8.57.0": version: 8.57.0 resolution: "@eslint/js@npm:8.57.0" @@ -2617,9 +2602,9 @@ __metadata: linkType: hard "@fastify/busboy@npm:^2.0.0": - version: 2.1.0 - resolution: "@fastify/busboy@npm:2.1.0" - checksum: 7bb641080aac7cf01d88749ad331af10ba9ec3713ec07cabbe833908c75df21bd56249bb6173bdec07f5a41896b21e3689316f86684c06635da45f91ff4565a2 + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 6f8027a8cba7f8f7b736718b013f5a38c0476eea67034c94a0d3c375e2b114366ad4419e6a6fa7ffc2ef9c6d3e0435d76dd584a7a1cbac23962fda7650b579e3 languageName: node linkType: hard @@ -3009,6 +2994,45 @@ __metadata: languageName: unknown linkType: soft +"@graphprotocol/subgraph-service@workspace:packages/subgraph-service": + version: 0.0.0-use.local + resolution: "@graphprotocol/subgraph-service@workspace:packages/subgraph-service" + dependencies: + "@graphprotocol/contracts": "workspace:^7.0.0" + "@nomicfoundation/hardhat-chai-matchers": "npm:^2.0.0" + "@nomicfoundation/hardhat-ethers": "npm:^3.0.0" + "@nomicfoundation/hardhat-foundry": "npm:^1.1.1" + "@nomicfoundation/hardhat-network-helpers": "npm:^1.0.0" + "@nomicfoundation/hardhat-toolbox": "npm:^4.0.0" + "@nomicfoundation/hardhat-verify": "npm:^2.0.0" + "@openzeppelin/contracts": "npm:^5.0.2" + "@typechain/ethers-v6": "npm:^0.5.0" + "@typechain/hardhat": "npm:^9.0.0" + "@types/chai": "npm:^4.2.0" + "@types/mocha": "npm:>=9.1.0" + "@types/node": "npm:>=16.0.0" + chai: "npm:^4.2.0" + eslint: "npm:^8.56.0" + eslint-graph-config: "workspace:^0.0.1" + ethers: "npm:^6.4.0" + hardhat: "npm:^2.20.1" + hardhat-contract-sizer: "npm:^2.10.0" + hardhat-gas-reporter: "npm:^1.0.8" + hardhat-storage-layout: "npm:^0.1.7" + lint-staged: "npm:^15.2.2" + prettier: "npm:^3.2.5" + prettier-plugin-solidity: "npm:^1.3.1" + solhint: "npm:^4.5.4" + solhint-graph-config: "workspace:^0.0.1" + solhint-plugin-graph: "file:node_modules/solhint-graph-config/plugin" + solidity-coverage: "npm:^0.8.0" + solidity-docgen: "npm:^0.6.0-beta.36" + ts-node: "npm:>=8.0.0" + typechain: "npm:^8.3.0" + typescript: "npm:^5.3.3" + languageName: unknown + linkType: soft + "@graphprotocol/token-distribution@workspace:packages/token-distribution": version: 0.0.0-use.local resolution: "@graphprotocol/token-distribution@workspace:packages/token-distribution" @@ -3921,7 +3945,7 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.13, @humanwhocodes/config-array@npm:^0.11.14": +"@humanwhocodes/config-array@npm:^0.11.14": version: 0.11.14 resolution: "@humanwhocodes/config-array@npm:0.11.14" dependencies: @@ -3940,9 +3964,9 @@ __metadata: linkType: hard "@humanwhocodes/object-schema@npm:^2.0.2": - version: 2.0.2 - resolution: "@humanwhocodes/object-schema@npm:2.0.2" - checksum: 6fd83dc320231d71c4541d0244051df61f301817e9f9da9fd4cb7e44ec8aacbde5958c1665b0c419401ab935114fdf532a6ad5d4e7294b1af2f347dd91a6983f + version: 2.0.3 + resolution: "@humanwhocodes/object-schema@npm:2.0.3" + checksum: 80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c languageName: node linkType: hard @@ -3960,14 +3984,14 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.2": - version: 0.3.3 - resolution: "@jridgewell/gen-mapping@npm:0.3.3" +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" dependencies: - "@jridgewell/set-array": "npm:^1.0.1" + "@jridgewell/set-array": "npm:^1.2.1" "@jridgewell/sourcemap-codec": "npm:^1.4.10" - "@jridgewell/trace-mapping": "npm:^0.3.9" - checksum: 376fc11cf5a967318ba3ddd9d8e91be528eab6af66810a713c49b0c3f8dc67e9949452c51c38ab1b19aa618fb5e8594da5a249977e26b1e7fea1ee5a1fcacc74 + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb languageName: node linkType: hard @@ -3978,10 +4002,10 @@ __metadata: languageName: node linkType: hard -"@jridgewell/set-array@npm:^1.0.1": - version: 1.1.2 - resolution: "@jridgewell/set-array@npm:1.1.2" - checksum: bc7ab4c4c00470de4e7562ecac3c0c84f53e7ee8a711e546d67c47da7febe7c45cd67d4d84ee3c9b2c05ae8e872656cdded8a707a283d30bd54fbc65aef821ab +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4 languageName: node linkType: hard @@ -4002,13 +4026,13 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9": - version: 0.3.22 - resolution: "@jridgewell/trace-mapping@npm:0.3.22" +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" dependencies: "@jridgewell/resolve-uri": "npm:^3.1.0" "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 18cf19f88e2792c1c91515f2b629aae05f3cdbb2e60c3886e16e80725234ce26dd10144c4981c05d9366e7094498c0b4fe5c1a89f4a730d7376a4ba4af448149 + checksum: 3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4 languageName: node linkType: hard @@ -4022,11 +4046,11 @@ __metadata: linkType: hard "@ljharb/through@npm:^2.3.9, @ljharb/through@npm:~2.3.9": - version: 2.3.12 - resolution: "@ljharb/through@npm:2.3.12" + version: 2.3.13 + resolution: "@ljharb/through@npm:2.3.13" dependencies: - call-bind: "npm:^1.0.5" - checksum: 7560aaef7b6ef88c16783ffde37278e2177c7f0f5427400059a8a7687b144dc711bf5b2347ab27e858a29f25e4b868d77c915c9614bc399b82b8123430614653 + call-bind: "npm:^1.0.7" + checksum: fb60b2fb2c674a674d8ebdb8972ccf52f8a62a9c1f5a2ac42557bc0273231c65d642aa2d7627cbb300766a25ae4642acd0f95fba2f8a1ff891086f0cb15807c3 languageName: node linkType: hard @@ -4115,6 +4139,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:^1.4.0": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 8c3f005ee72e7b8f9cff756dfae1241485187254e3f743873e22073d63906863df5d4f13d441b7530ea614b7a093f0d889309f28b59850f33b66cb26a779a4a5 + languageName: node + linkType: hard + "@noble/secp256k1@npm:1.7.1, @noble/secp256k1@npm:~1.7.0": version: 1.7.1 resolution: "@noble/secp256k1@npm:1.7.1" @@ -4149,116 +4180,67 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/edr-darwin-arm64@npm:0.2.1": - version: 0.2.1 - resolution: "@nomicfoundation/edr-darwin-arm64@npm:0.2.1" - conditions: os=darwin & cpu=arm64 +"@nomicfoundation/edr-darwin-arm64@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-darwin-arm64@npm:0.3.8" + checksum: 98298ddd1dd1d513245be57dc89aad51a0ff6da2f1227c32085a8d49c0d3cbc311981539037c3030b652e1008253d6e72081f019d44cf47c6aa8f14175505554 languageName: node linkType: hard -"@nomicfoundation/edr-darwin-x64@npm:0.2.1": - version: 0.2.1 - resolution: "@nomicfoundation/edr-darwin-x64@npm:0.2.1" - conditions: os=darwin & cpu=x64 +"@nomicfoundation/edr-darwin-x64@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-darwin-x64@npm:0.3.8" + checksum: a09fb0030b5dc7e202e7d42aae9f52af86090999a50cbfd9a4b3197b9c7fc8c7325c01d67fdd88b7037a8831e0e89ecf131155edf2c98c453c28f37c6da346f4 languageName: node linkType: hard -"@nomicfoundation/edr-linux-arm64-gnu@npm:0.2.1": - version: 0.2.1 - resolution: "@nomicfoundation/edr-linux-arm64-gnu@npm:0.2.1" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@nomicfoundation/edr-linux-arm64-musl@npm:0.2.1": - version: 0.2.1 - resolution: "@nomicfoundation/edr-linux-arm64-musl@npm:0.2.1" - conditions: os=linux & cpu=arm64 & libc=musl +"@nomicfoundation/edr-linux-arm64-gnu@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-linux-arm64-gnu@npm:0.3.8" + checksum: 20766169cb3425202a45812f01f9e49560f7cedfb797ea548759136fb8078d6179c11557b69fab8514e7f21a3f3f856dec0ba7a1584d5b431ac1440142f2012e languageName: node linkType: hard -"@nomicfoundation/edr-linux-x64-gnu@npm:0.2.1": - version: 0.2.1 - resolution: "@nomicfoundation/edr-linux-x64-gnu@npm:0.2.1" - conditions: os=linux & cpu=x64 & libc=glibc +"@nomicfoundation/edr-linux-arm64-musl@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-linux-arm64-musl@npm:0.3.8" + checksum: dabd1ee8fc5f45382e8d58770138ba0cd6536915aa5f99459404d27dec046c76e427a0971ed705da83a6aa65e9272ac84b86b14313bd83ea4fea2c81c2d3f1e5 languageName: node linkType: hard -"@nomicfoundation/edr-linux-x64-musl@npm:0.2.1": - version: 0.2.1 - resolution: "@nomicfoundation/edr-linux-x64-musl@npm:0.2.1" - conditions: os=linux & cpu=x64 & libc=musl +"@nomicfoundation/edr-linux-x64-gnu@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-linux-x64-gnu@npm:0.3.8" + checksum: 060aaa197a8401b0142d07042e72159703c6e61ef866e98548c00ff2512deb75d179536d63a89ce6cd0866269d22b2823459be730c2766c95b73645f7d4d1afc languageName: node linkType: hard -"@nomicfoundation/edr-win32-arm64-msvc@npm:0.2.1": - version: 0.2.1 - resolution: "@nomicfoundation/edr-win32-arm64-msvc@npm:0.2.1" - conditions: os=win32 & cpu=arm64 +"@nomicfoundation/edr-linux-x64-musl@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-linux-x64-musl@npm:0.3.8" + checksum: 49a7cb73b833a694744e2f5323d7268009eb1961e01ceb91f9137cf843e54571636b89418f204222d5f40b9122dd1c0e058b6efd368a438bc3bdb50205ea70d9 languageName: node linkType: hard -"@nomicfoundation/edr-win32-ia32-msvc@npm:0.2.1": - version: 0.2.1 - resolution: "@nomicfoundation/edr-win32-ia32-msvc@npm:0.2.1" - conditions: os=win32 & cpu=ia32 +"@nomicfoundation/edr-win32-x64-msvc@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-win32-x64-msvc@npm:0.3.8" + checksum: b7dfea0f01fd034ff6b48c44f75836f4dda84975f49c3655c97e76f2535945ed532756e7f2c22fa31035c4a29ce26d9546051f993ce553a8c4d570298525f55c languageName: node linkType: hard -"@nomicfoundation/edr-win32-x64-msvc@npm:0.2.1": - version: 0.2.1 - resolution: "@nomicfoundation/edr-win32-x64-msvc@npm:0.2.1" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@nomicfoundation/edr@npm:^0.2.0": - version: 0.2.1 - resolution: "@nomicfoundation/edr@npm:0.2.1" - dependencies: - "@nomicfoundation/edr-darwin-arm64": "npm:0.2.1" - "@nomicfoundation/edr-darwin-x64": "npm:0.2.1" - "@nomicfoundation/edr-linux-arm64-gnu": "npm:0.2.1" - "@nomicfoundation/edr-linux-arm64-musl": "npm:0.2.1" - "@nomicfoundation/edr-linux-x64-gnu": "npm:0.2.1" - "@nomicfoundation/edr-linux-x64-musl": "npm:0.2.1" - "@nomicfoundation/edr-win32-arm64-msvc": "npm:0.2.1" - "@nomicfoundation/edr-win32-ia32-msvc": "npm:0.2.1" - "@nomicfoundation/edr-win32-x64-msvc": "npm:0.2.1" - dependenciesMeta: - "@nomicfoundation/edr-darwin-arm64": - optional: true - "@nomicfoundation/edr-darwin-x64": - optional: true - "@nomicfoundation/edr-linux-arm64-gnu": - optional: true - "@nomicfoundation/edr-linux-arm64-musl": - optional: true - "@nomicfoundation/edr-linux-x64-gnu": - optional: true - "@nomicfoundation/edr-linux-x64-musl": - optional: true - "@nomicfoundation/edr-win32-arm64-msvc": - optional: true - "@nomicfoundation/edr-win32-ia32-msvc": - optional: true - "@nomicfoundation/edr-win32-x64-msvc": - optional: true - checksum: e8956284c14fb47662c92368ed17d871a24876a27c2e6525c99fabfe41cadb7d6f403889802216691ba41c38ee055c9cd59befc48f7b8018002ac2d09d2da29b - languageName: node - linkType: hard - -"@nomicfoundation/ethereumjs-block@npm:4.2.2": - version: 4.2.2 - resolution: "@nomicfoundation/ethereumjs-block@npm:4.2.2" +"@nomicfoundation/edr@npm:^0.3.7": + version: 0.3.8 + resolution: "@nomicfoundation/edr@npm:0.3.8" dependencies: - "@nomicfoundation/ethereumjs-common": "npm:3.1.2" - "@nomicfoundation/ethereumjs-rlp": "npm:4.0.3" - "@nomicfoundation/ethereumjs-trie": "npm:5.0.5" - "@nomicfoundation/ethereumjs-tx": "npm:4.1.2" - "@nomicfoundation/ethereumjs-util": "npm:8.0.6" - ethereum-cryptography: "npm:0.1.3" - checksum: 1c211294b3064d2bbfcf33b460438f01fb9cd77429314a90a5e2ffce5162019a384f4ae7d3825cfd386a140db191b251b475427562c53f85beffc786156f817e + "@nomicfoundation/edr-darwin-arm64": "npm:0.3.8" + "@nomicfoundation/edr-darwin-x64": "npm:0.3.8" + "@nomicfoundation/edr-linux-arm64-gnu": "npm:0.3.8" + "@nomicfoundation/edr-linux-arm64-musl": "npm:0.3.8" + "@nomicfoundation/edr-linux-x64-gnu": "npm:0.3.8" + "@nomicfoundation/edr-linux-x64-musl": "npm:0.3.8" + "@nomicfoundation/edr-win32-x64-msvc": "npm:0.3.8" + checksum: 56f4debf1d736783f498624fc2d647b075a56baedc6daf593a3e9627c99724e3fbf665245daa321a6f1db74694c11c2d70585d84fd13ecc90bf5632f503e1f04 languageName: node linkType: hard @@ -4277,40 +4259,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-block@npm:5.0.4": - version: 5.0.4 - resolution: "@nomicfoundation/ethereumjs-block@npm:5.0.4" - dependencies: - "@nomicfoundation/ethereumjs-common": "npm:4.0.4" - "@nomicfoundation/ethereumjs-rlp": "npm:5.0.4" - "@nomicfoundation/ethereumjs-trie": "npm:6.0.4" - "@nomicfoundation/ethereumjs-tx": "npm:5.0.4" - "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - ethereum-cryptography: "npm:0.1.3" - checksum: 9f8cb09f5910275188b1ad48611856c14131ad28022b958cc648f8e095fadd41002454a3396c612c2977691e59a8baad4f6adf07aab3f9c4b20b5f24c71dd7a0 - languageName: node - linkType: hard - -"@nomicfoundation/ethereumjs-blockchain@npm:6.2.2": - version: 6.2.2 - resolution: "@nomicfoundation/ethereumjs-blockchain@npm:6.2.2" - dependencies: - "@nomicfoundation/ethereumjs-block": "npm:4.2.2" - "@nomicfoundation/ethereumjs-common": "npm:3.1.2" - "@nomicfoundation/ethereumjs-ethash": "npm:2.0.5" - "@nomicfoundation/ethereumjs-rlp": "npm:4.0.3" - "@nomicfoundation/ethereumjs-trie": "npm:5.0.5" - "@nomicfoundation/ethereumjs-util": "npm:8.0.6" - abstract-level: "npm:^1.0.3" - debug: "npm:^4.3.3" - ethereum-cryptography: "npm:0.1.3" - level: "npm:^8.0.0" - lru-cache: "npm:^5.1.1" - memory-level: "npm:^1.0.0" - checksum: 6fe6e315900e1d6a29d59be41f566bdfd5ffdf82ab0fe081b1999dcc4eec3a248ab080d359a56e8cde4e473ca90349b0c50fa1ab707aa3e275fb1c478237e5e2 - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-blockchain@npm:7.0.1": version: 7.0.1 resolution: "@nomicfoundation/ethereumjs-blockchain@npm:7.0.1" @@ -4332,34 +4280,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-blockchain@npm:7.0.4": - version: 7.0.4 - resolution: "@nomicfoundation/ethereumjs-blockchain@npm:7.0.4" - dependencies: - "@nomicfoundation/ethereumjs-block": "npm:5.0.4" - "@nomicfoundation/ethereumjs-common": "npm:4.0.4" - "@nomicfoundation/ethereumjs-ethash": "npm:3.0.4" - "@nomicfoundation/ethereumjs-rlp": "npm:5.0.4" - "@nomicfoundation/ethereumjs-trie": "npm:6.0.4" - "@nomicfoundation/ethereumjs-tx": "npm:5.0.4" - "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - debug: "npm:^4.3.3" - ethereum-cryptography: "npm:0.1.3" - lru-cache: "npm:^10.0.0" - checksum: 47f73fea07880edb68b2614981226d9315a1a3dc673d0e09d68f0bc9ebd93cbfe6ccceb3cb56f777dc9b9386cff39878349fd7474d460a38478e7175b47788f9 - languageName: node - linkType: hard - -"@nomicfoundation/ethereumjs-common@npm:3.1.2": - version: 3.1.2 - resolution: "@nomicfoundation/ethereumjs-common@npm:3.1.2" - dependencies: - "@nomicfoundation/ethereumjs-util": "npm:8.0.6" - crc-32: "npm:^1.2.0" - checksum: 90910630025b5bb503f36125c45395cc9f875ffdd8137a83e9c1d566678edcc8db40f8ce1dff9da1ef2c91c7d6b6d1fa75c41a9579a5d3a8f0ae669fcea244b1 - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-common@npm:4.0.1": version: 4.0.1 resolution: "@nomicfoundation/ethereumjs-common@npm:4.0.1" @@ -4379,20 +4299,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-ethash@npm:2.0.5": - version: 2.0.5 - resolution: "@nomicfoundation/ethereumjs-ethash@npm:2.0.5" - dependencies: - "@nomicfoundation/ethereumjs-block": "npm:4.2.2" - "@nomicfoundation/ethereumjs-rlp": "npm:4.0.3" - "@nomicfoundation/ethereumjs-util": "npm:8.0.6" - abstract-level: "npm:^1.0.3" - bigint-crypto-utils: "npm:^3.0.23" - ethereum-cryptography: "npm:0.1.3" - checksum: 7a90ef53ae4c1ac5a314c3447966fdbefcc96481ae3a05d59e881053350c55be7c841708c61c79a2af40bbb0181d6e0db42601592f17a4db1611b199d49e8544 - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-ethash@npm:3.0.1": version: 3.0.1 resolution: "@nomicfoundation/ethereumjs-ethash@npm:3.0.1" @@ -4407,35 +4313,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-ethash@npm:3.0.4": - version: 3.0.4 - resolution: "@nomicfoundation/ethereumjs-ethash@npm:3.0.4" - dependencies: - "@nomicfoundation/ethereumjs-block": "npm:5.0.4" - "@nomicfoundation/ethereumjs-rlp": "npm:5.0.4" - "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - bigint-crypto-utils: "npm:^3.2.2" - ethereum-cryptography: "npm:0.1.3" - checksum: c4cb846b656720910fe6d4a741ad0be93833c701456da983fa3a1795dda6faaa0ab4fb3130446e648db94b68358e1e4e30024d372fb40d3f65a40650af1a83bc - languageName: node - linkType: hard - -"@nomicfoundation/ethereumjs-evm@npm:1.3.2, @nomicfoundation/ethereumjs-evm@npm:^1.0.0-rc.3": - version: 1.3.2 - resolution: "@nomicfoundation/ethereumjs-evm@npm:1.3.2" - dependencies: - "@nomicfoundation/ethereumjs-common": "npm:3.1.2" - "@nomicfoundation/ethereumjs-util": "npm:8.0.6" - "@types/async-eventemitter": "npm:^0.2.1" - async-eventemitter: "npm:^0.2.4" - debug: "npm:^4.3.3" - ethereum-cryptography: "npm:0.1.3" - mcl-wasm: "npm:^0.7.1" - rustbn.js: "npm:~0.2.0" - checksum: 4aa14d7dce597a91c25bec5975022348741cebf6ed20cda028ddcbebe739ba2e6f4c879fa1ebe849bd5c78d3fd2443ebbb7d57e1fca5a98fbe88fc9ce15d9fd6 - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-evm@npm:2.0.1": version: 2.0.1 resolution: "@nomicfoundation/ethereumjs-evm@npm:2.0.1" @@ -4452,31 +4329,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-evm@npm:2.0.4": - version: 2.0.4 - resolution: "@nomicfoundation/ethereumjs-evm@npm:2.0.4" - dependencies: - "@nomicfoundation/ethereumjs-common": "npm:4.0.4" - "@nomicfoundation/ethereumjs-statemanager": "npm:2.0.4" - "@nomicfoundation/ethereumjs-tx": "npm:5.0.4" - "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - "@types/debug": "npm:^4.1.9" - debug: "npm:^4.3.3" - ethereum-cryptography: "npm:0.1.3" - rustbn-wasm: "npm:^0.2.0" - checksum: f21f4d0f1a74c903934d1c6c3abcd1342c9a812c71f142999c9f3f823119761cfdb4e89e829195fa446adb772b7f4b23ee9d55ed31bd92d5d03df438c3c29202 - languageName: node - linkType: hard - -"@nomicfoundation/ethereumjs-rlp@npm:4.0.3": - version: 4.0.3 - resolution: "@nomicfoundation/ethereumjs-rlp@npm:4.0.3" - bin: - rlp: bin/rlp - checksum: 3e3c07abf53ff5832afbbdf3f3687e11e2e829699348eea1ae465084c72e024559d97e351e8f0fb27f32c7896633c7dd50b19d8de486e89cde777fd5447381cd - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-rlp@npm:5.0.1": version: 5.0.1 resolution: "@nomicfoundation/ethereumjs-rlp@npm:5.0.1" @@ -4495,21 +4347,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-statemanager@npm:1.0.5": - version: 1.0.5 - resolution: "@nomicfoundation/ethereumjs-statemanager@npm:1.0.5" - dependencies: - "@nomicfoundation/ethereumjs-common": "npm:3.1.2" - "@nomicfoundation/ethereumjs-rlp": "npm:4.0.3" - "@nomicfoundation/ethereumjs-trie": "npm:5.0.5" - "@nomicfoundation/ethereumjs-util": "npm:8.0.6" - debug: "npm:^4.3.3" - ethereum-cryptography: "npm:0.1.3" - functional-red-black-tree: "npm:^1.0.1" - checksum: 4a05b7a86a1bbc8fd409416edf437d99d9d4498c438e086c30250cb3dc92ff00086f9ff959f469c72d46178e831104dc15f10465e27fbbf0ca97da27d6889a0c - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-statemanager@npm:2.0.1": version: 2.0.1 resolution: "@nomicfoundation/ethereumjs-statemanager@npm:2.0.1" @@ -4524,39 +4361,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-statemanager@npm:2.0.4": - version: 2.0.4 - resolution: "@nomicfoundation/ethereumjs-statemanager@npm:2.0.4" - dependencies: - "@nomicfoundation/ethereumjs-common": "npm:4.0.4" - "@nomicfoundation/ethereumjs-rlp": "npm:5.0.4" - "@nomicfoundation/ethereumjs-trie": "npm:6.0.4" - "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - debug: "npm:^4.3.3" - ethereum-cryptography: "npm:0.1.3" - js-sdsl: "npm:^4.1.4" - lru-cache: "npm:^10.0.0" - peerDependencies: - "@nomicfoundation/ethereumjs-verkle": 0.0.2 - peerDependenciesMeta: - "@nomicfoundation/ethereumjs-verkle": - optional: true - checksum: 6190fef25b1099ede00edf69194903a5c5df18563adae3f053e2eafacc91eeab547d257e6aa47ce7ff5264533bb7bb0fbfcb18e75ea66376ac7305ad40dafbf4 - languageName: node - linkType: hard - -"@nomicfoundation/ethereumjs-trie@npm:5.0.5": - version: 5.0.5 - resolution: "@nomicfoundation/ethereumjs-trie@npm:5.0.5" - dependencies: - "@nomicfoundation/ethereumjs-rlp": "npm:4.0.3" - "@nomicfoundation/ethereumjs-util": "npm:8.0.6" - ethereum-cryptography: "npm:0.1.3" - readable-stream: "npm:^3.6.0" - checksum: cab544fef4bcdc3acef1bfb4ee9f2fde44b66a22b2329bfd67515facdf115a318961f8bc0e38befded838e8fc513974f90f340b53a98b8469e54960b15cd857a - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-trie@npm:6.0.1": version: 6.0.1 resolution: "@nomicfoundation/ethereumjs-trie@npm:6.0.1" @@ -4570,32 +4374,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-trie@npm:6.0.4": - version: 6.0.4 - resolution: "@nomicfoundation/ethereumjs-trie@npm:6.0.4" - dependencies: - "@nomicfoundation/ethereumjs-rlp": "npm:5.0.4" - "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - "@types/readable-stream": "npm:^2.3.13" - ethereum-cryptography: "npm:0.1.3" - lru-cache: "npm:^10.0.0" - readable-stream: "npm:^3.6.0" - checksum: b475d858f98037431c54c7177d0ce95133a81f1ee98a0b042136d65c88b7b5b3d86ba981cf78292776781d43d60daed44edf508ff4d416355bd00517e9142c9f - languageName: node - linkType: hard - -"@nomicfoundation/ethereumjs-tx@npm:4.1.2": - version: 4.1.2 - resolution: "@nomicfoundation/ethereumjs-tx@npm:4.1.2" - dependencies: - "@nomicfoundation/ethereumjs-common": "npm:3.1.2" - "@nomicfoundation/ethereumjs-rlp": "npm:4.0.3" - "@nomicfoundation/ethereumjs-util": "npm:8.0.6" - ethereum-cryptography: "npm:0.1.3" - checksum: cb569c882d3ce922acff1a4238864f11109ac5a30dfa481b1ed9c7043c2b773f3a5fc88a3f4fefb62b11c448305296533f555f93d1d969a5abd3c2a13c80ed74 - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-tx@npm:5.0.1": version: 5.0.1 resolution: "@nomicfoundation/ethereumjs-tx@npm:5.0.1" @@ -4627,16 +4405,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-util@npm:8.0.6, @nomicfoundation/ethereumjs-util@npm:^8.0.0-rc.3": - version: 8.0.6 - resolution: "@nomicfoundation/ethereumjs-util@npm:8.0.6" - dependencies: - "@nomicfoundation/ethereumjs-rlp": "npm:4.0.3" - ethereum-cryptography: "npm:0.1.3" - checksum: 647006f4dfa962f61cec54c34ff9939468042cf762ff3b2cf80c8362558f21750348a3cda63dc9890b1cb2ba664f97dc4a892afca5f5d6f95b3ba4d56be5a33b - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-util@npm:9.0.1": version: 9.0.1 resolution: "@nomicfoundation/ethereumjs-util@npm:9.0.1" @@ -4648,7 +4416,7 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-util@npm:9.0.4": +"@nomicfoundation/ethereumjs-util@npm:9.0.4, @nomicfoundation/ethereumjs-util@npm:^9.0.4": version: 9.0.4 resolution: "@nomicfoundation/ethereumjs-util@npm:9.0.4" dependencies: @@ -4663,18 +4431,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-verkle@npm:0.0.2": - version: 0.0.2 - resolution: "@nomicfoundation/ethereumjs-verkle@npm:0.0.2" - dependencies: - "@nomicfoundation/ethereumjs-rlp": "npm:5.0.4" - "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - lru-cache: "npm:^10.0.0" - rust-verkle-wasm: "npm:^0.0.1" - checksum: 7f6b3be75949adbdb8ecea4539a7c4cdce9ee1d76159b5d77f04a794e4e9de42570fc0491fc4769ecc3553547031996b16ec88ba18d68bf0e1b0d1149effb51b - languageName: node - linkType: hard - "@nomicfoundation/ethereumjs-vm@npm:7.0.1": version: 7.0.1 resolution: "@nomicfoundation/ethereumjs-vm@npm:7.0.1" @@ -4696,49 +4452,6 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-vm@npm:7.0.4": - version: 7.0.4 - resolution: "@nomicfoundation/ethereumjs-vm@npm:7.0.4" - dependencies: - "@nomicfoundation/ethereumjs-block": "npm:5.0.4" - "@nomicfoundation/ethereumjs-blockchain": "npm:7.0.4" - "@nomicfoundation/ethereumjs-common": "npm:4.0.4" - "@nomicfoundation/ethereumjs-evm": "npm:2.0.4" - "@nomicfoundation/ethereumjs-rlp": "npm:5.0.4" - "@nomicfoundation/ethereumjs-statemanager": "npm:2.0.4" - "@nomicfoundation/ethereumjs-trie": "npm:6.0.4" - "@nomicfoundation/ethereumjs-tx": "npm:5.0.4" - "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - debug: "npm:^4.3.3" - ethereum-cryptography: "npm:0.1.3" - checksum: a1893c8aa0fb8666bcb7371d8a57f641bd6079a79f9e08175aca214cd4a3d7eda3e54046a7d1b4c6cbc2356e80b1e6b44295e56df2d184ceb157eb67e54ee326 - languageName: node - linkType: hard - -"@nomicfoundation/ethereumjs-vm@npm:^6.0.0-rc.3": - version: 6.4.2 - resolution: "@nomicfoundation/ethereumjs-vm@npm:6.4.2" - dependencies: - "@nomicfoundation/ethereumjs-block": "npm:4.2.2" - "@nomicfoundation/ethereumjs-blockchain": "npm:6.2.2" - "@nomicfoundation/ethereumjs-common": "npm:3.1.2" - "@nomicfoundation/ethereumjs-evm": "npm:1.3.2" - "@nomicfoundation/ethereumjs-rlp": "npm:4.0.3" - "@nomicfoundation/ethereumjs-statemanager": "npm:1.0.5" - "@nomicfoundation/ethereumjs-trie": "npm:5.0.5" - "@nomicfoundation/ethereumjs-tx": "npm:4.1.2" - "@nomicfoundation/ethereumjs-util": "npm:8.0.6" - "@types/async-eventemitter": "npm:^0.2.1" - async-eventemitter: "npm:^0.2.4" - debug: "npm:^4.3.3" - ethereum-cryptography: "npm:0.1.3" - functional-red-black-tree: "npm:^1.0.1" - mcl-wasm: "npm:^0.7.1" - rustbn.js: "npm:~0.2.0" - checksum: 78e4b0ba20e8fa4ef112bae88f432746647ed48b41918b34855fe08269be3aaff84f95c08b6c61475fb70f24a28ba73612bd2bcd19b3c007c8bf9e11a43fa8e0 - languageName: node - linkType: hard - "@nomicfoundation/hardhat-chai-matchers@npm:^2.0.0": version: 2.0.6 resolution: "@nomicfoundation/hardhat-chai-matchers@npm:2.0.6" @@ -4757,26 +4470,26 @@ __metadata: linkType: hard "@nomicfoundation/hardhat-ethers@npm:^3.0.0": - version: 3.0.5 - resolution: "@nomicfoundation/hardhat-ethers@npm:3.0.5" + version: 3.0.6 + resolution: "@nomicfoundation/hardhat-ethers@npm:3.0.6" dependencies: debug: "npm:^4.1.1" lodash.isequal: "npm:^4.5.0" peerDependencies: ethers: ^6.1.0 hardhat: ^2.0.0 - checksum: 8253d107f956fbbfcb55b758cfd05159dcc77289bc115418626c3be32efeaced82c7dbfcb9d67ef0d9dccb6851e8588edeb228f325982ac3c61d7f605bcef009 + checksum: c7abe4234fae6422a357ef9e959cfe4183d5d7121d18e9f71b1659944419fde7d2a0290cd42fd5e85d855d8c83b86bbaed316f4950f0976015f941d958679a99 languageName: node linkType: hard "@nomicfoundation/hardhat-foundry@npm:^1.1.1": - version: 1.1.1 - resolution: "@nomicfoundation/hardhat-foundry@npm:1.1.1" + version: 1.1.2 + resolution: "@nomicfoundation/hardhat-foundry@npm:1.1.2" dependencies: chalk: "npm:^2.4.2" peerDependencies: hardhat: ^2.17.2 - checksum: e1f914bd705b93c9efc9f0b30eb178288504aede202ec00a9b03d3fa494baf175d0218ee678a328179b1ecfe18e16184888f671e8a03488e4ebfba0daf93a603 + checksum: 54cad1a0d1fc3c2137722a1b213dcbd18f77e63778bda9593052e6090868b2fb7bf8087c10404c6b181fa631e75f7e70490b5b97c3e4eba8f52ef449131dada0 languageName: node linkType: hard @@ -4817,8 +4530,8 @@ __metadata: linkType: hard "@nomicfoundation/hardhat-verify@npm:^2.0.0": - version: 2.0.4 - resolution: "@nomicfoundation/hardhat-verify@npm:2.0.4" + version: 2.0.7 + resolution: "@nomicfoundation/hardhat-verify@npm:2.0.7" dependencies: "@ethersproject/abi": "npm:^5.1.2" "@ethersproject/address": "npm:^5.0.2" @@ -4831,7 +4544,7 @@ __metadata: undici: "npm:^5.14.0" peerDependencies: hardhat: ^2.0.4 - checksum: 9003db2eb06aad8764473240d5ddb0cdef27b9bd7ed4586469aec8997d4556a1b1f11c537b567e3a30af694ac5d756dc9cccc52c14604e92d0dfdc964d12c6e8 + checksum: a6b3b89d3d2a594c44b50832840deefd3261b158bde774319322859077637f656c2e436af21ca3ce10d60eac78e3a1fbfea02abfe20a4729f97b4f30515524a6 languageName: node linkType: hard @@ -5003,24 +4716,24 @@ __metadata: linkType: hard "@npmcli/agent@npm:^2.0.0": - version: 2.2.1 - resolution: "@npmcli/agent@npm:2.2.1" + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" dependencies: agent-base: "npm:^7.1.0" http-proxy-agent: "npm:^7.0.0" https-proxy-agent: "npm:^7.0.1" lru-cache: "npm:^10.0.1" - socks-proxy-agent: "npm:^8.0.1" - checksum: 38ee5cbe8f3cde13be916e717bfc54fd1a7605c07af056369ff894e244c221e0b56b08ca5213457477f9bc15bca9e729d51a4788829b5c3cf296b3c996147f76 + socks-proxy-agent: "npm:^8.0.3" + checksum: 325e0db7b287d4154ecd164c0815c08007abfb07653cc57bceded17bb7fd240998a3cbdbe87d700e30bef494885eccc725ab73b668020811d56623d145b524ae languageName: node linkType: hard "@npmcli/fs@npm:^3.1.0": - version: 3.1.0 - resolution: "@npmcli/fs@npm:3.1.0" + version: 3.1.1 + resolution: "@npmcli/fs@npm:3.1.1" dependencies: semver: "npm:^7.3.5" - checksum: 162b4a0b8705cd6f5c2470b851d1dc6cd228c86d2170e1769d738c1fbb69a87160901411c3c035331e9e99db72f1f1099a8b734bf1637cc32b9a5be1660e4e1e + checksum: c37a5b4842bfdece3d14dfdb054f73fe15ed2d3da61b34ff76629fb5b1731647c49166fd2a8bf8b56fcfa51200382385ea8909a3cbecdad612310c114d3f6c99 languageName: node linkType: hard @@ -5053,28 +4766,28 @@ __metadata: linkType: hard "@openzeppelin/defender-admin-client@npm:^1.46.0": - version: 1.54.1 - resolution: "@openzeppelin/defender-admin-client@npm:1.54.1" + version: 1.54.2 + resolution: "@openzeppelin/defender-admin-client@npm:1.54.2" dependencies: - "@openzeppelin/defender-base-client": "npm:1.54.1" + "@openzeppelin/defender-base-client": "npm:1.54.2" axios: "npm:^1.4.0" ethers: "npm:^5.7.2" lodash: "npm:^4.17.19" node-fetch: "npm:^2.6.0" - checksum: b8d9b112bc9c477aca23a9b7249801eb997295302afe60e5c0883579f1ca1069a411ee7be9f972de52019bf59e0d36b7c11503ec09d4328c15899fa4bfdf6d6c + checksum: fff2a74f840168d65a7cc51992610c199eb0d2b54b63f84060dded898d2730e0b008b3f492251ec99a697d45e69987a203ee005b5912e51a2786407755e3e53f languageName: node linkType: hard -"@openzeppelin/defender-base-client@npm:1.54.1, @openzeppelin/defender-base-client@npm:^1.46.0": - version: 1.54.1 - resolution: "@openzeppelin/defender-base-client@npm:1.54.1" +"@openzeppelin/defender-base-client@npm:1.54.2, @openzeppelin/defender-base-client@npm:^1.46.0": + version: 1.54.2 + resolution: "@openzeppelin/defender-base-client@npm:1.54.2" dependencies: amazon-cognito-identity-js: "npm:^6.0.1" async-retry: "npm:^1.3.3" axios: "npm:^1.4.0" lodash: "npm:^4.17.19" node-fetch: "npm:^2.6.0" - checksum: 10a709dfc4fc55ad8d431b1c6d5e67129131d9763f3a91b9ec9ee63653cc8b0a8567809d04341bcb8615e0e20c917c2045a45693070ee9d83da11620338d874d + checksum: b30c5c5ed47ed0ff788025abd0cdfc816fdbd49065c221be7e760385e5cbf5b05488ed1cfb040c5cbe0a1ca6cc6af035dc88a6e5b2c09fb9ae4ae048493014bd languageName: node linkType: hard @@ -5128,8 +4841,8 @@ __metadata: linkType: hard "@openzeppelin/upgrades-core@npm:^1.27.0": - version: 1.32.5 - resolution: "@openzeppelin/upgrades-core@npm:1.32.5" + version: 1.33.1 + resolution: "@openzeppelin/upgrades-core@npm:1.33.1" dependencies: cbor: "npm:^9.0.0" chalk: "npm:^4.1.0" @@ -5141,7 +4854,7 @@ __metadata: solidity-ast: "npm:^0.4.51" bin: openzeppelin-upgrades-core: dist/cli/cli.js - checksum: aac654c46aadcfba55024a17d029edcbc529be2fae16fa8d4efc3fd8114cbb4d36d8974a62b1f34fcfa593b3b072898995034ff3bb6a921e00bcac669d8b1998 + checksum: 96fbed78baec7502709a38f5a00180750c24e96aa047a438b34c0d9895dc4ffed47b7e4fedab57cabfd733a3c079e78c98eec23a6df61f3fb4c8b2c9d096bcba languageName: node linkType: hard @@ -5166,15 +4879,15 @@ __metadata: linkType: hard "@peculiar/webcrypto@npm:^1.4.0": - version: 1.4.5 - resolution: "@peculiar/webcrypto@npm:1.4.5" + version: 1.4.6 + resolution: "@peculiar/webcrypto@npm:1.4.6" dependencies: "@peculiar/asn1-schema": "npm:^2.3.8" "@peculiar/json-schema": "npm:^1.1.12" pvtsutils: "npm:^1.3.5" tslib: "npm:^2.6.2" - webcrypto-core: "npm:^1.7.8" - checksum: 7cefe2a1329e3d41721268cf483dfd7a7a3bfbdaaba0ca8db9a538b49a51c6977f66f7f85e6f0c2162ff8d09540821bedc6766586d83c4be565b1af49ea81a86 + webcrypto-core: "npm:^1.7.9" + checksum: b9c80b1a0a3e3ebbf045bd5167fe99ec4a83b170e9aa15a5952a9138afc278210d772306dcc57101d9407c3f9c70dbf6bfb4d8b3f20996ad35c650bb0fe6a90c languageName: node linkType: hard @@ -5236,9 +4949,9 @@ __metadata: linkType: hard "@repeaterjs/repeater@npm:^3.0.4": - version: 3.0.5 - resolution: "@repeaterjs/repeater@npm:3.0.5" - checksum: e6e1aca2bbfe0b8e974bc5185a6839f9e78ec8acb96b6d6911a9dfc958443689f9bc38bcc6d554e6c8598f597f0151841aafbd1ee3ef16262ee93d18b2c1d4b5 + version: 3.0.6 + resolution: "@repeaterjs/repeater@npm:3.0.6" + checksum: c3915e2603927c7d6a9eb09673bc28fc49ab3a86947ec191a74663b33deebee2fcc4b03c31cc663ff27bd6db9e6c9487639b6935e265d601ce71b8c497f5f4a8 languageName: node linkType: hard @@ -5329,10 +5042,10 @@ __metadata: languageName: node linkType: hard -"@scure/base@npm:^1.1.1, @scure/base@npm:~1.1.0, @scure/base@npm:~1.1.4": - version: 1.1.5 - resolution: "@scure/base@npm:1.1.5" - checksum: 6eb07be0202fac74a57c79d0d00a45f6f7e57447010c1e3d90a4275d197829727b7abc54b248fc6f9bef9ae374f7be5ee9154dde5b5b73da773560bf17aa8504 +"@scure/base@npm:~1.1.0, @scure/base@npm:~1.1.4": + version: 1.1.6 + resolution: "@scure/base@npm:1.1.6" + checksum: 237a46a1f45391fc57719154f14295db936a0b1562ea3e182dd42d7aca082dbb7062a28d6c49af16a7e478b12dae8a0fe678d921ea5056bcc30238d29eb05c55 languageName: node linkType: hard @@ -5481,12 +5194,12 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.9.1": - version: 2.10.0 - resolution: "@smithy/types@npm:2.10.0" +"@smithy/types@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/types@npm:3.0.0" dependencies: - tslib: "npm:^2.5.0" - checksum: e82d7584e9b0d0c8fb6da059af6ebcb8af86dba7c1dc3e757b4998eca636f8dd697ea47701ff6c755789f0a63ef16f960fcc682ab2ca185cef4c6a6db5f022dc + tslib: "npm:^2.6.2" + checksum: 9f6eefa4f715a8f0bfd79787f82156b4785baaa1524496abe9fc3db96c36f7c782fb962353601d8bd2bba3b449d999d48a09b2b25405bfcd7fb5e1d1c935f1fb languageName: node linkType: hard @@ -5522,72 +5235,72 @@ __metadata: languageName: node linkType: hard -"@stylistic/eslint-plugin-js@npm:1.6.2, @stylistic/eslint-plugin-js@npm:^1.6.2": - version: 1.6.2 - resolution: "@stylistic/eslint-plugin-js@npm:1.6.2" +"@stylistic/eslint-plugin-js@npm:1.8.1, @stylistic/eslint-plugin-js@npm:^1.8.1": + version: 1.8.1 + resolution: "@stylistic/eslint-plugin-js@npm:1.8.1" dependencies: - "@types/eslint": "npm:^8.56.2" + "@types/eslint": "npm:^8.56.10" acorn: "npm:^8.11.3" escape-string-regexp: "npm:^4.0.0" eslint-visitor-keys: "npm:^3.4.3" espree: "npm:^9.6.1" peerDependencies: eslint: ">=8.40.0" - checksum: b74b08802cb888b64b2432e2fa7723c664d1b6a3ee5ad48f8caeef83eebcfcf291f92f967b65e79854d19a660e9428567247de402eeb9e59d9320f71c8c3881e + checksum: 0f5aa5f4afd0a0120a7675f5f0abb2d6fc5ee6197390613a69dcf510644964f1eb8ef8c060be2cf8c1885863a507bdf42e74954f886dca4102e49acfee50c577 languageName: node linkType: hard -"@stylistic/eslint-plugin-jsx@npm:1.6.2": - version: 1.6.2 - resolution: "@stylistic/eslint-plugin-jsx@npm:1.6.2" +"@stylistic/eslint-plugin-jsx@npm:1.8.1": + version: 1.8.1 + resolution: "@stylistic/eslint-plugin-jsx@npm:1.8.1" dependencies: - "@stylistic/eslint-plugin-js": "npm:^1.6.2" - "@types/eslint": "npm:^8.56.2" + "@stylistic/eslint-plugin-js": "npm:^1.8.1" + "@types/eslint": "npm:^8.56.10" estraverse: "npm:^5.3.0" - picomatch: "npm:^4.0.1" + picomatch: "npm:^4.0.2" peerDependencies: eslint: ">=8.40.0" - checksum: 882daa8ac9e3d7db5009dd6a9b4c406edab0ced233d3d49e6a9a0acb94ed68d8e5ec9a705c8925c7adc103ef9c057f33b74c32c7087f40a61c5b85f31f530fcc + checksum: 3bf9a543c1dc661bbe1fb939a46a8cc9543f8c2fbd53b39c05861e042e28c7483cf318152c5cbf1dbc6022e0e211375931f707c5d9a7a63f83a74f857f7b28b4 languageName: node linkType: hard -"@stylistic/eslint-plugin-plus@npm:1.6.2": - version: 1.6.2 - resolution: "@stylistic/eslint-plugin-plus@npm:1.6.2" +"@stylistic/eslint-plugin-plus@npm:1.8.1": + version: 1.8.1 + resolution: "@stylistic/eslint-plugin-plus@npm:1.8.1" dependencies: - "@types/eslint": "npm:^8.56.2" + "@types/eslint": "npm:^8.56.10" "@typescript-eslint/utils": "npm:^6.21.0" peerDependencies: eslint: "*" - checksum: 426e68c7edcb96d48f8ccb22c07fb5b7b26d85210494cfbafb6331d67496946ae3af841933059c31594d5f7c8b4e867de2345418d64a1885b102988d7679fae1 + checksum: 644cf23179b69df12bc798357ae0193eed2dd68a6e5e8dd11f5c8ecad0898eb58b5dac68fafd31c52b852b0800cb21ce457397d4d94cb60549311283540a2dd4 languageName: node linkType: hard -"@stylistic/eslint-plugin-ts@npm:1.6.2": - version: 1.6.2 - resolution: "@stylistic/eslint-plugin-ts@npm:1.6.2" +"@stylistic/eslint-plugin-ts@npm:1.8.1": + version: 1.8.1 + resolution: "@stylistic/eslint-plugin-ts@npm:1.8.1" dependencies: - "@stylistic/eslint-plugin-js": "npm:1.6.2" - "@types/eslint": "npm:^8.56.2" + "@stylistic/eslint-plugin-js": "npm:1.8.1" + "@types/eslint": "npm:^8.56.10" "@typescript-eslint/utils": "npm:^6.21.0" peerDependencies: eslint: ">=8.40.0" - checksum: 15e19abfce7ac77843d1331ee5cab74b405bdb5fb890acb071f6a7c21dc81b338d6482f227aa0af0b32faa61de25166b3a3253cec1df867f99ca105155e001cc + checksum: 1bd0bb220998b7ebd3a7e788b8bafc6674291160604825eea547cfd1a9530b02777ffe5775ddce932388044d7e932c9693be8c30fa989b03ee0ddf98ebc3d40d languageName: node linkType: hard "@stylistic/eslint-plugin@npm:^1.6.2": - version: 1.6.2 - resolution: "@stylistic/eslint-plugin@npm:1.6.2" + version: 1.8.1 + resolution: "@stylistic/eslint-plugin@npm:1.8.1" dependencies: - "@stylistic/eslint-plugin-js": "npm:1.6.2" - "@stylistic/eslint-plugin-jsx": "npm:1.6.2" - "@stylistic/eslint-plugin-plus": "npm:1.6.2" - "@stylistic/eslint-plugin-ts": "npm:1.6.2" - "@types/eslint": "npm:^8.56.2" + "@stylistic/eslint-plugin-js": "npm:1.8.1" + "@stylistic/eslint-plugin-jsx": "npm:1.8.1" + "@stylistic/eslint-plugin-plus": "npm:1.8.1" + "@stylistic/eslint-plugin-ts": "npm:1.8.1" + "@types/eslint": "npm:^8.56.10" peerDependencies: eslint: ">=8.40.0" - checksum: 353c852e1ace9b80bfe18a31b977723d79081397a12ebd14f34f2f5c2eeebc71a38ea17b65b9e3e3d8fcf09c14807822bf9123551e8df1785a3d1d1a6ee39c51 + checksum: 036e4e9dcc4674810bd36b22404234b6a34b79b762fe8275470916ce5a3d3b10e5ef9ba86fb786fcbb39b801a6757079915c1cdd57d07c88ed472fdff5192cc4 languageName: node linkType: hard @@ -5681,9 +5394,9 @@ __metadata: linkType: hard "@tsconfig/node10@npm:^1.0.7": - version: 1.0.9 - resolution: "@tsconfig/node10@npm:1.0.9" - checksum: c176a2c1e1b16be120c328300ea910df15fb9a5277010116d26818272341a11483c5a80059389d04edacf6fd2d03d4687ad3660870fdd1cc0b7109e160adb220 + version: 1.0.11 + resolution: "@tsconfig/node10@npm:1.0.11" + checksum: 28a0710e5d039e0de484bdf85fee883bfd3f6a8980601f4d44066b0a6bcd821d31c4e231d1117731c4e24268bd4cf2a788a6787c12fc7f8d11014c07d582783c languageName: node linkType: hard @@ -5808,15 +5521,6 @@ __metadata: languageName: node linkType: hard -"@types/async-eventemitter@npm:^0.2.1": - version: 0.2.4 - resolution: "@types/async-eventemitter@npm:0.2.4" - dependencies: - "@types/events": "npm:*" - checksum: 2ae267eb3e959fe5aaf6d850ab06ac2e5b44f1a7e3e421250f3ebaa8a108f641e9050d042980bc35aab98d6fa5f1a62a43cfb7f377011ce9013ed62229327111 - languageName: node - linkType: hard - "@types/bn.js@npm:*, @types/bn.js@npm:^5.1.0, @types/bn.js@npm:^5.1.1": version: 5.1.5 resolution: "@types/bn.js@npm:5.1.5" @@ -5867,9 +5571,9 @@ __metadata: linkType: hard "@types/chai@npm:*, @types/chai@npm:^4.2.0, @types/chai@npm:^4.3.9": - version: 4.3.12 - resolution: "@types/chai@npm:4.3.12" - checksum: e5d952726d7f053812579962b07d0e4965c160c6a90bf466580e639cd3a1f1d30da1abbfe782383538a043a07908f9dfb823fa9065b37752a5f27d62234f44d5 + version: 4.3.16 + resolution: "@types/chai@npm:4.3.16" + checksum: 745d4a9be429d5d86a7ab26064610b8957fe12dd80e94dc7d0707cf3db1c889e3ffe0d73d69bb15e6d376bf4462a7a75e9d8fc1051750b5d656d6cfe459829b7 languageName: node linkType: hard @@ -5882,7 +5586,7 @@ __metadata: languageName: node linkType: hard -"@types/debug@npm:^4.1.10, @types/debug@npm:^4.1.7, @types/debug@npm:^4.1.8, @types/debug@npm:^4.1.9": +"@types/debug@npm:^4.1.10, @types/debug@npm:^4.1.7, @types/debug@npm:^4.1.8": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" dependencies: @@ -5900,13 +5604,13 @@ __metadata: languageName: node linkType: hard -"@types/eslint@npm:*, @types/eslint@npm:^8.56.2": - version: 8.56.3 - resolution: "@types/eslint@npm:8.56.3" +"@types/eslint@npm:*, @types/eslint@npm:^8.56.10": + version: 8.56.10 + resolution: "@types/eslint@npm:8.56.10" dependencies: "@types/estree": "npm:*" "@types/json-schema": "npm:*" - checksum: c5d81d0001fae211451b39d82b2bc8d7224b00d52a514954a33840a3665f36f3bde3be602eec6ad08d1fff59108052cd7746ced4237116bc3d8ac01a7cf5b5fe + checksum: 674349d6c342c3864d70f4d5a9965f96fb253801532752c8c500ad6a1c2e8b219e01ccff5dc8791dcb58b5483012c495708bb9f3ff929f5c9322b3da126c15d3 languageName: node linkType: hard @@ -5926,13 +5630,6 @@ __metadata: languageName: node linkType: hard -"@types/events@npm:*": - version: 3.0.3 - resolution: "@types/events@npm:3.0.3" - checksum: 3a56f8c51eb4ebc0d05dcadca0c6636c816acc10216ce36c976fad11e54a01f4bb979a07211355686015884753b37f17d74bfdc7aaf4ebb027c1e8a501c7b21d - languageName: node - linkType: hard - "@types/form-data@npm:0.0.33": version: 0.0.33 resolution: "@types/form-data@npm:0.0.33" @@ -5996,9 +5693,9 @@ __metadata: linkType: hard "@types/lodash@npm:^4.14.200": - version: 4.14.202 - resolution: "@types/lodash@npm:4.14.202" - checksum: 6064d43c8f454170841bd67c8266cc9069d9e570a72ca63f06bceb484cb4a3ee60c9c1f305c1b9e3a87826049fd41124b8ef265c4dd08b00f6766609c7fe9973 + version: 4.17.4 + resolution: "@types/lodash@npm:4.17.4" + checksum: 0124c64cb9fe7a0f78b6777955abd05ef0d97844d49118652eae45f8fa57bfb7f5a7a9bccc0b5a84c0a6dc09631042e4590cb665acb9d58dfd5e6543c75341ec languageName: node linkType: hard @@ -6070,37 +5767,19 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^20.11.19, @types/node@npm:^20.4.2, @types/node@npm:^20.8.7, @types/node@npm:^20.9.0": - version: 20.11.20 - resolution: "@types/node@npm:20.11.20" - dependencies: - undici-types: "npm:~5.26.4" - checksum: 8e8de211e6d54425c603388a9b5cc9c434101985d0a1c88aabbf65d10df2b1fccd71855c20e61ae8a75c7aea56cb0f64e722cf7914cff1247d0b62ce21996ac4 - languageName: node - linkType: hard - -"@types/node@npm:18.15.13": - version: 18.15.13 - resolution: "@types/node@npm:18.15.13" - checksum: 6e5f61c559e60670a7a8fb88e31226ecc18a21be103297ca4cf9848f0a99049dae77f04b7ae677205f2af494f3701b113ba8734f4b636b355477a6534dbb8ada - languageName: node - linkType: hard - -"@types/node@npm:>=12": - version: 20.11.30 - resolution: "@types/node@npm:20.11.30" +"@types/node@npm:*, @types/node@npm:>=12, @types/node@npm:>=16.0.0, @types/node@npm:^20.11.19, @types/node@npm:^20.4.2, @types/node@npm:^20.8.7, @types/node@npm:^20.9.0": + version: 20.12.12 + resolution: "@types/node@npm:20.12.12" dependencies: undici-types: "npm:~5.26.4" - checksum: 867cfaf969c6d8850d8d7304e7ab739898a50ecb1395b61ff2335644f5f48d7a46fbc4a14cee967aed65ec134b61a746edae70d1f32f11321ccf29165e3bc4e6 + checksum: f374b763c744e8f16e4f38cf6e2c0eef31781ec9228c9e43a6f267880fea420fab0a238b59f10a7cb3444e49547c5e3785787e371fc242307310995b21988812 languageName: node linkType: hard -"@types/node@npm:>=16.0.0": - version: 20.11.26 - resolution: "@types/node@npm:20.11.26" - dependencies: - undici-types: "npm:~5.26.4" - checksum: 2df81e4f109588c4c490f2c7d616a06d2b3b9298f217468134b80711af810c9a6017a59beb3e6b1c596eb9b6c5a39d33403b99179acb89006badfbc55f2468bb +"@types/node@npm:18.15.13": + version: 18.15.13 + resolution: "@types/node@npm:18.15.13" + checksum: 6e5f61c559e60670a7a8fb88e31226ecc18a21be103297ca4cf9848f0a99049dae77f04b7ae677205f2af494f3701b113ba8734f4b636b355477a6534dbb8ada languageName: node linkType: hard @@ -6162,17 +5841,10 @@ __metadata: languageName: node linkType: hard -"@types/qs@npm:^6.2.31, @types/qs@npm:^6.9.4": - version: 6.9.11 - resolution: "@types/qs@npm:6.9.11" - checksum: 657a50f05b694d6fd3916d24177cfa0f3b8b87d9deff4ffa4dddcb0b03583ebf7c47b424b8de400270fb9a5cc1e9cf790dd82c833c6935305851e7da8ede3ff5 - languageName: node - linkType: hard - -"@types/qs@npm:^6.9.7": - version: 6.9.13 - resolution: "@types/qs@npm:6.9.13" - checksum: 0e2dbfb6ee13657cd87742f92c94f1b7a70901452fce477fb9391928165766623581a3229b34fde3e832afbedee509de98984124f38b513ba072d6e193ea06cd +"@types/qs@npm:^6.2.31, @types/qs@npm:^6.9.4, @types/qs@npm:^6.9.7": + version: 6.9.15 + resolution: "@types/qs@npm:6.9.15" + checksum: 49c5ff75ca3adb18a1939310042d273c9fc55920861bd8e5100c8a923b3cda90d759e1a95e18334092da1c8f7b820084687770c83a1ccef04fb2c6908117c823 languageName: node linkType: hard @@ -6214,9 +5886,9 @@ __metadata: linkType: hard "@types/semver@npm:^7.5.0": - version: 7.5.7 - resolution: "@types/semver@npm:7.5.7" - checksum: fb72d8b86a7779650f14ae89542f1da2ab624adb8188d98754b1d29a2fe3d41f0348bf9435b60ad145df1812fd2a09b3256779aa23b532c199f3dee59619a1eb + version: 7.5.8 + resolution: "@types/semver@npm:7.5.8" + checksum: 8663ff927234d1c5fcc04b33062cb2b9fcfbe0f5f351ed26c4d1e1581657deebd506b41ff7fdf89e787e3d33ce05854bc01686379b89e9c49b564c4cfa988efa languageName: node linkType: hard @@ -6270,9 +5942,9 @@ __metadata: linkType: hard "@types/validator@npm:^13.7.1, @types/validator@npm:^13.7.17": - version: 13.11.9 - resolution: "@types/validator@npm:13.11.9" - checksum: 856ebfcfe25d6c91a90235e0eb27302a737832530898195bbfb265da52ae7fe6d68f684942574f8818d3c262cae7a1de99f145dac73fc57217933af1bfc199cb + version: 13.11.10 + resolution: "@types/validator@npm:13.11.10" + checksum: fe63a20fa90d3e8c661d0ac5b5af162cdd387b9e8fd67f5a0a00ca308e4e2d7602467cc32ef3e2c979b737629fa9e2ff593d3946ee4f8667bbb80af0494b9c66 languageName: node linkType: hard @@ -6320,28 +5992,26 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.0.2": - version: 7.0.2 - resolution: "@typescript-eslint/eslint-plugin@npm:7.0.2" +"@typescript-eslint/eslint-plugin@npm:7.9.0": + version: 7.9.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.9.0" dependencies: - "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.0.2" - "@typescript-eslint/type-utils": "npm:7.0.2" - "@typescript-eslint/utils": "npm:7.0.2" - "@typescript-eslint/visitor-keys": "npm:7.0.2" - debug: "npm:^4.3.4" + "@eslint-community/regexpp": "npm:^4.10.0" + "@typescript-eslint/scope-manager": "npm:7.9.0" + "@typescript-eslint/type-utils": "npm:7.9.0" + "@typescript-eslint/utils": "npm:7.9.0" + "@typescript-eslint/visitor-keys": "npm:7.9.0" graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.4" + ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" + ts-api-utils: "npm:^1.3.0" peerDependencies: "@typescript-eslint/parser": ^7.0.0 eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 76727ad48f01c1bb4ef37690e7ed12754930ce3a4bbe5dcd52f24d42f4625fc0b151db8189947f3956b4a09a562eb2da683ff65b57a13a15426eee3b680f80a5 + checksum: 5c0ded9cb2210c141d236075f01a86447bf497a5061773c3c64a90756264776b4c4df100f7588e36d34f727eca55afd52fe6696a3cbe2d1f131250934254603a languageName: node linkType: hard @@ -6370,21 +6040,21 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.0.2": - version: 7.0.2 - resolution: "@typescript-eslint/parser@npm:7.0.2" +"@typescript-eslint/parser@npm:7.9.0": + version: 7.9.0 + resolution: "@typescript-eslint/parser@npm:7.9.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.0.2" - "@typescript-eslint/types": "npm:7.0.2" - "@typescript-eslint/typescript-estree": "npm:7.0.2" - "@typescript-eslint/visitor-keys": "npm:7.0.2" + "@typescript-eslint/scope-manager": "npm:7.9.0" + "@typescript-eslint/types": "npm:7.9.0" + "@typescript-eslint/typescript-estree": "npm:7.9.0" + "@typescript-eslint/visitor-keys": "npm:7.9.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: acffdbea0bba24398ba8bd1ccf5b59438bc093e41d7a325019383094f39d676b5cf2f5963bfa5e332e54728e5b9e14be3984752ee91da6f0e1a3e0b613422d0e + checksum: 16ca04645429436d9b7986cddda979ef4d088f4223f4a69e04a369e0fd4852dd5ff3d4b99da2e43cddaa2b421b24ff42f275d87bd110ae2356bdd0e81c2534e7 languageName: node linkType: hard @@ -6416,13 +6086,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.0.2": - version: 7.0.2 - resolution: "@typescript-eslint/scope-manager@npm:7.0.2" +"@typescript-eslint/scope-manager@npm:7.9.0": + version: 7.9.0 + resolution: "@typescript-eslint/scope-manager@npm:7.9.0" dependencies: - "@typescript-eslint/types": "npm:7.0.2" - "@typescript-eslint/visitor-keys": "npm:7.0.2" - checksum: 60241a0dbed7605133b6242d7fc172e8ee649e1033b8a179cebe3e21c60e0c08c12679fd37644cfef57c95a5d75a3927afc9d6365a5f9684c1d043285db23c66 + "@typescript-eslint/types": "npm:7.9.0" + "@typescript-eslint/visitor-keys": "npm:7.9.0" + checksum: 1ba6fc559a42a9b54e38c3ac2b6669efcff1a30292fb4e5fc8739c890a6c0f37d1a6aee1d115198f57c88e4f1776e95c1d7143de5cb5b970d5eb3023e97789dd languageName: node linkType: hard @@ -6443,20 +6113,20 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.0.2": - version: 7.0.2 - resolution: "@typescript-eslint/type-utils@npm:7.0.2" +"@typescript-eslint/type-utils@npm:7.9.0": + version: 7.9.0 + resolution: "@typescript-eslint/type-utils@npm:7.9.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.0.2" - "@typescript-eslint/utils": "npm:7.0.2" + "@typescript-eslint/typescript-estree": "npm:7.9.0" + "@typescript-eslint/utils": "npm:7.9.0" debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.0.1" + ts-api-utils: "npm:^1.3.0" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: fa7957aa65cb0d7366c7c9be94e45cc2f1ebe9981cbf393054b505c6d555a01b2a2fe7cd1254d668f30183a275032f909186ce0b9f213f64b776bd7872144a6e + checksum: 775280fb179268f8bacd60e684d9d5a1c6a379646b082c7244bf2dfb7dd693053bd9efa473b71e10a86db69322b0a2cecf5598d019684930df50000bf3d70af0 languageName: node linkType: hard @@ -6467,10 +6137,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:7.0.2": - version: 7.0.2 - resolution: "@typescript-eslint/types@npm:7.0.2" - checksum: 5f95266cc2cd0e6cf1239dcd36b53c7d98b01ba12c61947316f0d879df87b912b4d23f0796324e2ab0fb8780503a338da41a4695fa91d90392b6c6aca5239fa7 +"@typescript-eslint/types@npm:7.9.0": + version: 7.9.0 + resolution: "@typescript-eslint/types@npm:7.9.0" + checksum: d5f4a547dba4865ee2391bf06f2b3f8e8592a561976d2be35bb61ce340c7d1b7b4b25ac6ab5b9941813b465b9420bebb7b2179b1d71f6a83069feeb000b3558d languageName: node linkType: hard @@ -6493,22 +6163,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.0.2": - version: 7.0.2 - resolution: "@typescript-eslint/typescript-estree@npm:7.0.2" +"@typescript-eslint/typescript-estree@npm:7.9.0": + version: 7.9.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.9.0" dependencies: - "@typescript-eslint/types": "npm:7.0.2" - "@typescript-eslint/visitor-keys": "npm:7.0.2" + "@typescript-eslint/types": "npm:7.9.0" + "@typescript-eslint/visitor-keys": "npm:7.9.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" - minimatch: "npm:9.0.3" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" peerDependenciesMeta: typescript: optional: true - checksum: 2f6795b05fced9f2e0887f6735aa1a0b20516952792e4be13cd94c5e56db8ad013ba27aeb56f89fedff8b7af587f854482f00aac75b418611c74e42169c29aeb + checksum: cfc3d2b7a5433c9a2989c7289bc72b49786993782801ad8ca5a07c651df457a67fbce13b120c86c34c03d56570a90e5cf4f3b8806349f103a3658f2366ec28ea languageName: node linkType: hard @@ -6529,20 +6199,17 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.0.2": - version: 7.0.2 - resolution: "@typescript-eslint/utils@npm:7.0.2" +"@typescript-eslint/utils@npm:7.9.0": + version: 7.9.0 + resolution: "@typescript-eslint/utils@npm:7.9.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@types/json-schema": "npm:^7.0.12" - "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.0.2" - "@typescript-eslint/types": "npm:7.0.2" - "@typescript-eslint/typescript-estree": "npm:7.0.2" - semver: "npm:^7.5.4" + "@typescript-eslint/scope-manager": "npm:7.9.0" + "@typescript-eslint/types": "npm:7.9.0" + "@typescript-eslint/typescript-estree": "npm:7.9.0" peerDependencies: eslint: ^8.56.0 - checksum: b4ae9a36393c92b332e99d70219d1ee056271261f7433924db804e5f06d97ca60408b9c7a655afce8a851982e7153243a625d6cc76fea764f767f96c8f3e16da + checksum: cb99d6a950e7da0319bc7b923a82c52c0798a14e837afee51b2295cfbde02e0a2ac8e0b5904cd7bd01d1b376c7a6ad3739101b486feaf2517c8640024deb88c7 languageName: node linkType: hard @@ -6556,13 +6223,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.0.2": - version: 7.0.2 - resolution: "@typescript-eslint/visitor-keys@npm:7.0.2" +"@typescript-eslint/visitor-keys@npm:7.9.0": + version: 7.9.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.9.0" dependencies: - "@typescript-eslint/types": "npm:7.0.2" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 4146d1ad6ce9374e6b5a75677fc709816bdc5fe324b1a857405f21dad23bb28c79cfd0555bc2a01c4af1d9e9ee81ff5e29ec41cc9d05b0b1101cc4264e7f21d1 + "@typescript-eslint/types": "npm:7.9.0" + eslint-visitor-keys: "npm:^3.4.3" + checksum: 19181d8b9d2d7bc43d5c8884661cd9a86ac316392b8e590187cc507442093a1ba2bef0cc22181b8298d5dc9f455abb73cffa4663451bdf32b1b7fe12160c5c99 languageName: node linkType: hard @@ -6586,12 +6253,12 @@ __metadata: linkType: hard "@urql/core@npm:>=2.3.6": - version: 4.2.3 - resolution: "@urql/core@npm:4.2.3" + version: 5.0.3 + resolution: "@urql/core@npm:5.0.3" dependencies: - "@0no-co/graphql.web": "npm:^1.0.1" + "@0no-co/graphql.web": "npm:^1.0.5" wonka: "npm:^6.3.2" - checksum: 2e2e5f94365c5513c6eb8d996d0b60211ca5ef122bfb7e77a192f63f8f469689ead2b232b835ce47f8127d7c9a5c8083548cac05f3b4be4f01f723dbfb575da0 + checksum: 7ae9dfe4cbce949a0e2856f46e5c0f62a1bdb6eda6f24480468b62f886cc03131e77b578da4fbb9fe8c1622b7542fdd371b83e7883f01a296924b5dfbe738f10 languageName: node linkType: hard @@ -6872,12 +6539,12 @@ __metadata: languageName: node linkType: hard -"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0": - version: 7.1.0 - resolution: "agent-base@npm:7.1.0" +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" dependencies: debug: "npm:^4.3.4" - checksum: fc974ab57ffdd8421a2bc339644d312a9cca320c20c3393c9d8b1fd91731b9bbabdb985df5fc860f5b79d81c3e350daa3fcb31c5c07c0bb385aafc817df004ce + checksum: e59ce7bed9c63bf071a30cc471f2933862044c97fd9958967bfe22521d7a0f601ce4ed5a8c011799d0c726ca70312142ae193bbebb60f576b52be19d4a363b50 languageName: node linkType: hard @@ -6930,27 +6597,27 @@ __metadata: linkType: hard "ajv@npm:^8.0.0, ajv@npm:^8.0.1, ajv@npm:^8.11.0, ajv@npm:^8.12.0": - version: 8.12.0 - resolution: "ajv@npm:8.12.0" + version: 8.13.0 + resolution: "ajv@npm:8.13.0" dependencies: - fast-deep-equal: "npm:^3.1.1" + fast-deep-equal: "npm:^3.1.3" json-schema-traverse: "npm:^1.0.0" require-from-string: "npm:^2.0.2" - uri-js: "npm:^4.2.2" - checksum: ac4f72adf727ee425e049bc9d8b31d4a57e1c90da8d28bcd23d60781b12fcd6fc3d68db5df16994c57b78b94eed7988f5a6b482fd376dc5b084125e20a0a622e + uri-js: "npm:^4.4.1" + checksum: 14c6497b6f72843986d7344175a1aa0e2c35b1e7f7475e55bc582cddb765fca7e6bf950f465dc7846f817776d9541b706f4b5b3fbedd8dfdeb5fce6f22864264 languageName: node linkType: hard "amazon-cognito-identity-js@npm:^6.0.1": - version: 6.3.11 - resolution: "amazon-cognito-identity-js@npm:6.3.11" + version: 6.3.13 + resolution: "amazon-cognito-identity-js@npm:6.3.13" dependencies: "@aws-crypto/sha256-js": "npm:1.2.2" buffer: "npm:4.9.2" fast-base64-decode: "npm:^1.0.0" isomorphic-unfetch: "npm:^3.0.0" js-cookie: "npm:^2.2.1" - checksum: 4619e4c19770722ac243c98fb7d4aff35eb0b8f5a2db9ea31a5765f5c54deb7245e316e7e9f633f07d70520f13be157fc90c6139c5f0f2ecc59e5e7d16ee76b1 + checksum: 274785ef26573969bcc12d8f36d1f529da7fd50068ee52c7e3213c61549ce319db7c477c8c11633fc7f6bfe114fd93071228720742c0b091bafe18e7c13536a8 languageName: node linkType: hard @@ -6994,11 +6661,9 @@ __metadata: linkType: hard "ansi-escapes@npm:^6.2.0": - version: 6.2.0 - resolution: "ansi-escapes@npm:6.2.0" - dependencies: - type-fest: "npm:^3.0.0" - checksum: 3eec75deedd8b10192c5f98e4cd9715cc3ff268d33fc463c24b7d22446668bfcd4ad1803993ea89c0f51f88b5a3399572bacb7c8cb1a067fc86e189c5f3b0c7e + version: 6.2.1 + resolution: "ansi-escapes@npm:6.2.1" + checksum: a2c6f58b044be5f69662ee17073229b492daa2425a7fd99a665db6c22eab6e4ab42752807def7281c1c7acfed48f87f2362dda892f08c2c437f1b39c6b033103 languageName: node linkType: hard @@ -7261,15 +6926,16 @@ __metadata: linkType: hard "array.prototype.findlast@npm:^1.2.2": - version: 1.2.4 - resolution: "array.prototype.findlast@npm:1.2.4" + version: 1.2.5 + resolution: "array.prototype.findlast@npm:1.2.5" dependencies: - call-bind: "npm:^1.0.5" + call-bind: "npm:^1.0.7" define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.22.3" + es-abstract: "npm:^1.23.2" es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" es-shim-unscopables: "npm:^1.0.2" - checksum: 4b5145a68ebaa00ef3d61de07c6694cad73d60763079f1e7662b948e5a167b5121b0c1e6feae8df1e42ead07c21699e25242b95cd5c48e094fd530b192aa4150 + checksum: ddc952b829145ab45411b9d6adcb51a8c17c76bf89c9dd64b52d5dffa65d033da8c076ed2e17091779e83bc892b9848188d7b4b33453c5565e65a92863cb2775 languageName: node linkType: hard @@ -7286,15 +6952,17 @@ __metadata: linkType: hard "array.prototype.reduce@npm:^1.0.6": - version: 1.0.6 - resolution: "array.prototype.reduce@npm:1.0.6" + version: 1.0.7 + resolution: "array.prototype.reduce@npm:1.0.7" dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" es-array-method-boxes-properly: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" is-string: "npm:^1.0.7" - checksum: 4082757ff094c372d94e5b5c7f7f12dae11cfdf41dec7cd7a54a528f6a92155442bac38eddd23a82be7e8fd9c458b124163e791cb5841372d02b1ba964a92816 + checksum: 97aac907d7b15088d5b991bad79de96f95ea0d47a701a034e2dc816e0aabaed2fb401d7fe65ab6fda05eafa58319aa2d1bac404f515e162b81b3b61a51224db2 languageName: node linkType: hard @@ -7328,15 +6996,14 @@ __metadata: languageName: node linkType: hard -"asn1.js@npm:^5.2.0": - version: 5.4.1 - resolution: "asn1.js@npm:5.4.1" +"asn1.js@npm:^4.10.1": + version: 4.10.1 + resolution: "asn1.js@npm:4.10.1" dependencies: bn.js: "npm:^4.0.0" inherits: "npm:^2.0.1" minimalistic-assert: "npm:^1.0.0" - safer-buffer: "npm:^2.1.0" - checksum: b577232fa6069cc52bb128e564002c62b2b1fe47f7137bdcd709c0b8495aa79cee0f8cc458a831b2d8675900eea0d05781b006be5e1aa4f0ae3577a73ec20324 + checksum: afa7f3ab9e31566c80175a75b182e5dba50589dcc738aa485be42bdd787e2a07246a4b034d481861123cbe646a7656f318f4f1cad2e9e5e808a210d5d6feaa88 languageName: node linkType: hard @@ -7402,7 +7069,7 @@ __metadata: languageName: node linkType: hard -"async-eventemitter@npm:^0.2.2, async-eventemitter@npm:^0.2.4": +"async-eventemitter@npm:^0.2.2": version: 0.2.4 resolution: "async-eventemitter@npm:0.2.4" dependencies: @@ -7505,7 +7172,7 @@ __metadata: languageName: node linkType: hard -"available-typed-arrays@npm:^1.0.6, available-typed-arrays@npm:^1.0.7": +"available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" dependencies: @@ -7548,13 +7215,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0, axios@npm:^1.5.1": - version: 1.6.7 - resolution: "axios@npm:1.6.7" + version: 1.6.8 + resolution: "axios@npm:1.6.8" dependencies: - follow-redirects: "npm:^1.15.4" + follow-redirects: "npm:^1.15.6" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: 131bf8e62eee48ca4bd84e6101f211961bf6a21a33b95e5dfb3983d5a2fe50d9fffde0b57668d7ce6f65063d3dc10f2212cbcb554f75cfca99da1c73b210358d + checksum: 0f22da6f490335479a89878bc7d5a1419484fbb437b564a80c34888fc36759ae4f56ea28d55a191695e5ed327f0bad56e7ff60fb6770c14d1be6501505d47ab9 languageName: node linkType: hard @@ -8326,7 +7993,7 @@ __metadata: languageName: node linkType: hard -"bigint-crypto-utils@npm:^3.0.23, bigint-crypto-utils@npm:^3.2.2": +"bigint-crypto-utils@npm:^3.0.23": version: 3.3.0 resolution: "bigint-crypto-utils@npm:3.3.0" checksum: 7d06fa01d63e8e9513eee629fe8a426993276b1bdca5aefd0eb3188cee7026334d29e801ef6187a5bc6105ebf26e6e79e6fab544a7da769ccf55b913e66d2a14 @@ -8348,9 +8015,9 @@ __metadata: linkType: hard "binary-extensions@npm:^2.0.0": - version: 2.2.0 - resolution: "binary-extensions@npm:2.2.0" - checksum: d73d8b897238a2d3ffa5f59c0241870043aa7471335e89ea5e1ff48edb7c2d0bb471517a3e4c5c3f4c043615caa2717b5f80a5e61e07503d51dc85cb848e665d + version: 2.3.0 + resolution: "binary-extensions@npm:2.3.0" + checksum: 75a59cafc10fb12a11d510e77110c6c7ae3f4ca22463d52487709ca7f18f69d886aa387557cc9864fbdb10153d0bdb4caacabf11541f55e89ed6e18d12ece2b5 languageName: node linkType: hard @@ -8651,7 +8318,7 @@ __metadata: languageName: node linkType: hard -"browserify-aes@npm:^1.0.0, browserify-aes@npm:^1.0.4, browserify-aes@npm:^1.2.0": +"browserify-aes@npm:^1.0.4, browserify-aes@npm:^1.2.0": version: 1.2.0 resolution: "browserify-aes@npm:1.2.0" dependencies: @@ -8699,19 +8366,20 @@ __metadata: linkType: hard "browserify-sign@npm:^4.0.0": - version: 4.2.2 - resolution: "browserify-sign@npm:4.2.2" + version: 4.2.3 + resolution: "browserify-sign@npm:4.2.3" dependencies: bn.js: "npm:^5.2.1" browserify-rsa: "npm:^4.1.0" create-hash: "npm:^1.2.0" create-hmac: "npm:^1.1.7" - elliptic: "npm:^6.5.4" + elliptic: "npm:^6.5.5" + hash-base: "npm:~3.0" inherits: "npm:^2.0.4" - parse-asn1: "npm:^5.1.6" - readable-stream: "npm:^3.6.2" + parse-asn1: "npm:^5.1.7" + readable-stream: "npm:^2.3.8" safe-buffer: "npm:^5.2.1" - checksum: 4d1292e5c165d93455630515003f0e95eed9239c99e2d373920c5b56903d16296a3d23cd4bdc4d298f55ad9b83714a9e63bc4839f1166c303349a16e84e9b016 + checksum: 30c0eba3f5970a20866a4d3fbba2c5bd1928cd24f47faf995f913f1499214c6f3be14bb4d6ec1ab5c6cafb1eca9cb76ba1c2e1c04ed018370634d4e659c77216 languageName: node linkType: hard @@ -8900,8 +8568,8 @@ __metadata: linkType: hard "cacache@npm:^18.0.0": - version: 18.0.2 - resolution: "cacache@npm:18.0.2" + version: 18.0.3 + resolution: "cacache@npm:18.0.3" dependencies: "@npmcli/fs": "npm:^3.1.0" fs-minipass: "npm:^3.0.0" @@ -8915,7 +8583,7 @@ __metadata: ssri: "npm:^10.0.0" tar: "npm:^6.1.11" unique-filename: "npm:^3.0.0" - checksum: 7992665305cc251a984f4fdbab1449d50e88c635bc43bf2785530c61d239c61b349e5734461baa461caaee65f040ab14e2d58e694f479c0810cffd181ba5eabc + checksum: dfda92840bb371fb66b88c087c61a74544363b37a265023223a99965b16a16bbb87661fe4948718d79df6e0cc04e85e62784fbcf1832b2a5e54ff4c46fbb45b7 languageName: node linkType: hard @@ -9082,9 +8750,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30000844, caniuse-lite@npm:^1.0.30001587": - version: 1.0.30001589 - resolution: "caniuse-lite@npm:1.0.30001589" - checksum: 20debfb949413f603011bc7dacaf050010778bc4f8632c86fafd1bd0c43180c95ae7c31f6c82348f6309e5e221934e327c3607a216e3f09640284acf78cd6d4d + version: 1.0.30001620 + resolution: "caniuse-lite@npm:1.0.30001620" + checksum: 3783117143fbdc98c1b91a579d0f2a7bcee7008f322ba7a2bf56a6c3d105400772c7ed8026840b4ea909ec7bf254bcc36532f2ce1b1a1240b00d0335da39b7ec languageName: node linkType: hard @@ -9139,13 +8807,13 @@ __metadata: linkType: hard "chai-as-promised@npm:^7.1.1": - version: 7.1.1 - resolution: "chai-as-promised@npm:7.1.1" + version: 7.1.2 + resolution: "chai-as-promised@npm:7.1.2" dependencies: check-error: "npm:^1.0.2" peerDependencies: - chai: ">= 2.1.2 < 5" - checksum: e25a602c3a8cd0b97ce6b0c7ddaaf4bd8517941da9f44dc65262c5268ea463f634dc495cdef6a21eaeffdb5022b6f4c3781027b8308273b7fff089c605abf6aa + chai: ">= 2.1.2 < 6" + checksum: ee20ed75296d8cbf828b2f3c9ad64627cee67b1a38b8e906ca59fe788fb6965ddb10f702ae66645ed88f15a905ade4f2d9f8540029e92e2d59b229c9f912273f languageName: node linkType: hard @@ -9501,15 +9169,15 @@ __metadata: linkType: hard "cli-table3@npm:^0.6.0, cli-table3@npm:^0.6.2": - version: 0.6.3 - resolution: "cli-table3@npm:0.6.3" + version: 0.6.5 + resolution: "cli-table3@npm:0.6.5" dependencies: "@colors/colors": "npm:1.5.0" string-width: "npm:^4.2.0" dependenciesMeta: "@colors/colors": optional: true - checksum: 39e580cb346c2eaf1bd8f4ff055ae644e902b8303c164a1b8894c0dc95941f92e001db51f49649011be987e708d9fa3183ccc2289a4d376a057769664048cc0c + checksum: d7cc9ed12212ae68241cc7a3133c52b844113b17856e11f4f81308acc3febcea7cc9fd298e70933e294dd642866b29fd5d113c2c098948701d0c35f09455de78 languageName: node linkType: hard @@ -10071,6 +9739,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:0.6.0": + version: 0.6.0 + resolution: "cookie@npm:0.6.0" + checksum: f2318b31af7a31b4ddb4a678d024514df5e705f9be5909a192d7f116cfb6d45cbacf96a473fa733faa95050e7cff26e7832bb3ef94751592f1387b71c8956686 + languageName: node + linkType: hard + "cookiejar@npm:^2.1.1": version: 2.1.4 resolution: "cookiejar@npm:2.1.4" @@ -10086,9 +9761,9 @@ __metadata: linkType: hard "core-js-pure@npm:^3.0.1": - version: 3.36.0 - resolution: "core-js-pure@npm:3.36.0" - checksum: 1c5ecb37451bcebaa449e36285d27c4c79d5ff24b8bfd44491ce661cfc12b5c56471c847d306d21a56894338d00abea4993a6f8e07c71d4e887d1f71e410d22e + version: 3.37.1 + resolution: "core-js-pure@npm:3.37.1" + checksum: 38200d08862b4ef2207af72a7525f7b9ac750f5e1d84ef27a3e314aefa69518179a9b732f51ebe35c3b38606d9fa4f686fcf6eff067615cc293a3b1c84041e74 languageName: node linkType: hard @@ -10364,13 +10039,13 @@ __metadata: languageName: node linkType: hard -"d@npm:1, d@npm:^1.0.1": - version: 1.0.1 - resolution: "d@npm:1.0.1" +"d@npm:1, d@npm:^1.0.1, d@npm:^1.0.2": + version: 1.0.2 + resolution: "d@npm:1.0.2" dependencies: - es5-ext: "npm:^0.10.50" - type: "npm:^1.0.1" - checksum: 1fedcb3b956a461f64d86b94b347441beff5cef8910b6ac4ec509a2c67eeaa7093660a98b26601ac91f91260238add73bdf25867a9c0cb783774642bc4c1523f + es5-ext: "npm:^0.10.64" + type: "npm:^2.7.2" + checksum: 3e6ede10cd3b77586c47da48423b62bed161bf1a48bdbcc94d87263522e22f5dfb0e678a6dba5323fdc14c5d8612b7f7eb9e7d9e37b2e2d67a7bf9f116dabe5a languageName: node linkType: hard @@ -10390,6 +10065,39 @@ __metadata: languageName: node linkType: hard +"data-view-buffer@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-buffer@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.6" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 8984119e59dbed906a11fcfb417d7d861936f16697a0e7216fe2c6c810f6b5e8f4a5281e73f2c28e8e9259027190ac4a33e2a65fdd7fa86ac06b76e838918583 + languageName: node + linkType: hard + +"data-view-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-length@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: b7d9e48a0cf5aefed9ab7d123559917b2d7e0d65531f43b2fd95b9d3a6b46042dd3fca597c42bba384e66b70d7ad66ff23932f8367b241f53d93af42cfe04ec2 + languageName: node + linkType: hard + +"data-view-byte-offset@npm:^1.0.0": + version: 1.0.0 + resolution: "data-view-byte-offset@npm:1.0.0" + dependencies: + call-bind: "npm:^1.0.6" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 21b0d2e53fd6e20cc4257c873bf6d36d77bd6185624b84076c0a1ddaa757b49aaf076254006341d35568e89f52eecd1ccb1a502cfb620f2beca04f48a6a62a8f + languageName: node + linkType: hard + "dataloader@npm:2.2.2, dataloader@npm:^2.2.2": version: 2.2.2 resolution: "dataloader@npm:2.2.2" @@ -10594,7 +10302,7 @@ __metadata: languageName: node linkType: hard -"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.1, define-data-property@npm:^1.1.2, define-data-property@npm:^1.1.4": +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.1, define-data-property@npm:^1.1.4": version: 1.1.4 resolution: "define-data-property@npm:1.1.4" dependencies: @@ -10612,7 +10320,7 @@ __metadata: languageName: node linkType: hard -"define-properties@npm:^1.1.3, define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": +"define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": version: 1.2.1 resolution: "define-properties@npm:1.2.1" dependencies: @@ -10748,15 +10456,15 @@ __metadata: linkType: hard "detect-port@npm:^1.3.0": - version: 1.5.1 - resolution: "detect-port@npm:1.5.1" + version: 1.6.1 + resolution: "detect-port@npm:1.6.1" dependencies: address: "npm:^1.0.1" debug: "npm:4" bin: detect: bin/detect-port.js detect-port: bin/detect-port.js - checksum: f2b204ad3a9f8e8b53fea35fcc97469f31a8e3e786a2f59fbc886397e33b5f130c5f964bf001b9a64d990047c3824f6a439308461ff19801df04ab48a754639e + checksum: 4ea9eb46a637cb21220dd0a62b6074792894fc77b2cacbc9de533d1908b2eedafa7bfd7547baaa2ac1e9c7ba7c289b34b17db896dca6da142f4fc6e2060eee17 languageName: node linkType: hard @@ -10927,14 +10635,14 @@ __metadata: linkType: hard "duplexify@npm:^4.1.1, duplexify@npm:^4.1.2": - version: 4.1.2 - resolution: "duplexify@npm:4.1.2" + version: 4.1.3 + resolution: "duplexify@npm:4.1.3" dependencies: end-of-stream: "npm:^1.4.1" inherits: "npm:^2.0.3" readable-stream: "npm:^3.1.1" - stream-shift: "npm:^1.0.0" - checksum: cacd09d8f1c58f92f83e17dffc14ece50415b32753446ed92046236a27a9e73cb914cda495d955ea12e0e615381082a511f20e219f48a06e84675c9d6950675b + stream-shift: "npm:^1.0.2" + checksum: 8a7621ae95c89f3937f982fe36d72ea997836a708471a75bb2a0eecde3330311b1e128a6dad510e0fd64ace0c56bff3484ed2e82af0e465600c82117eadfbda5 languageName: node linkType: hard @@ -10963,13 +10671,13 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.3.47, electron-to-chromium@npm:^1.4.668": - version: 1.4.681 - resolution: "electron-to-chromium@npm:1.4.681" - checksum: 5b2558dfb8bb82c20fb5fa1d9bbe06a3add47431dc3e1e4815e997be6ad387787047d9e534ed96839a9e7012520a5281c865158b09db41d10c029af003f05f94 + version: 1.4.774 + resolution: "electron-to-chromium@npm:1.4.774" + checksum: dc957ee574d14838abd16f48fb3e4bd069bf47807fe02144b850d4903265810e17abc5800a361941f787bd78692cf4f81eab70046a6757eb39e44c91ff520dd4 languageName: node linkType: hard -"elliptic@npm:6.5.4, elliptic@npm:^6.4.0, elliptic@npm:^6.5.2, elliptic@npm:^6.5.3, elliptic@npm:^6.5.4": +"elliptic@npm:6.5.4": version: 6.5.4 resolution: "elliptic@npm:6.5.4" dependencies: @@ -10984,6 +10692,21 @@ __metadata: languageName: node linkType: hard +"elliptic@npm:^6.4.0, elliptic@npm:^6.5.2, elliptic@npm:^6.5.3, elliptic@npm:^6.5.4, elliptic@npm:^6.5.5": + version: 6.5.5 + resolution: "elliptic@npm:6.5.5" + dependencies: + bn.js: "npm:^4.11.9" + brorand: "npm:^1.1.0" + hash.js: "npm:^1.0.0" + hmac-drbg: "npm:^1.0.1" + inherits: "npm:^2.0.4" + minimalistic-assert: "npm:^1.0.1" + minimalistic-crypto-utils: "npm:^1.0.1" + checksum: 3e591e93783a1b66f234ebf5bd3a8a9a8e063a75073a35a671e03e3b25253b6e33ac121f7efe9b8808890fffb17b40596cc19d01e6e8d1fa13b9a56ff65597c8 + languageName: node + linkType: hard + "emoji-regex@npm:^10.3.0": version: 10.3.0 resolution: "emoji-regex@npm:10.3.0" @@ -11115,17 +10838,21 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3": - version: 1.22.4 - resolution: "es-abstract@npm:1.22.4" +"es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.2": + version: 1.23.3 + resolution: "es-abstract@npm:1.23.3" dependencies: array-buffer-byte-length: "npm:^1.0.1" arraybuffer.prototype.slice: "npm:^1.0.3" - available-typed-arrays: "npm:^1.0.6" + available-typed-arrays: "npm:^1.0.7" call-bind: "npm:^1.0.7" + data-view-buffer: "npm:^1.0.1" + data-view-byte-length: "npm:^1.0.1" + data-view-byte-offset: "npm:^1.0.0" es-define-property: "npm:^1.0.0" es-errors: "npm:^1.3.0" - es-set-tostringtag: "npm:^2.0.2" + es-object-atoms: "npm:^1.0.0" + es-set-tostringtag: "npm:^2.0.3" es-to-primitive: "npm:^1.2.1" function.prototype.name: "npm:^1.1.6" get-intrinsic: "npm:^1.2.4" @@ -11133,15 +10860,16 @@ __metadata: globalthis: "npm:^1.0.3" gopd: "npm:^1.0.1" has-property-descriptors: "npm:^1.0.2" - has-proto: "npm:^1.0.1" + has-proto: "npm:^1.0.3" has-symbols: "npm:^1.0.3" - hasown: "npm:^2.0.1" + hasown: "npm:^2.0.2" internal-slot: "npm:^1.0.7" is-array-buffer: "npm:^3.0.4" is-callable: "npm:^1.2.7" - is-negative-zero: "npm:^2.0.2" + is-data-view: "npm:^1.0.1" + is-negative-zero: "npm:^2.0.3" is-regex: "npm:^1.1.4" - is-shared-array-buffer: "npm:^1.0.2" + is-shared-array-buffer: "npm:^1.0.3" is-string: "npm:^1.0.7" is-typed-array: "npm:^1.1.13" is-weakref: "npm:^1.0.2" @@ -11149,18 +10877,18 @@ __metadata: object-keys: "npm:^1.1.1" object.assign: "npm:^4.1.5" regexp.prototype.flags: "npm:^1.5.2" - safe-array-concat: "npm:^1.1.0" + safe-array-concat: "npm:^1.1.2" safe-regex-test: "npm:^1.0.3" - string.prototype.trim: "npm:^1.2.8" - string.prototype.trimend: "npm:^1.0.7" - string.prototype.trimstart: "npm:^1.0.7" - typed-array-buffer: "npm:^1.0.1" - typed-array-byte-length: "npm:^1.0.0" - typed-array-byte-offset: "npm:^1.0.0" - typed-array-length: "npm:^1.0.4" + string.prototype.trim: "npm:^1.2.9" + string.prototype.trimend: "npm:^1.0.8" + string.prototype.trimstart: "npm:^1.0.8" + typed-array-buffer: "npm:^1.0.2" + typed-array-byte-length: "npm:^1.0.1" + typed-array-byte-offset: "npm:^1.0.2" + typed-array-length: "npm:^1.0.6" unbox-primitive: "npm:^1.0.2" - which-typed-array: "npm:^1.1.14" - checksum: dc332c3a010c5e7b77b7ea8a4532ac455fa02e7bcabf996a47447165bafa72d0d99967407d0cf5dbbb5fbbf87f53cd8b706608ec70953523b8cd2b831b9a9d64 + which-typed-array: "npm:^1.1.15" + checksum: d27e9afafb225c6924bee9971a7f25f20c314f2d6cb93a63cada4ac11dcf42040896a6c22e5fb8f2a10767055ed4ddf400be3b1eb12297d281726de470b75666 languageName: node linkType: hard @@ -11187,7 +10915,16 @@ __metadata: languageName: node linkType: hard -"es-set-tostringtag@npm:^2.0.2": +"es-object-atoms@npm:^1.0.0": + version: 1.0.0 + resolution: "es-object-atoms@npm:1.0.0" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 1fed3d102eb27ab8d983337bb7c8b159dd2a1e63ff833ec54eea1311c96d5b08223b433060ba240541ca8adba9eee6b0a60cdbf2f80634b784febc9cc8b687b4 + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.0.3": version: 2.0.3 resolution: "es-set-tostringtag@npm:2.0.3" dependencies: @@ -11218,15 +10955,15 @@ __metadata: languageName: node linkType: hard -"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.50, es5-ext@npm:^0.10.62, es5-ext@npm:~0.10.14": - version: 0.10.63 - resolution: "es5-ext@npm:0.10.63" +"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.50, es5-ext@npm:^0.10.62, es5-ext@npm:^0.10.63, es5-ext@npm:^0.10.64, es5-ext@npm:~0.10.14": + version: 0.10.64 + resolution: "es5-ext@npm:0.10.64" dependencies: es6-iterator: "npm:^2.0.3" es6-symbol: "npm:^3.1.3" esniff: "npm:^2.0.1" next-tick: "npm:^1.1.0" - checksum: 1f20f9c73dc43cca9f1aa6908062f0a3d0bf3cee229a11a2cda6d4eca83583ceeb9b59ad36e951aa6e41ddd06d81aafac9a01de3d38a76b86f598a69ad0456bd + checksum: 4459b6ae216f3c615db086e02437bdfde851515a101577fd61b19f9b3c1ad924bab4d197981eb7f0ccb915f643f2fc10ff76b97a680e96cbb572d15a27acd9a3 languageName: node linkType: hard @@ -11249,16 +10986,16 @@ __metadata: linkType: hard "es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": - version: 3.1.3 - resolution: "es6-symbol@npm:3.1.3" + version: 3.1.4 + resolution: "es6-symbol@npm:3.1.4" dependencies: - d: "npm:^1.0.1" - ext: "npm:^1.1.2" - checksum: 22982f815f00df553a89f4fb74c5048fed85df598482b4bd38dbd173174247949c72982a7d7132a58b147525398400e5f182db59b0916cb49f1e245fb0e22233 + d: "npm:^1.0.2" + ext: "npm:^1.7.0" + checksum: 777bf3388db5d7919e09a0fd175aa5b8a62385b17cb2227b7a137680cba62b4d9f6193319a102642aa23d5840d38a62e4784f19cfa5be4a2210a3f0e9b23d15d languageName: node linkType: hard -"escalade@npm:^3.1.1": +"escalade@npm:^3.1.1, escalade@npm:^3.1.2": version: 3.1.2 resolution: "escalade@npm:3.1.2" checksum: 6b4adafecd0682f3aa1cd1106b8fff30e492c7015b178bc81b2d2f75106dabea6c6d6e8508fc491bd58e597c74abb0e8e2368f943ecb9393d4162e3c2f3cf287 @@ -11386,55 +11123,7 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.52.0, eslint@npm:^8.56.0": - version: 8.56.0 - resolution: "eslint@npm:8.56.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.56.0" - "@humanwhocodes/config-array": "npm:^0.11.13" - "@humanwhocodes/module-importer": "npm:^1.0.1" - "@nodelib/fs.walk": "npm:^1.2.8" - "@ungap/structured-clone": "npm:^1.2.0" - ajv: "npm:^6.12.4" - chalk: "npm:^4.0.0" - cross-spawn: "npm:^7.0.2" - debug: "npm:^4.3.2" - doctrine: "npm:^3.0.0" - escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^7.2.2" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" - esquery: "npm:^1.4.2" - esutils: "npm:^2.0.2" - fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^6.0.1" - find-up: "npm:^5.0.0" - glob-parent: "npm:^6.0.2" - globals: "npm:^13.19.0" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.0" - imurmurhash: "npm:^0.1.4" - is-glob: "npm:^4.0.0" - is-path-inside: "npm:^3.0.3" - js-yaml: "npm:^4.1.0" - json-stable-stringify-without-jsonify: "npm:^1.0.1" - levn: "npm:^0.4.1" - lodash.merge: "npm:^4.6.2" - minimatch: "npm:^3.1.2" - natural-compare: "npm:^1.4.0" - optionator: "npm:^0.9.3" - strip-ansi: "npm:^6.0.1" - text-table: "npm:^0.2.0" - bin: - eslint: bin/eslint.js - checksum: 2be598f7da1339d045ad933ffd3d4742bee610515cd2b0d9a2b8b729395a01d4e913552fff555b559fccaefd89d7b37632825789d1b06470608737ae69ab43fb - languageName: node - linkType: hard - -"eslint@npm:^8.57.0": +"eslint@npm:^8.52.0, eslint@npm:^8.56.0, eslint@npm:^8.57.0": version: 8.57.0 resolution: "eslint@npm:8.57.0" dependencies: @@ -11745,11 +11434,11 @@ __metadata: linkType: hard "ethereum-bloom-filters@npm:^1.0.6": - version: 1.0.10 - resolution: "ethereum-bloom-filters@npm:1.0.10" + version: 1.1.0 + resolution: "ethereum-bloom-filters@npm:1.1.0" dependencies: - js-sha3: "npm:^0.8.0" - checksum: ae70b0b0b6d83beece65638a634818f0bd1d00d7a4447e17b83797f4d8db4c49491b57119c5ed081c008fb766bb8f230f3603187fd6649d58a8cf3b9aa91549c + "@noble/hashes": "npm:^1.4.0" + checksum: 54b0b7a1fdf12fe02fc8f605f213d11ea026111b9d2af79ff58e8319c904d9d6cee77c62fe70bee62c4d0c7952caf58ebaf47a889d9e4199cf4da1a361a87b53 languageName: node linkType: hard @@ -12206,8 +11895,8 @@ __metadata: linkType: hard "ethers@npm:^6.4.0": - version: 6.11.1 - resolution: "ethers@npm:6.11.1" + version: 6.12.1 + resolution: "ethers@npm:6.12.1" dependencies: "@adraffy/ens-normalize": "npm:1.10.1" "@noble/curves": "npm:1.2.0" @@ -12216,7 +11905,7 @@ __metadata: aes-js: "npm:4.0.0-beta.5" tslib: "npm:2.4.0" ws: "npm:8.5.0" - checksum: 97a920e0244ba6cd1622b58a448c87f26dad20bad242777abb2e583d045bf7752218477bd7367ba6518c2a5e2b16030afff15e87b705526d0ea667498c27ac89 + checksum: 7686e1efdb0a831578f35d69188783c225de5a6fbb1b422327bc45cee04d49a2707e73c9342a6a5eb2870ce35668c71372737439ec3993d31d83f4a0e2446cc7 languageName: node linkType: hard @@ -12463,7 +12152,7 @@ __metadata: languageName: node linkType: hard -"express@npm:4.18.2, express@npm:^4.14.0": +"express@npm:4.18.2": version: 4.18.2 resolution: "express@npm:4.18.2" dependencies: @@ -12502,16 +12191,16 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.18.1": - version: 4.18.3 - resolution: "express@npm:4.18.3" +"express@npm:^4.14.0, express@npm:^4.18.1": + version: 4.19.2 + resolution: "express@npm:4.19.2" dependencies: accepts: "npm:~1.3.8" array-flatten: "npm:1.1.1" body-parser: "npm:1.20.2" content-disposition: "npm:0.5.4" content-type: "npm:~1.0.4" - cookie: "npm:0.5.0" + cookie: "npm:0.6.0" cookie-signature: "npm:1.0.6" debug: "npm:2.6.9" depd: "npm:2.0.0" @@ -12537,11 +12226,11 @@ __metadata: type-is: "npm:~1.6.18" utils-merge: "npm:1.0.1" vary: "npm:~1.1.2" - checksum: 0b9eeafbac549e3c67d92d083bf1773e358359f41ad142b92121935c6348d29079b75054555b3f62de39263fffc8ba06898b09fdd3e213e28e714c03c5d9f44c + checksum: e82e2662ea9971c1407aea9fc3c16d6b963e55e3830cd0ef5e00b533feda8b770af4e3be630488ef8a752d7c75c4fcefb15892868eeaafe7353cb9e3e269fdcb languageName: node linkType: hard -"ext@npm:^1.1.2": +"ext@npm:^1.7.0": version: 1.7.0 resolution: "ext@npm:1.7.0" dependencies: @@ -12728,9 +12417,9 @@ __metadata: linkType: hard "fast-redact@npm:^3.0.0": - version: 3.3.0 - resolution: "fast-redact@npm:3.3.0" - checksum: d81562510681e9ba6404ee5d3838ff5257a44d2f80937f5024c099049ff805437d0fae0124458a7e87535cc9dcf4de305bb075cab8f08d6c720bbc3447861b4e + version: 3.5.0 + resolution: "fast-redact@npm:3.5.0" + checksum: 7e2ce4aad6e7535e0775bf12bd3e4f2e53d8051d8b630e0fa9e67f68cb0b0e6070d2f7a94b1d0522ef07e32f7c7cda5755e2b677a6538f1e9070ca053c42343a languageName: node linkType: hard @@ -13059,17 +12748,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.12.1, follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.15.4": - version: 1.15.5 - resolution: "follow-redirects@npm:1.15.5" - peerDependenciesMeta: - debug: - optional: true - checksum: 418d71688ceaf109dfd6f85f747a0c75de30afe43a294caa211def77f02ef19865b547dfb73fde82b751e1cc507c06c754120b848fe5a7400b0a669766df7615 - languageName: node - linkType: hard - -"follow-redirects@npm:^1.14.9": +"follow-redirects@npm:^1.12.1, follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.14.9, follow-redirects@npm:^1.15.6": version: 1.15.6 resolution: "follow-redirects@npm:1.15.6" peerDependenciesMeta: @@ -13484,7 +13163,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": +"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": version: 1.2.4 resolution: "get-intrinsic@npm:1.2.4" dependencies: @@ -13704,17 +13383,17 @@ __metadata: linkType: hard "glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7": - version: 10.3.10 - resolution: "glob@npm:10.3.10" + version: 10.3.15 + resolution: "glob@npm:10.3.15" dependencies: foreground-child: "npm:^3.1.0" - jackspeak: "npm:^2.3.5" + jackspeak: "npm:^2.3.6" minimatch: "npm:^9.0.1" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry: "npm:^1.10.1" + minipass: "npm:^7.0.4" + path-scurry: "npm:^1.11.0" bin: glob: dist/esm/bin.mjs - checksum: 13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d + checksum: cda748ddc181b31b3df9548c0991800406d5cc3b3f8110e37a8751ec1e39f37cdae7d7782d5422d7df92775121cdf00599992dff22f7ff1260344843af227c2b languageName: node linkType: hard @@ -13808,11 +13487,12 @@ __metadata: linkType: hard "globalthis@npm:^1.0.3": - version: 1.0.3 - resolution: "globalthis@npm:1.0.3" + version: 1.0.4 + resolution: "globalthis@npm:1.0.4" dependencies: - define-properties: "npm:^1.1.3" - checksum: 0db6e9af102a5254630351557ac15e6909bc7459d3e3f6b001e59fe784c96d31108818f032d9095739355a88467459e6488ff16584ee6250cd8c27dec05af4b0 + define-properties: "npm:^1.2.1" + gopd: "npm:^1.0.1" + checksum: 9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846 languageName: node linkType: hard @@ -13991,11 +13671,11 @@ __metadata: linkType: hard "graphql-ws@npm:^5.12.1": - version: 5.15.0 - resolution: "graphql-ws@npm:5.15.0" + version: 5.16.0 + resolution: "graphql-ws@npm:5.16.0" peerDependencies: graphql: ">=0.11 <=16" - checksum: 4fcd93ed75261681b1def8cd96d1db0fc650586b145325b3fc134ab9c27ed48fbedad3e8261e3f3df65758a332d0420b8c60e13abb1ee8329ef624e312b61ccc + checksum: 5e538c3460ca997a1634bd0f64236d8d7aa6ac75c58aba549b49953faf0dd2497f4fa43eedb0bc82cfff50426c7ce47682a670d2571fd7f3af5dcf00911c9e1b languageName: node linkType: hard @@ -14049,7 +13729,7 @@ __metadata: languageName: node linkType: hard -"handlebars@npm:^4.0.1": +"handlebars@npm:^4.0.1, handlebars@npm:^4.7.7": version: 4.7.8 resolution: "handlebars@npm:4.7.8" dependencies: @@ -14103,7 +13783,7 @@ __metadata: languageName: node linkType: hard -"hardhat-contract-sizer@npm:^2.0.1, hardhat-contract-sizer@npm:^2.0.3": +"hardhat-contract-sizer@npm:^2.0.1, hardhat-contract-sizer@npm:^2.0.3, hardhat-contract-sizer@npm:^2.10.0": version: 2.10.0 resolution: "hardhat-contract-sizer@npm:2.10.0" dependencies: @@ -14218,114 +13898,57 @@ __metadata: prompt-sync: "npm:^4.2.0" peerDependencies: "@nomiclabs/hardhat-ethers": ^2.1.1 - ethers: ^5.0.0 - hardhat: ^2.0.0 - checksum: 5cf999c706f2baa4b03898ebed5ce302ff202156b2637434748072b6250f0967e1d580c8b07b52068558adb2eba178c6aff1543877672cbd57dd34a987e46604 - languageName: node - linkType: hard - -"hardhat-storage-layout@npm:0.1.6": - version: 0.1.6 - resolution: "hardhat-storage-layout@npm:0.1.6" - dependencies: - console-table-printer: "npm:^2.9.0" - peerDependencies: - hardhat: ^2.0.3 - checksum: f88e6aaedf65281c161d4b70b94417812e3ca36d7af39d0f9bf0711d62bf0c282c41d148cad8a99964824a8a19f0eb6861666bf04244ff8f4df3c292d51fc443 - languageName: node - linkType: hard - -"hardhat-tracer@npm:^1.0.0-alpha.6": - version: 1.3.0 - resolution: "hardhat-tracer@npm:1.3.0" - dependencies: - ethers: "npm:^5.6.1" - peerDependencies: - chalk: 4.x - ethers: 5.x - hardhat: 2.x - checksum: 488d8e704cc5ddcd9d536b33d1dc8a126b129ee24c8ff3b345bfc14703b251621ab606de2587a2aef6ae9b23bdf051d83997c7adb002add357a097a9deca3ecb - languageName: node - linkType: hard - -"hardhat@npm:^2.20.1": - version: 2.21.0 - resolution: "hardhat@npm:2.21.0" - dependencies: - "@ethersproject/abi": "npm:^5.1.2" - "@metamask/eth-sig-util": "npm:^4.0.0" - "@nomicfoundation/edr": "npm:^0.2.0" - "@nomicfoundation/ethereumjs-common": "npm:4.0.4" - "@nomicfoundation/ethereumjs-tx": "npm:5.0.4" - "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - "@nomicfoundation/solidity-analyzer": "npm:^0.1.0" - "@sentry/node": "npm:^5.18.1" - "@types/bn.js": "npm:^5.1.0" - "@types/lru-cache": "npm:^5.1.0" - adm-zip: "npm:^0.4.16" - aggregate-error: "npm:^3.0.0" - ansi-escapes: "npm:^4.3.0" - boxen: "npm:^5.1.2" - chalk: "npm:^2.4.2" - chokidar: "npm:^3.4.0" - ci-info: "npm:^2.0.0" - debug: "npm:^4.1.1" - enquirer: "npm:^2.3.0" - env-paths: "npm:^2.2.0" - ethereum-cryptography: "npm:^1.0.3" - ethereumjs-abi: "npm:^0.6.8" - find-up: "npm:^2.1.0" - fp-ts: "npm:1.19.3" - fs-extra: "npm:^7.0.1" - glob: "npm:7.2.0" - immutable: "npm:^4.0.0-rc.12" - io-ts: "npm:1.10.4" - keccak: "npm:^3.0.2" - lodash: "npm:^4.17.11" - mnemonist: "npm:^0.38.0" - mocha: "npm:^10.0.0" - p-map: "npm:^4.0.0" - raw-body: "npm:^2.4.1" - resolve: "npm:1.17.0" - semver: "npm:^6.3.0" - solc: "npm:0.7.3" - source-map-support: "npm:^0.5.13" - stacktrace-parser: "npm:^0.1.10" - tsort: "npm:0.0.1" - undici: "npm:^5.14.0" - uuid: "npm:^8.3.2" - ws: "npm:^7.4.6" + ethers: ^5.0.0 + hardhat: ^2.0.0 + checksum: 5cf999c706f2baa4b03898ebed5ce302ff202156b2637434748072b6250f0967e1d580c8b07b52068558adb2eba178c6aff1543877672cbd57dd34a987e46604 + languageName: node + linkType: hard + +"hardhat-storage-layout@npm:0.1.6": + version: 0.1.6 + resolution: "hardhat-storage-layout@npm:0.1.6" + dependencies: + console-table-printer: "npm:^2.9.0" peerDependencies: - ts-node: "*" - typescript: "*" - peerDependenciesMeta: - ts-node: - optional: true - typescript: - optional: true - bin: - hardhat: internal/cli/bootstrap.js - checksum: d7c887d147ddbd0792b5e64abfd8200c233a1815b91af908f68b167067e109f9ab6e0892d130137a745c6139bae691cee62a8e993290d4fc0a2a733e5dcce324 + hardhat: ^2.0.3 + checksum: f88e6aaedf65281c161d4b70b94417812e3ca36d7af39d0f9bf0711d62bf0c282c41d148cad8a99964824a8a19f0eb6861666bf04244ff8f4df3c292d51fc443 + languageName: node + linkType: hard + +"hardhat-storage-layout@npm:^0.1.7": + version: 0.1.7 + resolution: "hardhat-storage-layout@npm:0.1.7" + dependencies: + console-table-printer: "npm:^2.9.0" + peerDependencies: + hardhat: ^2.0.3 + checksum: 257b52a079183953d079ae221d05551391ff57adbad1ba033a3ccfa1b9df495ddd29285e67a7d03da484aa69f65850feb64a9bd7e37f53c549efd3833ed8b38c + languageName: node + linkType: hard + +"hardhat-tracer@npm:^1.0.0-alpha.6": + version: 1.3.0 + resolution: "hardhat-tracer@npm:1.3.0" + dependencies: + ethers: "npm:^5.6.1" + peerDependencies: + chalk: 4.x + ethers: 5.x + hardhat: 2.x + checksum: 488d8e704cc5ddcd9d536b33d1dc8a126b129ee24c8ff3b345bfc14703b251621ab606de2587a2aef6ae9b23bdf051d83997c7adb002add357a097a9deca3ecb languageName: node linkType: hard -"hardhat@npm:^2.6.1, hardhat@npm:^2.6.4": - version: 2.20.1 - resolution: "hardhat@npm:2.20.1" +"hardhat@npm:^2.20.1, hardhat@npm:^2.6.1, hardhat@npm:^2.6.4": + version: 2.22.4 + resolution: "hardhat@npm:2.22.4" dependencies: "@ethersproject/abi": "npm:^5.1.2" "@metamask/eth-sig-util": "npm:^4.0.0" - "@nomicfoundation/ethereumjs-block": "npm:5.0.4" - "@nomicfoundation/ethereumjs-blockchain": "npm:7.0.4" + "@nomicfoundation/edr": "npm:^0.3.7" "@nomicfoundation/ethereumjs-common": "npm:4.0.4" - "@nomicfoundation/ethereumjs-evm": "npm:2.0.4" - "@nomicfoundation/ethereumjs-rlp": "npm:5.0.4" - "@nomicfoundation/ethereumjs-statemanager": "npm:2.0.4" - "@nomicfoundation/ethereumjs-trie": "npm:6.0.4" "@nomicfoundation/ethereumjs-tx": "npm:5.0.4" "@nomicfoundation/ethereumjs-util": "npm:9.0.4" - "@nomicfoundation/ethereumjs-verkle": "npm:0.0.2" - "@nomicfoundation/ethereumjs-vm": "npm:7.0.4" "@nomicfoundation/solidity-analyzer": "npm:^0.1.0" "@sentry/node": "npm:^5.18.1" "@types/bn.js": "npm:^5.1.0" @@ -14373,7 +13996,7 @@ __metadata: optional: true bin: hardhat: internal/cli/bootstrap.js - checksum: e27f1fc6b016d7ceb62795ff47384a02ad61722cdd2ab55c91d7ff2ce31973a1ea5e462431c7033ca53e66e4722c3597664b0ebaac70104622d227e94b4fb3e0 + checksum: b9f51c40bc0d392dedb7fe866da30115a9c120b89eafe1f0afcda3cf1b379d7163e6a33a9b7a8ba78df795b477c2fd2d83ace8eb992668271b610786e320d5b7 languageName: node linkType: hard @@ -14489,7 +14112,7 @@ __metadata: languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.1, has-property-descriptors@npm:^1.0.2": +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": version: 1.0.2 resolution: "has-property-descriptors@npm:1.0.2" dependencies: @@ -14512,7 +14135,7 @@ __metadata: languageName: node linkType: hard -"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.1, has-tostringtag@npm:^1.0.2": +"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": version: 1.0.2 resolution: "has-tostringtag@npm:1.0.2" dependencies: @@ -14578,6 +14201,16 @@ __metadata: languageName: node linkType: hard +"hash-base@npm:~3.0": + version: 3.0.4 + resolution: "hash-base@npm:3.0.4" + dependencies: + inherits: "npm:^2.0.1" + safe-buffer: "npm:^5.0.1" + checksum: a13357dccb3827f0bb0b56bf928da85c428dc8670f6e4a1c7265e4f1653ce02d69030b40fd01b0f1d218a995a066eea279cded9cec72d207b593bcdfe309c2f0 + languageName: node + linkType: hard + "hash-it@npm:^6.0.0": version: 6.0.0 resolution: "hash-it@npm:6.0.0" @@ -14605,12 +14238,12 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.0, hasown@npm:^2.0.1": - version: 2.0.1 - resolution: "hasown@npm:2.0.1" +"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" dependencies: function-bind: "npm:^1.1.2" - checksum: 9e27e70e8e4204f4124c8f99950d1ba2b1f5174864fd39ff26da190f9ea6488c1b3927dcc64981c26d1f637a971783c9489d62c829d393ea509e6f1ba20370bb + checksum: 3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9 languageName: node linkType: hard @@ -14923,7 +14556,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.2.4": +"ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.1": version: 5.3.1 resolution: "ignore@npm:5.3.1" checksum: 703f7f45ffb2a27fb2c5a8db0c32e7dee66b33a225d28e8db4e1be6474795f606686a6e3bcc50e1aa12f2042db4c9d4a7d60af3250511de74620fbed052ea4cd @@ -14952,9 +14585,9 @@ __metadata: linkType: hard "immutable@npm:^4.0.0-rc.12": - version: 4.3.5 - resolution: "immutable@npm:4.3.5" - checksum: 63d2d7908241a955d18c7822fd2215b6e89ff5a1a33cc72cd475b013cbbdef7a705aa5170a51ce9f84a57f62fdddfaa34e7b5a14b33d8a43c65cc6a881d6e894 + version: 4.3.6 + resolution: "immutable@npm:4.3.6" + checksum: 7d0952a768b4fadcee47230ed86dc9505a4517095eceaf5a47e65288571c42400c6e4a2ae21eca4eda957cb7bc50720213135b62cf6a181639111f8acae128c3 languageName: node linkType: hard @@ -15418,6 +15051,15 @@ __metadata: languageName: node linkType: hard +"is-data-view@npm:^1.0.1": + version: 1.0.1 + resolution: "is-data-view@npm:1.0.1" + dependencies: + is-typed-array: "npm:^1.1.13" + checksum: a3e6ec84efe303da859107aed9b970e018e2bee7ffcb48e2f8096921a493608134240e672a2072577e5f23a729846241d9634806e8a0e51d9129c56d5f65442d + languageName: node + linkType: hard + "is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" @@ -15635,7 +15277,7 @@ __metadata: languageName: node linkType: hard -"is-negative-zero@npm:^2.0.2": +"is-negative-zero@npm:^2.0.3": version: 2.0.3 resolution: "is-negative-zero@npm:2.0.3" checksum: bcdcf6b8b9714063ffcfa9929c575ac69bfdabb8f4574ff557dfc086df2836cf07e3906f5bbc4f2a5c12f8f3ba56af640c843cdfc74da8caed86c7c7d66fd08e @@ -15767,7 +15409,7 @@ __metadata: languageName: node linkType: hard -"is-shared-array-buffer@npm:^1.0.2": +"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": version: 1.0.3 resolution: "is-shared-array-buffer@npm:1.0.3" dependencies: @@ -16116,7 +15758,7 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.3.5": +"jackspeak@npm:^2.3.6": version: 2.3.6 resolution: "jackspeak@npm:2.3.6" dependencies: @@ -17314,10 +16956,10 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.0.0, lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": - version: 10.2.0 - resolution: "lru-cache@npm:10.2.0" - checksum: c9847612aa2daaef102d30542a8d6d9b2c2bb36581c1bf0dc3ebf5e5f3352c772a749e604afae2e46873b930a9e9523743faac4e5b937c576ab29196774712ee +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.2.2 + resolution: "lru-cache@npm:10.2.2" + checksum: 402d31094335851220d0b00985084288136136992979d0e015f0f1697e15d1c86052d7d53ae86b614e5b058425606efffc6969a31a091085d7a2b80a8a1e26d6 languageName: node linkType: hard @@ -17385,8 +17027,8 @@ __metadata: linkType: hard "make-fetch-happen@npm:^13.0.0": - version: 13.0.0 - resolution: "make-fetch-happen@npm:13.0.0" + version: 13.0.1 + resolution: "make-fetch-happen@npm:13.0.1" dependencies: "@npmcli/agent": "npm:^2.0.0" cacache: "npm:^18.0.0" @@ -17397,9 +17039,10 @@ __metadata: minipass-flush: "npm:^1.0.5" minipass-pipeline: "npm:^1.2.4" negotiator: "npm:^0.6.3" + proc-log: "npm:^4.2.0" promise-retry: "npm:^2.0.1" ssri: "npm:^10.0.0" - checksum: 43b9f6dcbc6fe8b8604cb6396957c3698857a15ba4dbc38284f7f0e61f248300585ef1eb8cc62df54e9c724af977e45b5cdfd88320ef7f53e45070ed3488da55 + checksum: df5f4dbb6d98153b751bccf4dc4cc500de85a96a9331db9805596c46aa9f99d9555983954e6c1266d9f981ae37a9e4647f42b9a4bb5466f867f4012e582c9e7e languageName: node linkType: hard @@ -17827,12 +17470,12 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:*, minimatch@npm:9.0.3, minimatch@npm:^9.0.1": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" +"minimatch@npm:*, minimatch@npm:^9.0.1, minimatch@npm:^9.0.4": + version: 9.0.4 + resolution: "minimatch@npm:9.0.4" dependencies: brace-expansion: "npm:^2.0.1" - checksum: 85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac + checksum: 2c16f21f50e64922864e560ff97c587d15fd491f65d92a677a344e970fe62aafdbeafe648965fa96d33c061b4d0eabfe0213466203dd793367e7f28658cf6414 languageName: node linkType: hard @@ -17854,6 +17497,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:9.0.3": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac + languageName: node + linkType: hard + "minimatch@npm:^5.0.1": version: 5.1.6 resolution: "minimatch@npm:5.1.6" @@ -17898,8 +17550,8 @@ __metadata: linkType: hard "minipass-fetch@npm:^3.0.0": - version: 3.0.4 - resolution: "minipass-fetch@npm:3.0.4" + version: 3.0.5 + resolution: "minipass-fetch@npm:3.0.5" dependencies: encoding: "npm:^0.1.13" minipass: "npm:^7.0.3" @@ -17908,7 +17560,7 @@ __metadata: dependenciesMeta: encoding: optional: true - checksum: 1b63c1f3313e88eeac4689f1b71c9f086598db9a189400e3ee960c32ed89e06737fa23976c9305c2d57464fb3fcdc12749d3378805c9d6176f5569b0d0ee8a75 + checksum: 9d702d57f556274286fdd97e406fc38a2f5c8d15e158b498d7393b1105974b21249289ec571fa2b51e038a4872bfc82710111cf75fae98c662f3d6f95e72152b languageName: node linkType: hard @@ -17965,10 +17617,10 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": - version: 7.0.4 - resolution: "minipass@npm:7.0.4" - checksum: 6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5 +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4": + version: 7.1.1 + resolution: "minipass@npm:7.1.1" + checksum: fdccc2f99c31083f45f881fd1e6971d798e333e078ab3c8988fb818c470fbd5e935388ad9adb286397eba50baebf46ef8ff487c8d3f455a69c6f3efc327bdff9 languageName: node linkType: hard @@ -18067,8 +17719,8 @@ __metadata: linkType: hard "mocha@npm:^10.0.0, mocha@npm:^10.2.0": - version: 10.3.0 - resolution: "mocha@npm:10.3.0" + version: 10.4.0 + resolution: "mocha@npm:10.4.0" dependencies: ansi-colors: "npm:4.1.1" browser-stdout: "npm:1.3.1" @@ -18093,7 +17745,7 @@ __metadata: bin: _mocha: bin/_mocha mocha: bin/mocha.js - checksum: 8dc93842468b2be5f820e5eb64208fb68ba3e5ee90cfe21a9f1d439f9ec031e8a8dc97f4d3206a376c9e05141cf689a812aedcf4545f71f69b3e9a51f312ec4a + checksum: e572e9d8c164e98f64de7e9498608de042fd841c6a7441f456a5e216e9aed2299e2c568d9dc27f2be2de06521e6b2d1dd774ab58a243b1c7697d14aec2f0f7f7 languageName: node linkType: hard @@ -18547,19 +18199,19 @@ __metadata: linkType: hard "node-gyp-build@npm:^4.2.0, node-gyp-build@npm:^4.3.0": - version: 4.8.0 - resolution: "node-gyp-build@npm:4.8.0" + version: 4.8.1 + resolution: "node-gyp-build@npm:4.8.1" bin: node-gyp-build: bin.js node-gyp-build-optional: optional.js node-gyp-build-test: build-test.js - checksum: 85324be16f81f0235cbbc42e3eceaeb1b5ab94c8d8f5236755e1435b4908338c65a4e75f66ee343cbcb44ddf9b52a428755bec16dcd983295be4458d95c8e1ad + checksum: e36ca3d2adf2b9cca316695d7687207c19ac6ed326d6d7c68d7112cebe0de4f82d6733dff139132539fcc01cf5761f6c9082a21864ab9172edf84282bc849ce7 languageName: node linkType: hard "node-gyp@npm:latest": - version: 10.0.1 - resolution: "node-gyp@npm:10.0.1" + version: 10.1.0 + resolution: "node-gyp@npm:10.1.0" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" @@ -18573,7 +18225,7 @@ __metadata: which: "npm:^4.0.0" bin: node-gyp: bin/node-gyp.js - checksum: abddfff7d873312e4ed4a5fb75ce893a5c4fb69e7fcb1dfa71c28a6b92a7f1ef6b62790dffb39181b5a82728ba8f2f32d229cf8cbe66769fe02cea7db4a555aa + checksum: 9cc821111ca244a01fb7f054db7523ab0a0cd837f665267eb962eb87695d71fb1e681f9e21464cc2fd7c05530dc4c81b810bca1a88f7d7186909b74477491a3c languageName: node linkType: hard @@ -18610,13 +18262,13 @@ __metadata: linkType: hard "nopt@npm:^7.0.0": - version: 7.2.0 - resolution: "nopt@npm:7.2.0" + version: 7.2.1 + resolution: "nopt@npm:7.2.1" dependencies: abbrev: "npm:^2.0.0" bin: nopt: bin/nopt.js - checksum: 9bd7198df6f16eb29ff16892c77bcf7f0cc41f9fb5c26280ac0def2cf8cf319f3b821b3af83eba0e74c85807cc430a16efe0db58fe6ae1f41e69519f585b6aff + checksum: a069c7c736767121242037a22a788863accfa932ab285a1eb569eb8cd534b09d17206f68c37f096ae785647435e0c5a5a0a67b42ec743e481a455e5ae6a6df81 languageName: node linkType: hard @@ -18675,9 +18327,9 @@ __metadata: linkType: hard "normalize-url@npm:^8.0.0": - version: 8.0.0 - resolution: "normalize-url@npm:8.0.0" - checksum: 09582d56acd562d89849d9239852c2aff225c72be726556d6883ff36de50006803d32a023c10e917bcc1c55f73f3bb16434f67992fe9b61906a3db882192753c + version: 8.0.1 + resolution: "normalize-url@npm:8.0.1" + checksum: eb439231c4b84430f187530e6fdac605c5048ef4ec556447a10c00a91fc69b52d8d8298d9d608e68d3e0f7dc2d812d3455edf425e0f215993667c3183bcab1ef languageName: node linkType: hard @@ -18779,12 +18431,12 @@ __metadata: linkType: hard "object-is@npm:^1.1.5": - version: 1.1.5 - resolution: "object-is@npm:1.1.5" + version: 1.1.6 + resolution: "object-is@npm:1.1.6" dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.1.3" - checksum: 8c263fb03fc28f1ffb54b44b9147235c5e233dc1ca23768e7d2569740b5d860154d7cc29a30220fe28ed6d8008e2422aefdebfe987c103e1c5d190cf02d9d886 + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + checksum: 506af444c4dce7f8e31f34fc549e2fb8152d6b9c4a30c6e62852badd7f520b579c679af433e7a072f9d78eb7808d230dc12e1cf58da9154dfbf8813099ea0fe0 languageName: node linkType: hard @@ -18824,15 +18476,17 @@ __metadata: linkType: hard "object.getownpropertydescriptors@npm:^2.1.6": - version: 2.1.7 - resolution: "object.getownpropertydescriptors@npm:2.1.7" + version: 2.1.8 + resolution: "object.getownpropertydescriptors@npm:2.1.8" dependencies: array.prototype.reduce: "npm:^1.0.6" - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - safe-array-concat: "npm:^1.0.0" - checksum: 519c4eb47bd30dad1385994dbea59408c25f4bff68b29d918267091f3d597d39b04557691e94ee385fd9af7f191daffa59954e19c6f1e53215d6910d386005a2 + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-object-atoms: "npm:^1.0.0" + gopd: "npm:^1.0.1" + safe-array-concat: "npm:^1.1.2" + checksum: 553e9562fd86637c9c169df23a56f1d810d8c9b580a6d4be11552c009f32469310c9347f3d10325abf0cd9cfe4afc521a1e903fbd24148ae7ec860e1e7c75cf3 languageName: node linkType: hard @@ -18991,16 +18645,16 @@ __metadata: linkType: hard "optionator@npm:^0.9.3": - version: 0.9.3 - resolution: "optionator@npm:0.9.3" + version: 0.9.4 + resolution: "optionator@npm:0.9.4" dependencies: - "@aashutoshrathi/word-wrap": "npm:^1.2.3" deep-is: "npm:^0.1.3" fast-levenshtein: "npm:^2.0.6" levn: "npm:^0.4.1" prelude-ls: "npm:^1.2.1" type-check: "npm:^0.4.0" - checksum: 66fba794d425b5be51353035cf3167ce6cfa049059cbb93229b819167687e0f48d2bc4603fcb21b091c99acb516aae1083624675b15c4765b2e4693a085e959c + word-wrap: "npm:^1.2.5" + checksum: 4afb687a059ee65b61df74dfe87d8d6815cd6883cb8b3d5883a910df72d0f5d029821f37025e4bccf4048873dbdb09acc6d303d27b8f76b1a80dd5a7d5334675 languageName: node linkType: hard @@ -19264,16 +18918,17 @@ __metadata: languageName: node linkType: hard -"parse-asn1@npm:^5.0.0, parse-asn1@npm:^5.1.6": - version: 5.1.6 - resolution: "parse-asn1@npm:5.1.6" +"parse-asn1@npm:^5.0.0, parse-asn1@npm:^5.1.7": + version: 5.1.7 + resolution: "parse-asn1@npm:5.1.7" dependencies: - asn1.js: "npm:^5.2.0" - browserify-aes: "npm:^1.0.0" - evp_bytestokey: "npm:^1.0.0" - pbkdf2: "npm:^3.0.3" - safe-buffer: "npm:^5.1.1" - checksum: 4ed1d9b9e120c5484d29d67bb90171aac0b73422bc016d6294160aea983275c28a27ab85d862059a36a86a97dd31b7ddd97486802ca9fac67115fe3409e9dcbd + asn1.js: "npm:^4.10.1" + browserify-aes: "npm:^1.2.0" + evp_bytestokey: "npm:^1.0.3" + hash-base: "npm:~3.0" + pbkdf2: "npm:^3.1.2" + safe-buffer: "npm:^5.2.1" + checksum: 05eb5937405c904eb5a7f3633bab1acc11f4ae3478a07ef5c6d81ce88c3c0e505ff51f9c7b935ebc1265c868343793698fc91025755a895d0276f620f95e8a82 languageName: node linkType: hard @@ -19503,13 +19158,13 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.10.1": - version: 1.10.1 - resolution: "path-scurry@npm:1.10.1" +"path-scurry@npm:^1.11.0": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" dependencies: - lru-cache: "npm:^9.1.1 || ^10.0.0" + lru-cache: "npm:^10.2.0" minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - checksum: e5dc78a7348d25eec61ab166317e9e9c7b46818aa2c2b9006c507a6ff48c672d011292d9662527213e558f5652ce0afcc788663a061d8b59ab495681840c0c1e + checksum: 32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d languageName: node linkType: hard @@ -19552,7 +19207,7 @@ __metadata: languageName: node linkType: hard -"pbkdf2@npm:^3.0.17, pbkdf2@npm:^3.0.3, pbkdf2@npm:^3.0.9": +"pbkdf2@npm:^3.0.17, pbkdf2@npm:^3.0.3, pbkdf2@npm:^3.0.9, pbkdf2@npm:^3.1.2": version: 3.1.2 resolution: "pbkdf2@npm:3.1.2" dependencies: @@ -19589,9 +19244,9 @@ __metadata: linkType: hard "pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.6.1, pg-connection-string@npm:^2.6.2": - version: 2.6.2 - resolution: "pg-connection-string@npm:2.6.2" - checksum: e8fdea74fcc8bdc3d7c5c6eadd9425fdba7e67fb7fe836f9c0cecad94c8984e435256657d1d8ce0483d1fedef667e7a57e32449a63cb805cb0289fc34b62da35 + version: 2.6.4 + resolution: "pg-connection-string@npm:2.6.4" + checksum: 0d0b617df0fc6507bf6a94bdcd56c7a305788a1402d69bff9773350947c8f525d6d8136128065370749a3325e99658ae40fbdcce620fb8e60126181f0591a6a6 languageName: node linkType: hard @@ -19612,18 +19267,18 @@ __metadata: linkType: hard "pg-pool@npm:^3.5.1, pg-pool@npm:^3.6.1": - version: 3.6.1 - resolution: "pg-pool@npm:3.6.1" + version: 3.6.2 + resolution: "pg-pool@npm:3.6.2" peerDependencies: pg: ">=8.0" - checksum: 47837c4e4c2b9e195cec01bd58b6e276acc915537191707ad4d6ed975fd9bc03c73f63cb7fde4cb0e08ed059e35faf60fbd03744dee3af71d4b4631ab40eeb7f + checksum: 14c524549490954b5e48457a4b808df8f619f6deeb3b395b0cd184a8f4ed65a9273fe0697ba0341a41d6745af197f1437eb1cf51fff0cbbf5b0fb3852ebe5392 languageName: node linkType: hard "pg-protocol@npm:^1.5.0, pg-protocol@npm:^1.6.0": - version: 1.6.0 - resolution: "pg-protocol@npm:1.6.0" - checksum: 318a4d1e9cebd3927b10a8bc412f5017117a1f9a5fafb628d75847da7d1ab81c33250de58596bd0990029e14e92a995a851286d60fc236692299faf509572213 + version: 1.6.1 + resolution: "pg-protocol@npm:1.6.1" + checksum: 7eadef4010ac0a3925c460be7332ca4098a5c6d5181725a62193fcfa800000ae6632d98d814f3989b42cf5fdc3b45e34c714a1959d29174e81e30730e140ae5f languageName: node linkType: hard @@ -19693,10 +19348,10 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0": - version: 1.0.0 - resolution: "picocolors@npm:1.0.0" - checksum: 20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7 +"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1": + version: 1.0.1 + resolution: "picocolors@npm:1.0.1" + checksum: c63cdad2bf812ef0d66c8db29583802355d4ca67b9285d846f390cc15c2f6ccb94e8cb7eb6a6e97fc5990a6d3ad4ae42d86c84d3146e667c739a4234ed50d400 languageName: node linkType: hard @@ -19707,10 +19362,10 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^4.0.1": - version: 4.0.1 - resolution: "picomatch@npm:4.0.1" - checksum: a036a085b18b376493e8ccef155bb03c65a2be7203582b717bb0498d1446e6a80f7f86a36e07877590abd0431f26c64c6154058c31f4f46105d3686a34fa3cf6 +"picomatch@npm:^4.0.2": + version: 4.0.2 + resolution: "picomatch@npm:4.0.2" + checksum: 7c51f3ad2bb42c776f49ebf964c644958158be30d0a510efd5a395e8d49cb5acfed5b82c0c5b365523ce18e6ab85013c9ebe574f60305892ec3fa8eee8304ccc languageName: node linkType: hard @@ -20006,6 +19661,13 @@ __metadata: languageName: node linkType: hard +"proc-log@npm:^4.2.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 17db4757c2a5c44c1e545170e6c70a26f7de58feb985091fb1763f5081cab3d01b181fb2dd240c9f4a4255a1d9227d163d5771b7e69c9e49a561692db865efb9 + languageName: node + linkType: hard + "process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" @@ -20342,11 +20004,11 @@ __metadata: linkType: hard "qs@npm:^6.11.2, qs@npm:^6.4.0, qs@npm:^6.7.0, qs@npm:^6.9.4": - version: 6.11.2 - resolution: "qs@npm:6.11.2" + version: 6.12.1 + resolution: "qs@npm:6.12.1" dependencies: - side-channel: "npm:^1.0.4" - checksum: 4f95d4ff18ed480befcafa3390022817ffd3087fc65f146cceb40fc5edb9fa96cb31f648cae2fa96ca23818f0798bd63ad4ca369a0e22702fcd41379b3ab6571 + side-channel: "npm:^1.0.6" + checksum: 439e6d7c6583e7c69f2cab2c39c55b97db7ce576e4c7c469082b938b7fc8746e8d547baacb69b4cd2b6666484776c3f4840ad7163a4c5326300b0afa0acdd84b languageName: node linkType: hard @@ -20574,7 +20236,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:2 || 3, readable-stream@npm:3, readable-stream@npm:^3.0.0, readable-stream@npm:^3.0.6, readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0, readable-stream@npm:^3.6.2": +"readable-stream@npm:2 || 3, readable-stream@npm:3, readable-stream@npm:^3.0.0, readable-stream@npm:^3.0.6, readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -20597,7 +20259,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.5, readable-stream@npm:^2.2.2, readable-stream@npm:^2.2.8, readable-stream@npm:^2.2.9, readable-stream@npm:^2.3.6, readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.5, readable-stream@npm:^2.2.2, readable-stream@npm:^2.2.8, readable-stream@npm:^2.2.9, readable-stream@npm:^2.3.6, readable-stream@npm:^2.3.8, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -21155,13 +20817,13 @@ __metadata: linkType: hard "rimraf@npm:^5.0.0": - version: 5.0.5 - resolution: "rimraf@npm:5.0.5" + version: 5.0.7 + resolution: "rimraf@npm:5.0.7" dependencies: glob: "npm:^10.3.7" bin: rimraf: dist/esm/bin.mjs - checksum: d50dbe724f33835decd88395b25ed35995077c60a50ae78ded06e0185418914e555817aad1b4243edbff2254548c2f6ad6f70cc850040bebb4da9e8cc016f586 + checksum: bd6dbfaa98ae34ce1e54d1e06045d2d63e8859d9a1979bb4a4628b652b459a2d17b17dc20ee072b034bd2d09bd691e801d24c4d9cfe94e16fdbcc8470a1d4807 languageName: node linkType: hard @@ -21222,22 +20884,6 @@ __metadata: languageName: node linkType: hard -"rust-verkle-wasm@npm:^0.0.1": - version: 0.0.1 - resolution: "rust-verkle-wasm@npm:0.0.1" - checksum: 07536a7b4d1fe37dcfc9fc19fdee630d26c9c27acd3a18da8daf21c040b87bb162098fd304e1458e4edb72d8ed4cd0e74c9fcd75edb70eb5e29a1a524916ad12 - languageName: node - linkType: hard - -"rustbn-wasm@npm:^0.2.0": - version: 0.2.0 - resolution: "rustbn-wasm@npm:0.2.0" - dependencies: - "@scure/base": "npm:^1.1.1" - checksum: 86729b25a7295f706641366a3ba2bd59a666c1ddbdc40ec4a18f8f8dd5074aaf742ffaf260e80617513954e6a247f4e06f655fe99e9d75fddbdcc4cf0bea32b7 - languageName: node - linkType: hard - "rustbn.js@npm:~0.2.0": version: 0.2.0 resolution: "rustbn.js@npm:0.2.0" @@ -21263,15 +20909,15 @@ __metadata: languageName: node linkType: hard -"safe-array-concat@npm:^1.0.0, safe-array-concat@npm:^1.1.0": - version: 1.1.0 - resolution: "safe-array-concat@npm:1.1.0" +"safe-array-concat@npm:^1.0.0, safe-array-concat@npm:^1.1.2": + version: 1.1.2 + resolution: "safe-array-concat@npm:1.1.2" dependencies: - call-bind: "npm:^1.0.5" - get-intrinsic: "npm:^1.2.2" + call-bind: "npm:^1.0.7" + get-intrinsic: "npm:^1.2.4" has-symbols: "npm:^1.0.3" isarray: "npm:^2.0.5" - checksum: 833d3d950fc7507a60075f9bfaf41ec6dac7c50c7a9d62b1e6b071ecc162185881f92e594ff95c1a18301c881352dd6fd236d56999d5819559db7b92da9c28af + checksum: 12f9fdb01c8585e199a347eacc3bae7b5164ae805cdc8c6707199dbad5b9e30001a50a43c4ee24dc9ea32dbb7279397850e9208a7e217f4d8b1cf5d90129dec9 languageName: node linkType: hard @@ -21432,7 +21078,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.6.0, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4": +"semver@npm:7.6.0": version: 7.6.0 resolution: "semver@npm:7.6.0" dependencies: @@ -21452,6 +21098,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": + version: 7.6.2 + resolution: "semver@npm:7.6.2" + bin: + semver: bin/semver.js + checksum: 97d3441e97ace8be4b1976433d1c32658f6afaff09f143e52c593bae7eef33de19e3e369c88bd985ce1042c6f441c80c6803078d1de2a9988080b66684cbb30c + languageName: node + linkType: hard + "semver@npm:~5.4.1": version: 5.4.1 resolution: "semver@npm:5.4.1" @@ -21659,16 +21314,16 @@ __metadata: linkType: hard "set-function-length@npm:^1.2.1": - version: 1.2.1 - resolution: "set-function-length@npm:1.2.1" + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" dependencies: - define-data-property: "npm:^1.1.2" + define-data-property: "npm:^1.1.4" es-errors: "npm:^1.3.0" function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.3" + get-intrinsic: "npm:^1.2.4" gopd: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.1" - checksum: 1927e296599f2c04d210c1911f1600430a5e49e04a6d8bb03dca5487b95a574da9968813a2ced9a774bd3e188d4a6208352c8f64b8d4674cdb021dca21e190ca + has-property-descriptors: "npm:^1.0.2" + checksum: 82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c languageName: node linkType: hard @@ -21791,15 +21446,15 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4": - version: 1.0.5 - resolution: "side-channel@npm:1.0.5" +"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" dependencies: - call-bind: "npm:^1.0.6" + call-bind: "npm:^1.0.7" es-errors: "npm:^1.3.0" get-intrinsic: "npm:^1.2.4" object-inspect: "npm:^1.13.1" - checksum: 31312fecb68997ce2893b1f6d1fd07d6dd41e05cc938e82004f056f7de96dd9df599ef9418acdf730dda948e867e933114bd2efe4170c0146d1ed7009700c252 + checksum: d2afd163dc733cc0a39aa6f7e39bf0c436293510dbccbff446733daeaf295857dbccf94297092ec8c53e2503acac30f0b78830876f0485991d62a90e9cad305f languageName: node linkType: hard @@ -22006,24 +21661,24 @@ __metadata: languageName: node linkType: hard -"socks-proxy-agent@npm:^8.0.1": - version: 8.0.2 - resolution: "socks-proxy-agent@npm:8.0.2" +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.3 + resolution: "socks-proxy-agent@npm:8.0.3" dependencies: - agent-base: "npm:^7.0.2" + agent-base: "npm:^7.1.1" debug: "npm:^4.3.4" socks: "npm:^2.7.1" - checksum: a842402fc9b8848a31367f2811ca3cd14c4106588b39a0901cd7a69029998adfc6456b0203617c18ed090542ad0c24ee4e9d4c75a0c4b75071e214227c177eb7 + checksum: 4950529affd8ccd6951575e21c1b7be8531b24d924aa4df3ee32df506af34b618c4e50d261f4cc603f1bfd8d426915b7d629966c8ce45b05fb5ad8c8b9a6459d languageName: node linkType: hard "socks@npm:^2.7.1": - version: 2.8.1 - resolution: "socks@npm:2.8.1" + version: 2.8.3 + resolution: "socks@npm:2.8.3" dependencies: ip-address: "npm:^9.0.5" smart-buffer: "npm:^4.2.0" - checksum: ac77b515c260473cc7c4452f09b20939e22510ce3ae48385c516d1d5784374d5cc75be3cb18ff66cc985a7f4f2ef8fef84e984c5ec70aad58355ed59241f40a8 + checksum: d54a52bf9325165770b674a67241143a3d8b4e4c8884560c4e0e078aace2a728dffc7f70150660f51b85797c4e1a3b82f9b7aa25e0a0ceae1a243365da5c51a7 languageName: node linkType: hard @@ -22127,13 +21782,29 @@ __metadata: "solhint-graph-config@workspace:^0.0.1, solhint-graph-config@workspace:packages/solhint-graph-config": version: 0.0.0-use.local resolution: "solhint-graph-config@workspace:packages/solhint-graph-config" + dependencies: + solhint-plugin-graph: "file:plugin" peerDependencies: prettier: ^3.2.5 prettier-plugin-solidity: ^1.3.1 - solhint: ^4.1.1 + solhint: ^4.5.4 languageName: unknown linkType: soft +"solhint-plugin-graph@file:node_modules/solhint-graph-config/plugin::locator=%40graphprotocol%2Fsubgraph-service%40workspace%3Apackages%2Fsubgraph-service": + version: 0.0.0 + resolution: "solhint-plugin-graph@file:node_modules/solhint-graph-config/plugin#node_modules/solhint-graph-config/plugin::hash=37bdb1&locator=%40graphprotocol%2Fsubgraph-service%40workspace%3Apackages%2Fsubgraph-service" + checksum: f77aeda80dc6f8bb93376c3b05e910874038e701793f7805e9937f0047e68d3ac8595d915a4cb12dd974c49851d2b0fdf94742b0b2865cd7bf7e3a630177dfea + languageName: node + linkType: hard + +"solhint-plugin-graph@file:plugin::locator=solhint-graph-config%40workspace%3Apackages%2Fsolhint-graph-config": + version: 0.0.0 + resolution: "solhint-plugin-graph@file:plugin#plugin::hash=37bdb1&locator=solhint-graph-config%40workspace%3Apackages%2Fsolhint-graph-config" + checksum: f77aeda80dc6f8bb93376c3b05e910874038e701793f7805e9937f0047e68d3ac8595d915a4cb12dd974c49851d2b0fdf94742b0b2865cd7bf7e3a630177dfea + languageName: node + linkType: hard + "solhint-plugin-prettier@npm:^0.1.0": version: 0.1.0 resolution: "solhint-plugin-prettier@npm:0.1.0" @@ -22147,41 +21818,9 @@ __metadata: languageName: node linkType: hard -"solhint@npm:^4.1.1": - version: 4.1.1 - resolution: "solhint@npm:4.1.1" - dependencies: - "@solidity-parser/parser": "npm:^0.16.0" - ajv: "npm:^6.12.6" - antlr4: "npm:^4.11.0" - ast-parents: "npm:^0.0.1" - chalk: "npm:^4.1.2" - commander: "npm:^10.0.0" - cosmiconfig: "npm:^8.0.0" - fast-diff: "npm:^1.2.0" - glob: "npm:^8.0.3" - ignore: "npm:^5.2.4" - js-yaml: "npm:^4.1.0" - latest-version: "npm:^7.0.0" - lodash: "npm:^4.17.21" - pluralize: "npm:^8.0.0" - prettier: "npm:^2.8.3" - semver: "npm:^7.5.2" - strip-ansi: "npm:^6.0.1" - table: "npm:^6.8.1" - text-table: "npm:^0.2.0" - dependenciesMeta: - prettier: - optional: true - bin: - solhint: solhint.js - checksum: b4bdb21bdc13f7ba3436d571a30cae6cb8dfb58ab1387df8bef25eeca25c8fbb3f625c49a5dddea41f8361aaeb4d8e2e9f986f580663ddd4574fd3d5de5f66c9 - languageName: node - linkType: hard - -"solhint@npm:^4.5.2": - version: 4.5.2 - resolution: "solhint@npm:4.5.2" +"solhint@npm:^4.1.1, solhint@npm:^4.5.2, solhint@npm:^4.5.4": + version: 4.5.4 + resolution: "solhint@npm:4.5.4" dependencies: "@solidity-parser/parser": "npm:^0.18.0" ajv: "npm:^6.12.6" @@ -22207,16 +21846,16 @@ __metadata: optional: true bin: solhint: solhint.js - checksum: a54cc8df54ed711ca6be783b9291eb9e838f518f236d4df05c6ef412ead6a21f4a5bf3bace62ca7d2ed69f4566d5289db4c8c93e0c5e23ac91401904e1f1f312 + checksum: 85bc62536c6b1269403b2af369dcfc7c63d07c6efb994f4e3c4e7e96d3511a64ab10c68635c6676e09eee289104b5d349091960994e990cacf240497170c8aed languageName: node linkType: hard -"solidity-ast@npm:^0.4.51": - version: 0.4.55 - resolution: "solidity-ast@npm:0.4.55" +"solidity-ast@npm:^0.4.38, solidity-ast@npm:^0.4.51": + version: 0.4.56 + resolution: "solidity-ast@npm:0.4.56" dependencies: array.prototype.findlast: "npm:^1.2.2" - checksum: 6f945f014a34ccc9fe8ffbbef286e9f12d52a92bee79d01f8f16e81e2ccd610bbb3e60ab4bebaea7a868382c235d0f01938e32103a68d374753c355849f2279f + checksum: 6e10e58ddae8c7a9e53551bc61b673963c6671cac12050fa77575caff1ecc6a58440af8b7d85755fdda7e02d0516e2dcd3a5a976bd91a865375274163281d160 languageName: node linkType: hard @@ -22256,8 +21895,8 @@ __metadata: linkType: hard "solidity-coverage@npm:^0.8.0": - version: 0.8.11 - resolution: "solidity-coverage@npm:0.8.11" + version: 0.8.12 + resolution: "solidity-coverage@npm:0.8.12" dependencies: "@ethersproject/abi": "npm:^5.0.9" "@solidity-parser/parser": "npm:^0.18.0" @@ -22269,7 +21908,7 @@ __metadata: global-modules: "npm:^2.0.0" globby: "npm:^10.0.1" jsonschema: "npm:^1.2.4" - lodash: "npm:^4.17.15" + lodash: "npm:^4.17.21" mocha: "npm:^10.2.0" node-emoji: "npm:^1.10.0" pify: "npm:^4.0.1" @@ -22282,7 +21921,19 @@ __metadata: hardhat: ^2.11.0 bin: solidity-coverage: plugins/bin.js - checksum: de26a3bdece5b36005fcf84b4c4e9e0affc2822d69c823d925f439876c3d5c7b1fc83d447745c6aae994ad0e5c02f4c031d4d9b2d5613184d9286116857e6437 + checksum: 500de00ca5d0ff9531bcfc54040591e90bb281714c5ad810bc6aa77bb6ab696f15a141f6bcb1a47547dca68d10e717e1705741d4cf660d7dce8700fa97e6bfaf + languageName: node + linkType: hard + +"solidity-docgen@npm:^0.6.0-beta.36": + version: 0.6.0-beta.36 + resolution: "solidity-docgen@npm:0.6.0-beta.36" + dependencies: + handlebars: "npm:^4.7.7" + solidity-ast: "npm:^0.4.38" + peerDependencies: + hardhat: ^2.8.0 + checksum: 34ca1c18b2f662e5b6e407fad9346da91807b18ca57c877d909a4e730935475b0d3a5d8e91d79113c96741f4275944f9f3176a612894f4118e16cd9a9de80c02 languageName: node linkType: hard @@ -22503,11 +22154,11 @@ __metadata: linkType: hard "ssri@npm:^10.0.0": - version: 10.0.5 - resolution: "ssri@npm:10.0.5" + version: 10.0.6 + resolution: "ssri@npm:10.0.6" dependencies: minipass: "npm:^7.0.3" - checksum: b091f2ae92474183c7ac5ed3f9811457e1df23df7a7e70c9476eaa9a0c4a0c8fc190fb45acefbf023ca9ee864dd6754237a697dc52a0fb182afe65d8e77443d8 + checksum: e5a1e23a4057a86a97971465418f22ea89bd439ac36ade88812dd920e4e61873e8abd6a9b72a03a67ef50faa00a2daf1ab745c5a15b46d03e0544a0296354227 languageName: node linkType: hard @@ -22558,7 +22209,7 @@ __metadata: languageName: node linkType: hard -"stream-shift@npm:^1.0.0": +"stream-shift@npm:^1.0.2": version: 1.0.3 resolution: "stream-shift@npm:1.0.3" checksum: 939cd1051ca750d240a0625b106a2b988c45fb5a3be0cebe9a9858cb01bc1955e8c7b9fac17a9462976bea4a7b704e317c5c2200c70f0ca715a3363b9aa4fd3b @@ -22682,36 +22333,37 @@ __metadata: languageName: node linkType: hard -"string.prototype.trim@npm:^1.2.8, string.prototype.trim@npm:~1.2.8": - version: 1.2.8 - resolution: "string.prototype.trim@npm:1.2.8" +"string.prototype.trim@npm:^1.2.9, string.prototype.trim@npm:~1.2.8": + version: 1.2.9 + resolution: "string.prototype.trim@npm:1.2.9" dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - checksum: 4f76c583908bcde9a71208ddff38f67f24c9ec8093631601666a0df8b52fad44dad2368c78895ce83eb2ae8e7068294cc96a02fc971ab234e4d5c9bb61ea4e34 + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.0" + es-object-atoms: "npm:^1.0.0" + checksum: dcef1a0fb61d255778155006b372dff8cc6c4394bc39869117e4241f41a2c52899c0d263ffc7738a1f9e61488c490b05c0427faa15151efad721e1a9fb2663c2 languageName: node linkType: hard -"string.prototype.trimend@npm:^1.0.7": - version: 1.0.7 - resolution: "string.prototype.trimend@npm:1.0.7" +"string.prototype.trimend@npm:^1.0.8": + version: 1.0.8 + resolution: "string.prototype.trimend@npm:1.0.8" dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - checksum: 53c24911c7c4d8d65f5ef5322de23a3d5b6b4db73273e05871d5ab4571ae5638f38f7f19d71d09116578fb060e5a145cc6a208af2d248c8baf7a34f44d32ce57 + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 0a0b54c17c070551b38e756ae271865ac6cc5f60dabf2e7e343cceae7d9b02e1a1120a824e090e79da1b041a74464e8477e2da43e2775c85392be30a6f60963c languageName: node linkType: hard -"string.prototype.trimstart@npm:^1.0.7": - version: 1.0.7 - resolution: "string.prototype.trimstart@npm:1.0.7" +"string.prototype.trimstart@npm:^1.0.8": + version: 1.0.8 + resolution: "string.prototype.trimstart@npm:1.0.8" dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - checksum: 0bcf391b41ea16d4fda9c9953d0a7075171fe090d33b4cf64849af94944c50862995672ac03e0c5dba2940a213ad7f53515a668dac859ce22a0276289ae5cf4f + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: d53af1899959e53c83b64a5fd120be93e067da740e7e75acb433849aa640782fb6c7d4cd5b84c954c84413745a3764df135a8afeb22908b86a835290788d8366 languageName: node linkType: hard @@ -23002,15 +22654,15 @@ __metadata: linkType: hard "table@npm:^6.8.0, table@npm:^6.8.1": - version: 6.8.1 - resolution: "table@npm:6.8.1" + version: 6.8.2 + resolution: "table@npm:6.8.2" dependencies: ajv: "npm:^8.0.1" lodash.truncate: "npm:^4.4.2" slice-ansi: "npm:^4.0.0" string-width: "npm:^4.2.3" strip-ansi: "npm:^6.0.1" - checksum: 591ed84b2438b01c9bc02248e2238e21e8bfb73654bc5acca0d469053eb39be3db2f57d600dcf08ac983b6f50f80842c44612c03877567c2afee3aec4a033e5f + checksum: f8b348af38ee34e419d8ce7306ba00671ce6f20e861ccff22555f491ba264e8416086063ce278a8d81abfa8d23b736ec2cca7ac4029b5472f63daa4b4688b803 languageName: node linkType: hard @@ -23056,8 +22708,8 @@ __metadata: linkType: hard "tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.2.0 - resolution: "tar@npm:6.2.0" + version: 6.2.1 + resolution: "tar@npm:6.2.1" dependencies: chownr: "npm:^2.0.0" fs-minipass: "npm:^2.0.0" @@ -23065,7 +22717,7 @@ __metadata: minizlib: "npm:^2.1.1" mkdirp: "npm:^1.0.3" yallist: "npm:^4.0.0" - checksum: 02ca064a1a6b4521fef88c07d389ac0936730091f8c02d30ea60d472e0378768e870769ab9e986d87807bfee5654359cf29ff4372746cc65e30cbddc352660d8 + checksum: a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537 languageName: node linkType: hard @@ -23404,12 +23056,12 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.0.1": - version: 1.2.1 - resolution: "ts-api-utils@npm:1.2.1" +"ts-api-utils@npm:^1.0.1, ts-api-utils@npm:^1.3.0": + version: 1.3.0 + resolution: "ts-api-utils@npm:1.3.0" peerDependencies: typescript: ">=4.2.0" - checksum: 8ddb493e7ae581d3f57a2e469142feb60b420d4ad8366ab969fe8e36531f8f301f370676b47e8d97f28b5f5fd10d6f2d55f656943a8546ef95e35ce5cf117754 + checksum: f54a0ba9ed56ce66baea90a3fa087a484002e807f28a8ccb2d070c75e76bde64bd0f6dce98b3802834156306050871b67eec325cb4e918015a360a3f0868c77c languageName: node linkType: hard @@ -23690,13 +23342,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^3.0.0": - version: 3.13.1 - resolution: "type-fest@npm:3.13.1" - checksum: 547d22186f73a8c04590b70dcf63baff390078c75ea8acd366bbd510fd0646e348bd1970e47ecf795b7cff0b41d26e9c475c1fedd6ef5c45c82075fbf916b629 - languageName: node - linkType: hard - "type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -23707,13 +23352,6 @@ __metadata: languageName: node linkType: hard -"type@npm:^1.0.1": - version: 1.2.0 - resolution: "type@npm:1.2.0" - checksum: 444660849aaebef8cbb9bc43b28ec2068952064cfce6a646f88db97aaa2e2d6570c5629cd79238b71ba23aa3f75146a0b96e24e198210ee0089715a6f8889bf7 - languageName: node - linkType: hard - "type@npm:^2.7.2": version: 2.7.2 resolution: "type@npm:2.7.2" @@ -23804,7 +23442,7 @@ __metadata: languageName: node linkType: hard -"typed-array-buffer@npm:^1.0.1": +"typed-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "typed-array-buffer@npm:1.0.2" dependencies: @@ -23815,7 +23453,7 @@ __metadata: languageName: node linkType: hard -"typed-array-byte-length@npm:^1.0.0": +"typed-array-byte-length@npm:^1.0.1": version: 1.0.1 resolution: "typed-array-byte-length@npm:1.0.1" dependencies: @@ -23828,7 +23466,7 @@ __metadata: languageName: node linkType: hard -"typed-array-byte-offset@npm:^1.0.0": +"typed-array-byte-offset@npm:^1.0.2": version: 1.0.2 resolution: "typed-array-byte-offset@npm:1.0.2" dependencies: @@ -23842,9 +23480,9 @@ __metadata: languageName: node linkType: hard -"typed-array-length@npm:^1.0.4": - version: 1.0.5 - resolution: "typed-array-length@npm:1.0.5" +"typed-array-length@npm:^1.0.6": + version: 1.0.6 + resolution: "typed-array-length@npm:1.0.6" dependencies: call-bind: "npm:^1.0.7" for-each: "npm:^0.3.3" @@ -23852,7 +23490,7 @@ __metadata: has-proto: "npm:^1.0.3" is-typed-array: "npm:^1.1.13" possible-typed-array-names: "npm:^1.0.0" - checksum: 5cc0f79196e70a92f8f40846cfa62b3de6be51e83f73655e137116cf65e3c29a288502b18cc8faf33c943c2470a4569009e1d6da338441649a2db2f135761ad5 + checksum: 74253d7dc488eb28b6b2711cf31f5a9dcefc9c41b0681fd1c178ed0a1681b4468581a3626d39cd4df7aee3d3927ab62be06aa9ca74e5baf81827f61641445b77 languageName: node linkType: hard @@ -23873,17 +23511,18 @@ __metadata: linkType: hard "typescript-eslint@npm:^7.0.2": - version: 7.0.2 - resolution: "typescript-eslint@npm:7.0.2" + version: 7.9.0 + resolution: "typescript-eslint@npm:7.9.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:7.0.2" - "@typescript-eslint/parser": "npm:7.0.2" + "@typescript-eslint/eslint-plugin": "npm:7.9.0" + "@typescript-eslint/parser": "npm:7.9.0" + "@typescript-eslint/utils": "npm:7.9.0" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 947216bccdb392c1e5f1228772185afbe306db305f1f61343d3cb315aa6c80a928709172498af62536b50c1e7c91e263eed7886bb4b328ca8850ffb1ea71a3d9 + checksum: dacdd8b278d519eea1d980c71dd301a0b68fe1100aa8eaa9e3b80acd7089765ef50bdf369b7c11ddc5f4be6ac6d90cc9283db549003c3df8cfabbe4f44a36b53 languageName: node linkType: hard @@ -23897,23 +23536,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.0.4, typescript@npm:^5.1.6, typescript@npm:^5.3.3": - version: 5.3.3 - resolution: "typescript@npm:5.3.3" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: e33cef99d82573624fc0f854a2980322714986bc35b9cb4d1ce736ed182aeab78e2cb32b385efa493b2a976ef52c53e20d6c6918312353a91850e2b76f1ea44f - languageName: node - linkType: hard - -"typescript@npm:^5.2.2": - version: 5.4.2 - resolution: "typescript@npm:5.4.2" +"typescript@npm:^5.0.4, typescript@npm:^5.1.6, typescript@npm:^5.2.2, typescript@npm:^5.3.3": + version: 5.4.5 + resolution: "typescript@npm:5.4.5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 583ff68cafb0c076695f72d61df6feee71689568179fb0d3a4834dac343df6b6ed7cf7b6f6c801fa52d43cd1d324e2f2d8ae4497b09f9e6cfe3d80a6d6c9ca52 + checksum: 2954022ada340fd3d6a9e2b8e534f65d57c92d5f3989a263754a78aba549f7e6529acc1921913560a4b816c46dce7df4a4d29f9f11a3dc0d4213bb76d043251e languageName: node linkType: hard @@ -23927,23 +23556,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.0.4#optional!builtin, typescript@patch:typescript@npm%3A^5.1.6#optional!builtin, typescript@patch:typescript@npm%3A^5.3.3#optional!builtin": - version: 5.3.3 - resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin::version=5.3.3&hash=e012d7" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 1d0a5f4ce496c42caa9a30e659c467c5686eae15d54b027ee7866744952547f1be1262f2d40de911618c242b510029d51d43ff605dba8fb740ec85ca2d3f9500 - languageName: node - linkType: hard - -"typescript@patch:typescript@npm%3A^5.2.2#optional!builtin": - version: 5.4.2 - resolution: "typescript@patch:typescript@npm%3A5.4.2#optional!builtin::version=5.4.2&hash=e012d7" +"typescript@patch:typescript@npm%3A^5.0.4#optional!builtin, typescript@patch:typescript@npm%3A^5.1.6#optional!builtin, typescript@patch:typescript@npm%3A^5.2.2#optional!builtin, typescript@patch:typescript@npm%3A^5.3.3#optional!builtin": + version: 5.4.5 + resolution: "typescript@patch:typescript@npm%3A5.4.5#optional!builtin::version=5.4.5&hash=e012d7" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 22e2f213c3ffe5960c5eaec6c95c04e01858fed57a94be250746f540b935b2c18c3c3fc80d3ab65d28c0aba1eb76284557ba3bf521d28caee811c44ba2b648f9 + checksum: 9cf4c053893bcf327d101b6c024a55baf05430dc30263f9adb1bf354aeffc11306fe1f23ba2f9a0209674359f16219b5b7d229e923477b94831d07d5a33a4217 languageName: node linkType: hard @@ -24083,11 +23702,11 @@ __metadata: linkType: hard "undici@npm:^5.14.0": - version: 5.28.3 - resolution: "undici@npm:5.28.3" + version: 5.28.4 + resolution: "undici@npm:5.28.4" dependencies: "@fastify/busboy": "npm:^2.0.0" - checksum: 3c559ae50ef3104b7085251445dda6f4de871553b9e290845649d2f80b06c0c9cfcdf741b0029c6b20d36c82e6a74dc815b139fa9a26757d70728074ca6d6f5c + checksum: 08d0f2596553aa0a54ca6e8e9c7f45aef7d042c60918564e3a142d449eda165a80196f6ef19ea2ef2e6446959e293095d8e40af1236f0d67223b06afac5ecad7 languageName: node linkType: hard @@ -24176,16 +23795,16 @@ __metadata: linkType: hard "update-browserslist-db@npm:^1.0.13": - version: 1.0.13 - resolution: "update-browserslist-db@npm:1.0.13" + version: 1.0.16 + resolution: "update-browserslist-db@npm:1.0.16" dependencies: - escalade: "npm:^3.1.1" - picocolors: "npm:^1.0.0" + escalade: "npm:^3.1.2" + picocolors: "npm:^1.0.1" peerDependencies: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: e52b8b521c78ce1e0c775f356cd16a9c22c70d25f3e01180839c407a5dc787fb05a13f67560cbaf316770d26fa99f78f1acd711b1b54a4f35d4820d4ea7136e6 + checksum: 5995399fc202adbb51567e4810e146cdf7af630a92cc969365a099150cb00597e425cc14987ca7080b09a4d0cfd2a3de53fbe72eebff171aed7f9bb81f9bf405 languageName: node linkType: hard @@ -24207,7 +23826,7 @@ __metadata: languageName: node linkType: hard -"uri-js@npm:^4.2.2": +"uri-js@npm:^4.2.2, uri-js@npm:^4.4.1": version: 4.4.1 resolution: "uri-js@npm:4.4.1" dependencies: @@ -24383,9 +24002,9 @@ __metadata: linkType: hard "validator@npm:^13.7.0, validator@npm:^13.9.0": - version: 13.11.0 - resolution: "validator@npm:13.11.0" - checksum: 0107da3add5a4ebc6391dac103c55f6d8ed055bbcc29a4c9cbf89eacfc39ba102a5618c470bdc33c6487d30847771a892134a8c791f06ef0962dd4b7a60ae0f5 + version: 13.12.0 + resolution: "validator@npm:13.12.0" + checksum: 21d48a7947c9e8498790550f56cd7971e0e3d724c73388226b109c1bac2728f4f88caddfc2f7ed4b076f9b0d004316263ac786a17e9c4edf075741200718cd32 languageName: node linkType: hard @@ -25323,16 +24942,16 @@ __metadata: languageName: node linkType: hard -"webcrypto-core@npm:^1.7.8": - version: 1.7.8 - resolution: "webcrypto-core@npm:1.7.8" +"webcrypto-core@npm:^1.7.9": + version: 1.7.9 + resolution: "webcrypto-core@npm:1.7.9" dependencies: "@peculiar/asn1-schema": "npm:^2.3.8" "@peculiar/json-schema": "npm:^1.1.12" asn1js: "npm:^3.0.1" pvtsutils: "npm:^1.3.5" tslib: "npm:^2.6.2" - checksum: 4c6ef9ae4ae27489f88b7c571494b058120178528f25efe87b97cbc64ead03a6468a614f6269927d13735e4f5ce1d1f7599cf4385ee9b61a13921964a5748a66 + checksum: 29075c0fd6afdd11473dcf98623b929fae6a0861a54725af109df824e3c55c00580103a2f934baabff52d588e9c6c3892db80346061fd835c55e0a83264c19f5 languageName: node linkType: hard @@ -25358,16 +24977,16 @@ __metadata: linkType: hard "websocket@npm:^1.0.31, websocket@npm:^1.0.32": - version: 1.0.34 - resolution: "websocket@npm:1.0.34" + version: 1.0.35 + resolution: "websocket@npm:1.0.35" dependencies: bufferutil: "npm:^4.0.1" debug: "npm:^2.2.0" - es5-ext: "npm:^0.10.50" + es5-ext: "npm:^0.10.63" typedarray-to-buffer: "npm:^3.1.5" utf-8-validate: "npm:^5.0.2" yaeti: "npm:^0.0.6" - checksum: a7e17d24edec685fdf055940ff9c6a15e726df5bb5e537382390bd1ab978fc8c0d71cd2842bb628e361d823aafd43934cc56aa5b979d08e52461be7da8d01eee + checksum: 8be9a68dc0228f18058c9010d1308479f05050af8f6d68b9dbc6baebd9ab484c15a24b2521a5d742a9d78e62ee19194c532992f1047a9b9adf8c3eedb0b1fcdc languageName: node linkType: hard @@ -25432,16 +25051,16 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.2": - version: 1.1.14 - resolution: "which-typed-array@npm:1.1.14" +"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.2": + version: 1.1.15 + resolution: "which-typed-array@npm:1.1.15" dependencies: - available-typed-arrays: "npm:^1.0.6" - call-bind: "npm:^1.0.5" + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.7" for-each: "npm:^0.3.3" gopd: "npm:^1.0.1" - has-tostringtag: "npm:^1.0.1" - checksum: 0960f1e77807058819451b98c51d4cd72031593e8de990b24bd3fc22e176f5eee22921d68d852297c786aec117689f0423ed20aa4fde7ce2704d680677891f56 + has-tostringtag: "npm:^1.0.2" + checksum: 4465d5348c044032032251be54d8988270e69c6b7154f8fcb2a47ff706fe36f7624b3a24246b8d9089435a8f4ec48c1c1025c5d6b499456b9e5eff4f48212983 languageName: node linkType: hard @@ -25496,7 +25115,7 @@ __metadata: languageName: node linkType: hard -"winston-transport@npm:^4.5.0": +"winston-transport@npm:^4.7.0": version: 4.7.0 resolution: "winston-transport@npm:4.7.0" dependencies: @@ -25508,8 +25127,8 @@ __metadata: linkType: hard "winston@npm:*, winston@npm:^3.3.3": - version: 3.11.0 - resolution: "winston@npm:3.11.0" + version: 3.13.0 + resolution: "winston@npm:3.13.0" dependencies: "@colors/colors": "npm:^1.6.0" "@dabh/diagnostics": "npm:^2.0.2" @@ -25521,8 +25140,8 @@ __metadata: safe-stable-stringify: "npm:^2.3.1" stack-trace: "npm:0.0.x" triple-beam: "npm:^1.3.0" - winston-transport: "npm:^4.5.0" - checksum: 7e1f8919cbdc62cfe46e6204d79a83e1364696ef61111483f3ecf204988922383fe74192c5bc9f89df9b47caf24c2d34f5420ef6f3b693f8d1286b46432e97be + winston-transport: "npm:^4.7.0" + checksum: 2c3cc7389a691e1638edcb0d4bfea72caa82d87d5681ec6131ac9bae780d94d06fb7b112edcd4ec37c8b947a1b64943941b761e34d67c6b0dac6e9c31ae4b25b languageName: node linkType: hard @@ -25549,7 +25168,7 @@ __metadata: languageName: node linkType: hard -"word-wrap@npm:~1.2.3": +"word-wrap@npm:^1.2.5, word-wrap@npm:~1.2.3": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" checksum: e0e4a1ca27599c92a6ca4c32260e8a92e8a44f4ef6ef93f803f8ed823f486e0889fc0b93be4db59c8d51b3064951d25e43d434e95dc8c960cc3a63d65d00ba20 @@ -25722,8 +25341,8 @@ __metadata: linkType: hard "ws@npm:^8.12.0, ws@npm:^8.13.0": - version: 8.16.0 - resolution: "ws@npm:8.16.0" + version: 8.17.0 + resolution: "ws@npm:8.17.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -25732,7 +25351,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: a7783bb421c648b1e622b423409cb2a58ac5839521d2f689e84bc9dc41d59379c692dd405b15a997ea1d4c0c2e5314ad707332d0c558f15232d2bc07c0b4618a + checksum: 55241ec93a66fdfc4bf4f8bc66c8eb038fda2c7a4ee8f6f157f2ca7dc7aa76aea0c0da0bf3adb2af390074a70a0e45456a2eaf80e581e630b75df10a64b0a990 languageName: node linkType: hard @@ -26044,17 +25663,17 @@ __metadata: linkType: hard "zod-to-json-schema@npm:^3.20.5": - version: 3.22.4 - resolution: "zod-to-json-schema@npm:3.22.4" + version: 3.23.0 + resolution: "zod-to-json-schema@npm:3.23.0" peerDependencies: - zod: ^3.22.4 - checksum: a949720c165347982a4abf5d612b78bebc2b5fb1217d22e20c024782ce6a9ae0baffe5deb6ba6f961ffa7b28b888c37f744bbfee6d7e9d74f2ec1f94d6968f0d + zod: ^3.23.3 + checksum: bcd966fa040765d7170a89c0c5f1717575e7d8823b84cbbb606689d494ae308c9eaadd4b71a74752e3170deef64c1f1bb2985f4663c44a0ed2e7854ff6fda724 languageName: node linkType: hard "zod@npm:^3.21.4": - version: 3.22.4 - resolution: "zod@npm:3.22.4" - checksum: 7578ab283dac0eee66a0ad0fc4a7f28c43e6745aadb3a529f59a4b851aa10872b3890398b3160f257f4b6817b4ce643debdda4fb21a2c040adda7862cab0a587 + version: 3.23.8 + resolution: "zod@npm:3.23.8" + checksum: 8f14c87d6b1b53c944c25ce7a28616896319d95bc46a9660fe441adc0ed0a81253b02b5abdaeffedbeb23bdd25a0bf1c29d2c12dd919aef6447652dd295e3e69 languageName: node linkType: hard From 06d8308ebf2a1e913c5e8a4b05e27fdcf813dcd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 20 May 2024 11:52:26 -0300 Subject: [PATCH 2/3] chore: turn solhint plugin into package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- README.md | 3 +- package.json | 1 + packages/solhint-graph-config/package.json | 3 +- .../plugin => solhint-plugin-graph}/index.js | 0 .../package.json | 4 +- packages/subgraph-service/package.json | 2 +- yarn.lock | 50 ++++++++----------- 7 files changed, 29 insertions(+), 34 deletions(-) rename packages/{solhint-graph-config/plugin => solhint-plugin-graph}/index.js (100%) rename packages/{solhint-graph-config/plugin => solhint-plugin-graph}/package.json (69%) diff --git a/README.md b/README.md index d9b46bb52..eb1b61d06 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,8 @@ This repository is a Yarn workspaces monorepo containing the following packages: | [eslint-graph-config](./packages/eslint-graph-config) | [![npm version]()]() | Shared linting and formatting rules for TypeScript projects. | | [horizon](./packages/horizon) | [![npm version]()]() | Contracts for Graph Horizon, the next iteration of The Graph protocol. | | [sdk](./packages/sdk) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Fsdk.svg)](https://badge.fury.io/js/@graphprotocol%2Fsdk) | TypeScript based SDK to interact with the protocol contracts | -| [solhint-graph-config](./packages/eslint-graph-config) | [![npm version]()]() | Shared linting and formatting rules for Solidity projects. | +| [solhint-graph-config](./packages/solhint-graph-config) | [![npm version]()]() | Shared linting and formatting rules for Solidity projects. | +| [solhint-plugin-graph](./packages/solhint-plugin-graph) | [![npm version]()]() | Plugin for Solhint with specific Graph linting rules. | | [subgraph-service](./packages/subgraph-service) | [![npm version]()]() | Contracts for the Subgraph data service in Graph Horizon. | | [token-distribution](./packages/token-distribution) | - | Contracts managing token locks for network participants | diff --git a/package.json b/package.json index 126006c96..6b82fd5a4 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "packages/horizon", "packages/sdk", "packages/solhint-graph-config", + "packages/solhint-plugin-graph", "packages/subgraph-service", "packages/token-distribution" ], diff --git a/packages/solhint-graph-config/package.json b/packages/solhint-graph-config/package.json index d976b3cb9..5b516ed58 100644 --- a/packages/solhint-graph-config/package.json +++ b/packages/solhint-graph-config/package.json @@ -1,12 +1,13 @@ { "name": "solhint-graph-config", + "private": true, "version": "0.0.1", "description": "Linting and formatting rules for The Graph's Solidity projects", "main": "index.js", "author": "The Graph Team", "license": "GPL-2.0-or-later", "dependencies": { - "solhint-plugin-graph": "file:plugin" + "solhint-plugin-graph": "workspace:*" }, "peerDependencies": { "prettier": "^3.2.5", diff --git a/packages/solhint-graph-config/plugin/index.js b/packages/solhint-plugin-graph/index.js similarity index 100% rename from packages/solhint-graph-config/plugin/index.js rename to packages/solhint-plugin-graph/index.js diff --git a/packages/solhint-graph-config/plugin/package.json b/packages/solhint-plugin-graph/package.json similarity index 69% rename from packages/solhint-graph-config/plugin/package.json rename to packages/solhint-plugin-graph/package.json index 53bab497d..1b1c0f568 100644 --- a/packages/solhint-graph-config/plugin/package.json +++ b/packages/solhint-plugin-graph/package.json @@ -1,5 +1,5 @@ { "name": "solhint-plugin-graph", - "version": "0.0.0", + "version": "0.0.1", "private": true -} \ No newline at end of file +} diff --git a/packages/subgraph-service/package.json b/packages/subgraph-service/package.json index f66d229de..144263417 100644 --- a/packages/subgraph-service/package.json +++ b/packages/subgraph-service/package.json @@ -39,7 +39,7 @@ "prettier-plugin-solidity": "^1.3.1", "solhint": "^4.5.4", "solhint-graph-config": "workspace:^0.0.1", - "solhint-plugin-graph": "file:node_modules/solhint-graph-config/plugin", + "solhint-plugin-graph": "workspace:^0.0.1", "solidity-coverage": "^0.8.0", "solidity-docgen": "^0.6.0-beta.36", "ts-node": ">=8.0.0", diff --git a/yarn.lock b/yarn.lock index 1e14c7d52..bed525f83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -863,8 +863,8 @@ __metadata: linkType: hard "@changesets/cli@npm:^2.27.1": - version: 2.27.2 - resolution: "@changesets/cli@npm:2.27.2" + version: 2.27.3 + resolution: "@changesets/cli@npm:2.27.3" dependencies: "@babel/runtime": "npm:^7.20.1" "@changesets/apply-release-plan": "npm:^7.0.1" @@ -900,7 +900,7 @@ __metadata: tty-table: "npm:^4.1.5" bin: changeset: bin.js - checksum: c2fd356b235bb27de0267389af38bca356d1c61892d0d3e114cec2e628aa6e7aadfe1828d9024b9c7d8005c3b968760ab4d781d4ce3a04309d5263d710341bec + checksum: fee10ae204926dbf4847111bf49ca93dc5b43a55b48635e2e08e71ab8442cf414c8165ae11174d6366ef12305274ea1b75beb14ca74b9a766d82b8c32148199b languageName: node linkType: hard @@ -3024,7 +3024,7 @@ __metadata: prettier-plugin-solidity: "npm:^1.3.1" solhint: "npm:^4.5.4" solhint-graph-config: "workspace:^0.0.1" - solhint-plugin-graph: "file:node_modules/solhint-graph-config/plugin" + solhint-plugin-graph: "workspace:^0.0.1" solidity-coverage: "npm:^0.8.0" solidity-docgen: "npm:^0.6.0-beta.36" ts-node: "npm:>=8.0.0" @@ -4766,28 +4766,28 @@ __metadata: linkType: hard "@openzeppelin/defender-admin-client@npm:^1.46.0": - version: 1.54.2 - resolution: "@openzeppelin/defender-admin-client@npm:1.54.2" + version: 1.54.4 + resolution: "@openzeppelin/defender-admin-client@npm:1.54.4" dependencies: - "@openzeppelin/defender-base-client": "npm:1.54.2" + "@openzeppelin/defender-base-client": "npm:1.54.4" axios: "npm:^1.4.0" ethers: "npm:^5.7.2" lodash: "npm:^4.17.19" node-fetch: "npm:^2.6.0" - checksum: fff2a74f840168d65a7cc51992610c199eb0d2b54b63f84060dded898d2730e0b008b3f492251ec99a697d45e69987a203ee005b5912e51a2786407755e3e53f + checksum: a44439ebde420aa35b36db7c2845978dd099e0fb6edc394e7b65be67ec1135e99ccc8059e78cb70c8a8fd5598ba40d082648664af95f9cb97a7673c075f64abb languageName: node linkType: hard -"@openzeppelin/defender-base-client@npm:1.54.2, @openzeppelin/defender-base-client@npm:^1.46.0": - version: 1.54.2 - resolution: "@openzeppelin/defender-base-client@npm:1.54.2" +"@openzeppelin/defender-base-client@npm:1.54.4, @openzeppelin/defender-base-client@npm:^1.46.0": + version: 1.54.4 + resolution: "@openzeppelin/defender-base-client@npm:1.54.4" dependencies: amazon-cognito-identity-js: "npm:^6.0.1" async-retry: "npm:^1.3.3" axios: "npm:^1.4.0" lodash: "npm:^4.17.19" node-fetch: "npm:^2.6.0" - checksum: b30c5c5ed47ed0ff788025abd0cdfc816fdbd49065c221be7e760385e5cbf5b05488ed1cfb040c5cbe0a1ca6cc6af035dc88a6e5b2c09fb9ae4ae048493014bd + checksum: 636614a8012cfbbe065b8ccc3ef6a16635e2f1b48f7421242de81f74def99a51795464e9a2bd02e7305ff32b339a8847d7733452e6fe7810d4badd0c2086c38f languageName: node linkType: hard @@ -7215,13 +7215,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0, axios@npm:^1.5.1": - version: 1.6.8 - resolution: "axios@npm:1.6.8" + version: 1.7.1 + resolution: "axios@npm:1.7.1" dependencies: follow-redirects: "npm:^1.15.6" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: 0f22da6f490335479a89878bc7d5a1419484fbb437b564a80c34888fc36759ae4f56ea28d55a191695e5ed327f0bad56e7ff60fb6770c14d1be6501505d47ab9 + checksum: 554395472f18f4ddb43b4be2900473bc1a4d589464a8ab16f6954c53d9cace4317d5c9e009d5bb05f098d9565b2fa45f152a5d4cecb87536c8f0c370c25a7770 languageName: node linkType: hard @@ -21783,7 +21783,7 @@ __metadata: version: 0.0.0-use.local resolution: "solhint-graph-config@workspace:packages/solhint-graph-config" dependencies: - solhint-plugin-graph: "file:plugin" + solhint-plugin-graph: "workspace:*" peerDependencies: prettier: ^3.2.5 prettier-plugin-solidity: ^1.3.1 @@ -21791,19 +21791,11 @@ __metadata: languageName: unknown linkType: soft -"solhint-plugin-graph@file:node_modules/solhint-graph-config/plugin::locator=%40graphprotocol%2Fsubgraph-service%40workspace%3Apackages%2Fsubgraph-service": - version: 0.0.0 - resolution: "solhint-plugin-graph@file:node_modules/solhint-graph-config/plugin#node_modules/solhint-graph-config/plugin::hash=37bdb1&locator=%40graphprotocol%2Fsubgraph-service%40workspace%3Apackages%2Fsubgraph-service" - checksum: f77aeda80dc6f8bb93376c3b05e910874038e701793f7805e9937f0047e68d3ac8595d915a4cb12dd974c49851d2b0fdf94742b0b2865cd7bf7e3a630177dfea - languageName: node - linkType: hard - -"solhint-plugin-graph@file:plugin::locator=solhint-graph-config%40workspace%3Apackages%2Fsolhint-graph-config": - version: 0.0.0 - resolution: "solhint-plugin-graph@file:plugin#plugin::hash=37bdb1&locator=solhint-graph-config%40workspace%3Apackages%2Fsolhint-graph-config" - checksum: f77aeda80dc6f8bb93376c3b05e910874038e701793f7805e9937f0047e68d3ac8595d915a4cb12dd974c49851d2b0fdf94742b0b2865cd7bf7e3a630177dfea - languageName: node - linkType: hard +"solhint-plugin-graph@workspace:*, solhint-plugin-graph@workspace:^0.0.1, solhint-plugin-graph@workspace:packages/solhint-plugin-graph": + version: 0.0.0-use.local + resolution: "solhint-plugin-graph@workspace:packages/solhint-plugin-graph" + languageName: unknown + linkType: soft "solhint-plugin-prettier@npm:^0.1.0": version: 0.1.0 From 7aa37984931aa5686721df975cdd8d71f37edb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 20 May 2024 14:23:47 -0300 Subject: [PATCH 3/3] chore: move data service framework, rework file structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- packages/horizon/contracts/SimpleTest.sol | 10 ------ .../contracts/data-service/DataService.sol | 4 +-- .../data-service/DataServiceStorage.sol | 0 .../contracts/data-service/GraphDirectory.sol | 2 +- .../extensions/DataServiceFees.sol | 6 ++-- .../extensions/DataServiceFeesStorage.sol | 2 ++ .../extensions/DataServicePausable.sol | 0 .../extensions/DataServiceRescuable.sol | 2 +- .../extensions/IDataServiceFees.sol | 2 +- .../extensions/IDataServicePausable.sol | 2 +- .../extensions/IDataServiceRescuable.sol | 2 +- .../libraries/ProvisionGetter.sol | 2 +- .../libraries/ProvisionTracker.sol | 12 ++++--- .../utilities/ProvisionManager.sol | 10 +++--- .../utilities/ProvisionManagerStorage.sol | 0 .../contracts/interfaces}/IDataService.sol | 2 +- .../contracts/interfaces/IGraphEscrow.sol | 0 .../contracts/interfaces/IGraphPayments.sol | 0 .../{ => interfaces}/IGraphToken.sol | 2 +- .../{ => interfaces}/IHorizonStaking.sol | 0 .../{ => interfaces}/IHorizonStakingBase.sol | 0 .../IHorizonStakingExtension.sol | 0 .../{ => interfaces}/IHorizonStakingTypes.sol | 0 .../contracts/{ => interfaces}/IManaged.sol | 0 .../IStakingBackwardsCompatibility.sol | 0 .../contracts/interfaces/ITAPVerifier.sol | 0 .../contracts}/libraries/Denominations.sol | 0 .../{utils => libraries}/LibFixedMath.sol | 0 .../{utils => libraries}/MathUtils.sol | 0 .../contracts}/libraries/PPMMath.sol | 0 .../{utils => libraries}/TokenUtils.sol | 2 +- .../contracts}/libraries/UintRange.sol | 0 .../payments/collectors}/TAPVerifier.sol | 2 +- .../{ => staking}/HorizonStaking.sol | 11 ++++--- .../{ => staking}/HorizonStakingExtension.sol | 13 ++++---- .../{ => staking}/HorizonStakingStorage.sol | 7 +++-- .../StakingBackwardsCompatibility.sol | 31 +++++++------------ .../libraries}/ExponentialRebates.sol | 4 +-- .../{ => staking/utilities}/Managed.sol | 5 +-- packages/horizon/scripts/deploy.ts | 28 ----------------- packages/horizon/test/HorizonStaking.t.sol | 12 +++---- packages/horizon/test/HorizonStaking.ts | 4 +-- packages/horizon/test/SimpleTest.t.sol | 17 ---------- packages/horizon/test/SimpleTest.ts | 23 -------------- .../contracts/DisputeManager.sol | 12 ++++--- .../contracts/SubgraphService.sol | 22 ++++++------- .../contracts/SubgraphServiceStorage.sol | 2 +- .../contracts/interfaces/ISubgraphService.sol | 4 +-- .../contracts/utilities/AllocationManager.sol | 26 ++++++++++------ .../contracts/utilities/Directory.sol | 2 +- packages/subgraph-service/package.json | 1 + packages/subgraph-service/remappings.txt | 1 + .../test/mocks/MockHorizonStaking.sol | 24 ++++++++------ yarn.lock | 3 +- 54 files changed, 127 insertions(+), 189 deletions(-) delete mode 100644 packages/horizon/contracts/SimpleTest.sol rename packages/{subgraph-service => horizon}/contracts/data-service/DataService.sol (96%) rename packages/{subgraph-service => horizon}/contracts/data-service/DataServiceStorage.sol (100%) rename packages/{subgraph-service => horizon}/contracts/data-service/GraphDirectory.sol (96%) rename packages/{subgraph-service => horizon}/contracts/data-service/extensions/DataServiceFees.sol (98%) rename packages/{subgraph-service => horizon}/contracts/data-service/extensions/DataServiceFeesStorage.sol (96%) rename packages/{subgraph-service => horizon}/contracts/data-service/extensions/DataServicePausable.sol (100%) rename packages/{subgraph-service => horizon}/contracts/data-service/extensions/DataServiceRescuable.sol (97%) rename packages/{subgraph-service => horizon}/contracts/data-service/extensions/IDataServiceFees.sol (91%) rename packages/{subgraph-service => horizon}/contracts/data-service/extensions/IDataServicePausable.sol (73%) rename packages/{subgraph-service => horizon}/contracts/data-service/extensions/IDataServiceRescuable.sol (79%) rename packages/{subgraph-service => horizon}/contracts/data-service/libraries/ProvisionGetter.sol (87%) rename packages/{subgraph-service => horizon}/contracts/data-service/libraries/ProvisionTracker.sol (82%) rename packages/{subgraph-service => horizon}/contracts/data-service/utilities/ProvisionManager.sol (95%) rename packages/{subgraph-service => horizon}/contracts/data-service/utilities/ProvisionManagerStorage.sol (100%) rename packages/{subgraph-service/contracts/data-service => horizon/contracts/interfaces}/IDataService.sol (99%) rename packages/{subgraph-service => horizon}/contracts/interfaces/IGraphEscrow.sol (100%) rename packages/{subgraph-service => horizon}/contracts/interfaces/IGraphPayments.sol (100%) rename packages/horizon/contracts/{ => interfaces}/IGraphToken.sol (93%) rename packages/horizon/contracts/{ => interfaces}/IHorizonStaking.sol (100%) rename packages/horizon/contracts/{ => interfaces}/IHorizonStakingBase.sol (100%) rename packages/horizon/contracts/{ => interfaces}/IHorizonStakingExtension.sol (100%) rename packages/horizon/contracts/{ => interfaces}/IHorizonStakingTypes.sol (100%) rename packages/horizon/contracts/{ => interfaces}/IManaged.sol (100%) rename packages/horizon/contracts/{ => interfaces}/IStakingBackwardsCompatibility.sol (100%) rename packages/{subgraph-service => horizon}/contracts/interfaces/ITAPVerifier.sol (100%) rename packages/{subgraph-service/contracts/data-service => horizon/contracts}/libraries/Denominations.sol (100%) rename packages/horizon/contracts/{utils => libraries}/LibFixedMath.sol (100%) rename packages/horizon/contracts/{utils => libraries}/MathUtils.sol (100%) rename packages/{subgraph-service/contracts/data-service => horizon/contracts}/libraries/PPMMath.sol (100%) rename packages/horizon/contracts/{utils => libraries}/TokenUtils.sol (96%) rename packages/{subgraph-service/contracts/data-service => horizon/contracts}/libraries/UintRange.sol (100%) rename packages/{subgraph-service/contracts => horizon/contracts/payments/collectors}/TAPVerifier.sol (99%) rename packages/horizon/contracts/{ => staking}/HorizonStaking.sol (99%) rename packages/horizon/contracts/{ => staking}/HorizonStakingExtension.sol (97%) rename packages/horizon/contracts/{ => staking}/HorizonStakingStorage.sol (96%) rename packages/horizon/contracts/{ => staking}/StakingBackwardsCompatibility.sol (96%) rename packages/horizon/contracts/{utils => staking/libraries}/ExponentialRebates.sol (96%) rename packages/horizon/contracts/{ => staking/utilities}/Managed.sol (96%) delete mode 100644 packages/horizon/scripts/deploy.ts delete mode 100644 packages/horizon/test/SimpleTest.t.sol delete mode 100644 packages/horizon/test/SimpleTest.ts diff --git a/packages/horizon/contracts/SimpleTest.sol b/packages/horizon/contracts/SimpleTest.sol deleted file mode 100644 index 5cc28d9cc..000000000 --- a/packages/horizon/contracts/SimpleTest.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.4.0 <0.9.0; - -import { Test } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; - -contract SimpleTest is Test { - function test() external pure returns (uint256) { - return 42; - } -} diff --git a/packages/subgraph-service/contracts/data-service/DataService.sol b/packages/horizon/contracts/data-service/DataService.sol similarity index 96% rename from packages/subgraph-service/contracts/data-service/DataService.sol rename to packages/horizon/contracts/data-service/DataService.sol index 52f1e25b5..f256cbba7 100644 --- a/packages/subgraph-service/contracts/data-service/DataService.sol +++ b/packages/horizon/contracts/data-service/DataService.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IDataService } from "./IDataService.sol"; +import { IDataService } from "../interfaces/IDataService.sol"; -import { GraphDirectory } from "./GraphDirectory.sol"; import { DataServiceV1Storage } from "./DataServiceStorage.sol"; +import { GraphDirectory } from "./GraphDirectory.sol"; import { ProvisionManager } from "./utilities/ProvisionManager.sol"; /** diff --git a/packages/subgraph-service/contracts/data-service/DataServiceStorage.sol b/packages/horizon/contracts/data-service/DataServiceStorage.sol similarity index 100% rename from packages/subgraph-service/contracts/data-service/DataServiceStorage.sol rename to packages/horizon/contracts/data-service/DataServiceStorage.sol diff --git a/packages/subgraph-service/contracts/data-service/GraphDirectory.sol b/packages/horizon/contracts/data-service/GraphDirectory.sol similarity index 96% rename from packages/subgraph-service/contracts/data-service/GraphDirectory.sol rename to packages/horizon/contracts/data-service/GraphDirectory.sol index f35a7a663..b79d7de52 100644 --- a/packages/subgraph-service/contracts/data-service/GraphDirectory.sol +++ b/packages/horizon/contracts/data-service/GraphDirectory.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import { IController } from "@graphprotocol/contracts/contracts/governance/IController.sol"; -import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; +import { IHorizonStaking } from "../interfaces/IHorizonStaking.sol"; import { IGraphToken } from "@graphprotocol/contracts/contracts/token/IGraphToken.sol"; // import { IGraphTokenGateway } from "@graphprotocol/contracts/contracts/gateway/IGraphTokenGateway.sol"; import { IEpochManager } from "@graphprotocol/contracts/contracts/epochs/IEpochManager.sol"; diff --git a/packages/subgraph-service/contracts/data-service/extensions/DataServiceFees.sol b/packages/horizon/contracts/data-service/extensions/DataServiceFees.sol similarity index 98% rename from packages/subgraph-service/contracts/data-service/extensions/DataServiceFees.sol rename to packages/horizon/contracts/data-service/extensions/DataServiceFees.sol index 583f01efa..3978d9a48 100644 --- a/packages/subgraph-service/contracts/data-service/extensions/DataServiceFees.sol +++ b/packages/horizon/contracts/data-service/extensions/DataServiceFees.sol @@ -4,11 +4,11 @@ pragma solidity ^0.8.24; import { IDataServiceFees } from "./IDataServiceFees.sol"; import { IGraphPayments } from "../../interfaces/IGraphPayments.sol"; +import { ProvisionTracker } from "../libraries/ProvisionTracker.sol"; + import { DataService } from "../DataService.sol"; import { DataServiceFeesV1Storage } from "./DataServiceFeesStorage.sol"; -import { ProvisionTracker } from "../libraries/ProvisionTracker.sol"; - abstract contract DataServiceFees is DataService, DataServiceFeesV1Storage, IDataServiceFees { using ProvisionTracker for mapping(address => uint256); @@ -66,7 +66,7 @@ abstract contract DataServiceFees is DataService, DataServiceFeesV1Storage, IDat uint256 _tokens, uint256 _unlockTimestamp ) internal { - feesProvisionTracker[_feeType].lock(GRAPH_STAKING, _serviceProvider, _tokens); + feesProvisionTracker[_feeType].lock(GRAPH_STAKING, _serviceProvider, _tokens, delegationRatio); StakeClaimsList storage claimsList = claimsLists[_feeType][_serviceProvider]; bytes32 claimId = _buildStakeClaimId(_serviceProvider, claimsList.nonce); diff --git a/packages/subgraph-service/contracts/data-service/extensions/DataServiceFeesStorage.sol b/packages/horizon/contracts/data-service/extensions/DataServiceFeesStorage.sol similarity index 96% rename from packages/subgraph-service/contracts/data-service/extensions/DataServiceFeesStorage.sol rename to packages/horizon/contracts/data-service/extensions/DataServiceFeesStorage.sol index 4296a952a..d64f99239 100644 --- a/packages/subgraph-service/contracts/data-service/extensions/DataServiceFeesStorage.sol +++ b/packages/horizon/contracts/data-service/extensions/DataServiceFeesStorage.sol @@ -15,6 +15,8 @@ abstract contract DataServiceFeesV1Storage { mapping(IGraphPayments.PaymentTypes feeType => mapping(address serviceProvider => IDataServiceFees.StakeClaimsList list)) public claimsLists; + uint32 public delegationRatio; + /// @dev Gap to allow adding variables in future upgrades uint256[50] private __gap; } diff --git a/packages/subgraph-service/contracts/data-service/extensions/DataServicePausable.sol b/packages/horizon/contracts/data-service/extensions/DataServicePausable.sol similarity index 100% rename from packages/subgraph-service/contracts/data-service/extensions/DataServicePausable.sol rename to packages/horizon/contracts/data-service/extensions/DataServicePausable.sol diff --git a/packages/subgraph-service/contracts/data-service/extensions/DataServiceRescuable.sol b/packages/horizon/contracts/data-service/extensions/DataServiceRescuable.sol similarity index 97% rename from packages/subgraph-service/contracts/data-service/extensions/DataServiceRescuable.sol rename to packages/horizon/contracts/data-service/extensions/DataServiceRescuable.sol index 7e6120783..76a25162a 100644 --- a/packages/subgraph-service/contracts/data-service/extensions/DataServiceRescuable.sol +++ b/packages/horizon/contracts/data-service/extensions/DataServiceRescuable.sol @@ -6,7 +6,7 @@ import { IDataServiceRescuable } from "./IDataServiceRescuable.sol"; import { DataService } from "../DataService.sol"; -import { Denominations } from "../libraries/Denominations.sol"; +import { Denominations } from "../../libraries/Denominations.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /** diff --git a/packages/subgraph-service/contracts/data-service/extensions/IDataServiceFees.sol b/packages/horizon/contracts/data-service/extensions/IDataServiceFees.sol similarity index 91% rename from packages/subgraph-service/contracts/data-service/extensions/IDataServiceFees.sol rename to packages/horizon/contracts/data-service/extensions/IDataServiceFees.sol index 36caf73f1..fe75755fe 100644 --- a/packages/subgraph-service/contracts/data-service/extensions/IDataServiceFees.sol +++ b/packages/horizon/contracts/data-service/extensions/IDataServiceFees.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IDataService } from "../IDataService.sol"; +import { IDataService } from "../../interfaces/IDataService.sol"; import { IGraphPayments } from "../../interfaces/IGraphPayments.sol"; interface IDataServiceFees is IDataService { diff --git a/packages/subgraph-service/contracts/data-service/extensions/IDataServicePausable.sol b/packages/horizon/contracts/data-service/extensions/IDataServicePausable.sol similarity index 73% rename from packages/subgraph-service/contracts/data-service/extensions/IDataServicePausable.sol rename to packages/horizon/contracts/data-service/extensions/IDataServicePausable.sol index 5b2940d6c..302e8a67e 100644 --- a/packages/subgraph-service/contracts/data-service/extensions/IDataServicePausable.sol +++ b/packages/horizon/contracts/data-service/extensions/IDataServicePausable.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IDataService } from "../IDataService.sol"; +import { IDataService } from "../../interfaces/IDataService.sol"; interface IDataServicePausable is IDataService { function pause() external; diff --git a/packages/subgraph-service/contracts/data-service/extensions/IDataServiceRescuable.sol b/packages/horizon/contracts/data-service/extensions/IDataServiceRescuable.sol similarity index 79% rename from packages/subgraph-service/contracts/data-service/extensions/IDataServiceRescuable.sol rename to packages/horizon/contracts/data-service/extensions/IDataServiceRescuable.sol index 36ad6d68f..ee379315c 100644 --- a/packages/subgraph-service/contracts/data-service/extensions/IDataServiceRescuable.sol +++ b/packages/horizon/contracts/data-service/extensions/IDataServiceRescuable.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IDataService } from "../IDataService.sol"; +import { IDataService } from "../../interfaces/IDataService.sol"; interface IDataServiceRescuable is IDataService { function rescueGRT(address to, uint256 amount) external; diff --git a/packages/subgraph-service/contracts/data-service/libraries/ProvisionGetter.sol b/packages/horizon/contracts/data-service/libraries/ProvisionGetter.sol similarity index 87% rename from packages/subgraph-service/contracts/data-service/libraries/ProvisionGetter.sol rename to packages/horizon/contracts/data-service/libraries/ProvisionGetter.sol index 4de039012..6fdf1e2c4 100644 --- a/packages/subgraph-service/contracts/data-service/libraries/ProvisionGetter.sol +++ b/packages/horizon/contracts/data-service/libraries/ProvisionGetter.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; +import { IHorizonStaking } from "../../interfaces/IHorizonStaking.sol"; library ProvisionGetter { using ProvisionGetter for IHorizonStaking.Provision; diff --git a/packages/subgraph-service/contracts/data-service/libraries/ProvisionTracker.sol b/packages/horizon/contracts/data-service/libraries/ProvisionTracker.sol similarity index 82% rename from packages/subgraph-service/contracts/data-service/libraries/ProvisionTracker.sol rename to packages/horizon/contracts/data-service/libraries/ProvisionTracker.sol index 216bbe3dc..f0acc7f89 100644 --- a/packages/subgraph-service/contracts/data-service/libraries/ProvisionTracker.sol +++ b/packages/horizon/contracts/data-service/libraries/ProvisionTracker.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; +import { IHorizonStaking } from "../../interfaces/IHorizonStaking.sol"; library ProvisionTracker { error ProvisionTrackerInsufficientTokens(uint256 tokensAvailable, uint256 tokensRequired); @@ -10,12 +10,13 @@ library ProvisionTracker { mapping(address => uint256) storage self, IHorizonStaking graphStaking, address serviceProvider, - uint256 tokens + uint256 tokens, + uint32 delegationRatio ) internal { if (tokens == 0) return; uint256 tokensRequired = self[serviceProvider] + tokens; - uint256 tokensAvailable = graphStaking.getTokensAvailable(serviceProvider, address(this)); + uint256 tokensAvailable = graphStaking.getTokensAvailable(serviceProvider, address(this), delegationRatio); if (tokensRequired > tokensAvailable) { revert ProvisionTrackerInsufficientTokens(tokensAvailable, tokensRequired); } @@ -34,9 +35,10 @@ library ProvisionTracker { function getTokensFree( mapping(address => uint256) storage self, IHorizonStaking graphStaking, - address serviceProvider + address serviceProvider, + uint32 delegationRatio ) internal view returns (uint256) { - uint256 tokensAvailable = graphStaking.getTokensAvailable(serviceProvider, address(this)); + uint256 tokensAvailable = graphStaking.getTokensAvailable(serviceProvider, address(this), delegationRatio); if (tokensAvailable >= self[serviceProvider]) return tokensAvailable - self[serviceProvider]; else return 0; } diff --git a/packages/subgraph-service/contracts/data-service/utilities/ProvisionManager.sol b/packages/horizon/contracts/data-service/utilities/ProvisionManager.sol similarity index 95% rename from packages/subgraph-service/contracts/data-service/utilities/ProvisionManager.sol rename to packages/horizon/contracts/data-service/utilities/ProvisionManager.sol index 581cff131..dd9d2677f 100644 --- a/packages/subgraph-service/contracts/data-service/utilities/ProvisionManager.sol +++ b/packages/horizon/contracts/data-service/utilities/ProvisionManager.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; +import { IHorizonStaking } from "../../interfaces/IHorizonStaking.sol"; + +import { ProvisionGetter } from "../libraries/ProvisionGetter.sol"; +import { UintRange } from "../../libraries/UintRange.sol"; import { GraphDirectory } from "../GraphDirectory.sol"; import { ProvisionManagerV1Storage } from "./ProvisionManagerStorage.sol"; -import { ProvisionGetter } from "../libraries/ProvisionGetter.sol"; -import { UintRange } from "../libraries/UintRange.sol"; - abstract contract ProvisionManager is GraphDirectory, ProvisionManagerV1Storage { using ProvisionGetter for IHorizonStaking; using UintRange for uint256; @@ -50,7 +50,7 @@ abstract contract ProvisionManager is GraphDirectory, ProvisionManagerV1Storage function _checkAndAcceptProvision(address _serviceProvider) internal virtual { _checkProvisionParameters(_serviceProvider); - GRAPH_STAKING.acceptProvision(_serviceProvider); + GRAPH_STAKING.acceptProvisionParameters(_serviceProvider); } // -- Provision Parameters: setters -- diff --git a/packages/subgraph-service/contracts/data-service/utilities/ProvisionManagerStorage.sol b/packages/horizon/contracts/data-service/utilities/ProvisionManagerStorage.sol similarity index 100% rename from packages/subgraph-service/contracts/data-service/utilities/ProvisionManagerStorage.sol rename to packages/horizon/contracts/data-service/utilities/ProvisionManagerStorage.sol diff --git a/packages/subgraph-service/contracts/data-service/IDataService.sol b/packages/horizon/contracts/interfaces/IDataService.sol similarity index 99% rename from packages/subgraph-service/contracts/data-service/IDataService.sol rename to packages/horizon/contracts/interfaces/IDataService.sol index 0e598b2cb..4064d4444 100644 --- a/packages/subgraph-service/contracts/data-service/IDataService.sol +++ b/packages/horizon/contracts/interfaces/IDataService.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IGraphPayments } from "../interfaces/IGraphPayments.sol"; +import { IGraphPayments } from "./IGraphPayments.sol"; /** * @title Interface of the base {DataService} contract as defined by the Graph Horizon specification. diff --git a/packages/subgraph-service/contracts/interfaces/IGraphEscrow.sol b/packages/horizon/contracts/interfaces/IGraphEscrow.sol similarity index 100% rename from packages/subgraph-service/contracts/interfaces/IGraphEscrow.sol rename to packages/horizon/contracts/interfaces/IGraphEscrow.sol diff --git a/packages/subgraph-service/contracts/interfaces/IGraphPayments.sol b/packages/horizon/contracts/interfaces/IGraphPayments.sol similarity index 100% rename from packages/subgraph-service/contracts/interfaces/IGraphPayments.sol rename to packages/horizon/contracts/interfaces/IGraphPayments.sol diff --git a/packages/horizon/contracts/IGraphToken.sol b/packages/horizon/contracts/interfaces/IGraphToken.sol similarity index 93% rename from packages/horizon/contracts/IGraphToken.sol rename to packages/horizon/contracts/interfaces/IGraphToken.sol index fd0b0a553..27f68a0d2 100644 --- a/packages/horizon/contracts/IGraphToken.sol +++ b/packages/horizon/contracts/interfaces/IGraphToken.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IGraphToken is IERC20 { // -- Mint and Burn -- diff --git a/packages/horizon/contracts/IHorizonStaking.sol b/packages/horizon/contracts/interfaces/IHorizonStaking.sol similarity index 100% rename from packages/horizon/contracts/IHorizonStaking.sol rename to packages/horizon/contracts/interfaces/IHorizonStaking.sol diff --git a/packages/horizon/contracts/IHorizonStakingBase.sol b/packages/horizon/contracts/interfaces/IHorizonStakingBase.sol similarity index 100% rename from packages/horizon/contracts/IHorizonStakingBase.sol rename to packages/horizon/contracts/interfaces/IHorizonStakingBase.sol diff --git a/packages/horizon/contracts/IHorizonStakingExtension.sol b/packages/horizon/contracts/interfaces/IHorizonStakingExtension.sol similarity index 100% rename from packages/horizon/contracts/IHorizonStakingExtension.sol rename to packages/horizon/contracts/interfaces/IHorizonStakingExtension.sol diff --git a/packages/horizon/contracts/IHorizonStakingTypes.sol b/packages/horizon/contracts/interfaces/IHorizonStakingTypes.sol similarity index 100% rename from packages/horizon/contracts/IHorizonStakingTypes.sol rename to packages/horizon/contracts/interfaces/IHorizonStakingTypes.sol diff --git a/packages/horizon/contracts/IManaged.sol b/packages/horizon/contracts/interfaces/IManaged.sol similarity index 100% rename from packages/horizon/contracts/IManaged.sol rename to packages/horizon/contracts/interfaces/IManaged.sol diff --git a/packages/horizon/contracts/IStakingBackwardsCompatibility.sol b/packages/horizon/contracts/interfaces/IStakingBackwardsCompatibility.sol similarity index 100% rename from packages/horizon/contracts/IStakingBackwardsCompatibility.sol rename to packages/horizon/contracts/interfaces/IStakingBackwardsCompatibility.sol diff --git a/packages/subgraph-service/contracts/interfaces/ITAPVerifier.sol b/packages/horizon/contracts/interfaces/ITAPVerifier.sol similarity index 100% rename from packages/subgraph-service/contracts/interfaces/ITAPVerifier.sol rename to packages/horizon/contracts/interfaces/ITAPVerifier.sol diff --git a/packages/subgraph-service/contracts/data-service/libraries/Denominations.sol b/packages/horizon/contracts/libraries/Denominations.sol similarity index 100% rename from packages/subgraph-service/contracts/data-service/libraries/Denominations.sol rename to packages/horizon/contracts/libraries/Denominations.sol diff --git a/packages/horizon/contracts/utils/LibFixedMath.sol b/packages/horizon/contracts/libraries/LibFixedMath.sol similarity index 100% rename from packages/horizon/contracts/utils/LibFixedMath.sol rename to packages/horizon/contracts/libraries/LibFixedMath.sol diff --git a/packages/horizon/contracts/utils/MathUtils.sol b/packages/horizon/contracts/libraries/MathUtils.sol similarity index 100% rename from packages/horizon/contracts/utils/MathUtils.sol rename to packages/horizon/contracts/libraries/MathUtils.sol diff --git a/packages/subgraph-service/contracts/data-service/libraries/PPMMath.sol b/packages/horizon/contracts/libraries/PPMMath.sol similarity index 100% rename from packages/subgraph-service/contracts/data-service/libraries/PPMMath.sol rename to packages/horizon/contracts/libraries/PPMMath.sol diff --git a/packages/horizon/contracts/utils/TokenUtils.sol b/packages/horizon/contracts/libraries/TokenUtils.sol similarity index 96% rename from packages/horizon/contracts/utils/TokenUtils.sol rename to packages/horizon/contracts/libraries/TokenUtils.sol index 7bfc7203c..07b267451 100644 --- a/packages/horizon/contracts/utils/TokenUtils.sol +++ b/packages/horizon/contracts/libraries/TokenUtils.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; -import { IGraphToken } from "../IGraphToken.sol"; +import { IGraphToken } from "../interfaces/IGraphToken.sol"; /** * @title TokenUtils library diff --git a/packages/subgraph-service/contracts/data-service/libraries/UintRange.sol b/packages/horizon/contracts/libraries/UintRange.sol similarity index 100% rename from packages/subgraph-service/contracts/data-service/libraries/UintRange.sol rename to packages/horizon/contracts/libraries/UintRange.sol diff --git a/packages/subgraph-service/contracts/TAPVerifier.sol b/packages/horizon/contracts/payments/collectors/TAPVerifier.sol similarity index 99% rename from packages/subgraph-service/contracts/TAPVerifier.sol rename to packages/horizon/contracts/payments/collectors/TAPVerifier.sol index e7b3d5a7f..735cc38a0 100644 --- a/packages/subgraph-service/contracts/TAPVerifier.sol +++ b/packages/horizon/contracts/payments/collectors/TAPVerifier.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { ITAPVerifier } from "./interfaces/ITAPVerifier.sol"; +import { ITAPVerifier } from "../../interfaces/ITAPVerifier.sol"; import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; diff --git a/packages/horizon/contracts/HorizonStaking.sol b/packages/horizon/contracts/staking/HorizonStaking.sol similarity index 99% rename from packages/horizon/contracts/HorizonStaking.sol rename to packages/horizon/contracts/staking/HorizonStaking.sol index 7b97260be..883e1f611 100644 --- a/packages/horizon/contracts/HorizonStaking.sol +++ b/packages/horizon/contracts/staking/HorizonStaking.sol @@ -3,12 +3,13 @@ pragma solidity 0.8.24; import { GraphUpgradeable } from "@graphprotocol/contracts/contracts/upgrades/GraphUpgradeable.sol"; +import { IHorizonStakingBase } from "../interfaces/IHorizonStakingBase.sol"; +import { IGraphToken } from "../interfaces/IGraphToken.sol"; -import { IHorizonStakingBase } from "./IHorizonStakingBase.sol"; -import { TokenUtils } from "./utils/TokenUtils.sol"; -import { MathUtils } from "./utils/MathUtils.sol"; -import { Managed } from "./Managed.sol"; -import { IGraphToken } from "./IGraphToken.sol"; +import { TokenUtils } from "../libraries/TokenUtils.sol"; +import { MathUtils } from "../libraries/MathUtils.sol"; + +import { Managed } from "./utilities/Managed.sol"; import { HorizonStakingV1Storage } from "./HorizonStakingStorage.sol"; /** diff --git a/packages/horizon/contracts/HorizonStakingExtension.sol b/packages/horizon/contracts/staking/HorizonStakingExtension.sol similarity index 97% rename from packages/horizon/contracts/HorizonStakingExtension.sol rename to packages/horizon/contracts/staking/HorizonStakingExtension.sol index 1ec8b2c45..0183e73f9 100644 --- a/packages/horizon/contracts/HorizonStakingExtension.sol +++ b/packages/horizon/contracts/staking/HorizonStakingExtension.sol @@ -2,11 +2,13 @@ pragma solidity 0.8.24; -import { StakingBackwardsCompatibility } from "./StakingBackwardsCompatibility.sol"; import { IL2StakingBase } from "@graphprotocol/contracts/contracts/l2/staking/IL2StakingBase.sol"; import { IL2StakingTypes } from "@graphprotocol/contracts/contracts/l2/staking/IL2StakingTypes.sol"; -import { IHorizonStakingExtension } from "./IHorizonStakingExtension.sol"; -import { MathUtils } from "./utils/MathUtils.sol"; +import { IHorizonStakingExtension } from "../interfaces/IHorizonStakingExtension.sol"; + +import { MathUtils } from "../libraries/MathUtils.sol"; + +import { StakingBackwardsCompatibility } from "./StakingBackwardsCompatibility.sol"; /** * @title L2Staking contract @@ -28,9 +30,8 @@ contract HorizonStakingExtension is StakingBackwardsCompatibility, IHorizonStaki constructor( address _controller, - address _subgraphDataServiceAddress, - address _exponentialRebates - ) StakingBackwardsCompatibility(_controller, _subgraphDataServiceAddress, _exponentialRebates) {} + address _subgraphDataServiceAddress + ) StakingBackwardsCompatibility(_controller, _subgraphDataServiceAddress) {} /** * @notice Receive ETH into the Staking contract: this will always revert diff --git a/packages/horizon/contracts/HorizonStakingStorage.sol b/packages/horizon/contracts/staking/HorizonStakingStorage.sol similarity index 96% rename from packages/horizon/contracts/HorizonStakingStorage.sol rename to packages/horizon/contracts/staking/HorizonStakingStorage.sol index 6506429a7..80e25f6ae 100644 --- a/packages/horizon/contracts/HorizonStakingStorage.sol +++ b/packages/horizon/contracts/staking/HorizonStakingStorage.sol @@ -2,9 +2,10 @@ pragma solidity 0.8.24; -import { Managed } from "./Managed.sol"; -import { IStakingBackwardsCompatibility } from "./IStakingBackwardsCompatibility.sol"; -import { IHorizonStakingTypes } from "./IHorizonStakingTypes.sol"; +import { IStakingBackwardsCompatibility } from "../interfaces/IStakingBackwardsCompatibility.sol"; +import { IHorizonStakingTypes } from "../interfaces/IHorizonStakingTypes.sol"; + +import { Managed } from "./utilities/Managed.sol"; /** * @title HorizonStakingV1Storage diff --git a/packages/horizon/contracts/StakingBackwardsCompatibility.sol b/packages/horizon/contracts/staking/StakingBackwardsCompatibility.sol similarity index 96% rename from packages/horizon/contracts/StakingBackwardsCompatibility.sol rename to packages/horizon/contracts/staking/StakingBackwardsCompatibility.sol index 6e6261bd4..0d8c2749e 100644 --- a/packages/horizon/contracts/StakingBackwardsCompatibility.sol +++ b/packages/horizon/contracts/staking/StakingBackwardsCompatibility.sol @@ -2,20 +2,20 @@ pragma solidity 0.8.24; -import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import { ICuration } from "@graphprotocol/contracts/contracts/curation/ICuration.sol"; +import { IRewardsManager } from "@graphprotocol/contracts/contracts/rewards/IRewardsManager.sol"; +import { IEpochManager } from "@graphprotocol/contracts/contracts/epochs/IEpochManager.sol"; +import { IGraphToken } from "../interfaces/IGraphToken.sol"; +import { IStakingBackwardsCompatibility } from "../interfaces/IStakingBackwardsCompatibility.sol"; + +import { TokenUtils } from "../libraries/TokenUtils.sol"; +import { MathUtils } from "../libraries/MathUtils.sol"; +import { ExponentialRebates } from "./libraries/ExponentialRebates.sol"; import { Multicall } from "@graphprotocol/contracts/contracts/base/Multicall.sol"; import { GraphUpgradeable } from "@graphprotocol/contracts/contracts/upgrades/GraphUpgradeable.sol"; -import { TokenUtils } from "./utils/TokenUtils.sol"; -import { IGraphToken } from "./IGraphToken.sol"; +import { Managed } from "./utilities/Managed.sol"; import { HorizonStakingV1Storage } from "./HorizonStakingStorage.sol"; -import { MathUtils } from "./utils/MathUtils.sol"; -import { Managed } from "./Managed.sol"; -import { ICuration } from "@graphprotocol/contracts/contracts/curation/ICuration.sol"; -import { IRewardsManager } from "@graphprotocol/contracts/contracts/rewards/IRewardsManager.sol"; -import { IEpochManager } from "@graphprotocol/contracts/contracts/epochs/IEpochManager.sol"; -import { ExponentialRebates } from "./utils/ExponentialRebates.sol"; -import { IStakingBackwardsCompatibility } from "./IStakingBackwardsCompatibility.sol"; /** * @title Base Staking contract @@ -38,15 +38,8 @@ abstract contract StakingBackwardsCompatibility is address public immutable SUBGRAPH_DATA_SERVICE_ADDRESS; - address public immutable EXPONENTIAL_REBATES_ADDRESS; - - constructor( - address _controller, - address _subgraphDataServiceAddress, - address _exponentialRebatesAddress - ) Managed(_controller) { + constructor(address _controller, address _subgraphDataServiceAddress) Managed(_controller) { SUBGRAPH_DATA_SERVICE_ADDRESS = _subgraphDataServiceAddress; - EXPONENTIAL_REBATES_ADDRESS = _exponentialRebatesAddress; } /** @@ -128,7 +121,7 @@ abstract contract StakingBackwardsCompatibility is // No rebates if indexer has no stake or if lambda is zero uint256 newRebates = (alloc.tokens == 0 || __DEPRECATED_lambdaNumerator == 0) ? 0 - : ExponentialRebates(EXPONENTIAL_REBATES_ADDRESS).exponentialRebates( + : ExponentialRebates.exponentialRebates( alloc.collectedFees, alloc.tokens, __DEPRECATED_alphaNumerator, diff --git a/packages/horizon/contracts/utils/ExponentialRebates.sol b/packages/horizon/contracts/staking/libraries/ExponentialRebates.sol similarity index 96% rename from packages/horizon/contracts/utils/ExponentialRebates.sol rename to packages/horizon/contracts/staking/libraries/ExponentialRebates.sol index d53efdca3..50579cafb 100644 --- a/packages/horizon/contracts/utils/ExponentialRebates.sol +++ b/packages/horizon/contracts/staking/libraries/ExponentialRebates.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; -import { LibFixedMath } from "./LibFixedMath.sol"; +import { LibFixedMath } from "../../libraries/LibFixedMath.sol"; /** * @title ExponentialRebates contract @@ -10,7 +10,7 @@ import { LibFixedMath } from "./LibFixedMath.sol"; * @dev This is only used for backwards compatibility in HorizonStaking, and should * be removed after the transition period. */ -contract ExponentialRebates { +library ExponentialRebates { /// @dev Maximum value of the exponent for which to compute the exponential before clamping to zero. uint32 private constant MAX_EXPONENT = 15; diff --git a/packages/horizon/contracts/Managed.sol b/packages/horizon/contracts/staking/utilities/Managed.sol similarity index 96% rename from packages/horizon/contracts/Managed.sol rename to packages/horizon/contracts/staking/utilities/Managed.sol index 858156bbd..685c18184 100644 --- a/packages/horizon/contracts/Managed.sol +++ b/packages/horizon/contracts/staking/utilities/Managed.sol @@ -3,8 +3,9 @@ pragma solidity 0.8.24; import { IController } from "@graphprotocol/contracts/contracts/governance/IController.sol"; -import { IManaged } from "./IManaged.sol"; -import { GraphDirectory } from "./GraphDirectory.sol"; +import { IManaged } from "../../interfaces/IManaged.sol"; + +import { GraphDirectory } from "../../GraphDirectory.sol"; /** * @title Graph Managed contract diff --git a/packages/horizon/scripts/deploy.ts b/packages/horizon/scripts/deploy.ts deleted file mode 100644 index cf87ff10f..000000000 --- a/packages/horizon/scripts/deploy.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ethers } from 'hardhat' - -async function main() { - const currentTimestampInSeconds = Math.round(Date.now() / 1000) - const unlockTime = currentTimestampInSeconds + 60 - - const lockedAmount = ethers.parseEther('0.001') - const a = 1 - console.log(a) - const lock = await ethers.deployContract('Lock', [unlockTime], { - value: lockedAmount, - }) - - await lock.waitForDeployment() - - console.log( - `Lock with ${ethers.formatEther( - lockedAmount, - )}ETH and unlock timestamp ${unlockTime} deployed to ${typeof lock.target == 'string' ? lock.target : ''}`, - ) -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error) - process.exitCode = 1 -}) diff --git a/packages/horizon/test/HorizonStaking.t.sol b/packages/horizon/test/HorizonStaking.t.sol index 144b0c7a5..55088f0fe 100644 --- a/packages/horizon/test/HorizonStaking.t.sol +++ b/packages/horizon/test/HorizonStaking.t.sol @@ -3,14 +3,13 @@ pragma solidity 0.8.24; import "forge-std/Test.sol"; import "forge-std/console.sol"; -import { HorizonStaking } from "../contracts/HorizonStaking.sol"; +import { HorizonStaking } from "../contracts/staking/HorizonStaking.sol"; import { ControllerMock } from "../contracts/mocks/ControllerMock.sol"; -import { HorizonStakingExtension } from "../contracts/HorizonStakingExtension.sol"; -import { ExponentialRebates } from "../contracts/utils/ExponentialRebates.sol"; -import { IHorizonStaking } from "../contracts/IHorizonStaking.sol"; +import { HorizonStakingExtension } from "../contracts/staking/HorizonStakingExtension.sol"; +import { ExponentialRebates } from "../contracts/staking/libraries/ExponentialRebates.sol"; +import { IHorizonStaking } from "../contracts/interfaces/IHorizonStaking.sol"; contract HorizonStakingTest is Test { - ExponentialRebates rebates; HorizonStakingExtension ext; IHorizonStaking staking; ControllerMock controller; @@ -19,8 +18,7 @@ contract HorizonStakingTest is Test { console.log("Deploying Controller mock"); controller = new ControllerMock(address(0x1)); console.log("Deploying HorizonStaking"); - rebates = new ExponentialRebates(); - ext = new HorizonStakingExtension(address(controller), address(0x1), address(rebates)); + ext = new HorizonStakingExtension(address(controller), address(0x1)); staking = IHorizonStaking(address(new HorizonStaking(address(controller), address(ext), address(0x1)))); } diff --git a/packages/horizon/test/HorizonStaking.ts b/packages/horizon/test/HorizonStaking.ts index 6f6e1ad88..28eb281f7 100644 --- a/packages/horizon/test/HorizonStaking.ts +++ b/packages/horizon/test/HorizonStaking.ts @@ -16,8 +16,8 @@ describe('HorizonStaking', function () { const ExponentialRebates = await ethers.getContractFactory('ExponentialRebates') const exponentialRebates = await ExponentialRebates.deploy() await exponentialRebates.waitForDeployment() - const HorizonStakingExtension = await ethers.getContractFactory('HorizonStakingExtension') - const horizonStakingExtension = await HorizonStakingExtension.deploy(controller.target, ZeroAddress, exponentialRebates.target) + const HorizonStakingExtension = await ethers.getContractFactory('HorizonStakingExtension', { libraries: { ExponentialRebates: exponentialRebates.target } }) + const horizonStakingExtension = await HorizonStakingExtension.deploy(controller.target, ZeroAddress) await horizonStakingExtension.waitForDeployment() const HorizonStaking = await ethers.getContractFactory('HorizonStaking') const horizonStakingContract = await HorizonStaking.deploy(controller.target, horizonStakingExtension.target, ZeroAddress) diff --git a/packages/horizon/test/SimpleTest.t.sol b/packages/horizon/test/SimpleTest.t.sol deleted file mode 100644 index b130e5d34..000000000 --- a/packages/horizon/test/SimpleTest.t.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.10; - -import "forge-std/Test.sol"; -import { SimpleTest } from "../contracts/SimpleTest.sol"; - -contract ContractTest is Test { - SimpleTest simpleTest; - - function setUp() public { - simpleTest = new SimpleTest(); - } - - function test_NumberIs42() public { - assertEq(simpleTest.test(), 42); - } -} diff --git a/packages/horizon/test/SimpleTest.ts b/packages/horizon/test/SimpleTest.ts deleted file mode 100644 index cfcfb1443..000000000 --- a/packages/horizon/test/SimpleTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import hardhat from 'hardhat' - -import { expect } from 'chai' -import { loadFixture } from '@nomicfoundation/hardhat-toolbox/network-helpers' - -const ethers = hardhat.ethers - -describe('SimpleTest', function () { - async function deployFixture() { - const [owner] = await ethers.getSigners() - const SimpleTest = await ethers.getContractFactory('SimpleTest') - const simpleTest = await SimpleTest.deploy() - return { simpleTest, owner } - } - - describe('Deployment', function () { - it('Should return 42', async function () { - const { simpleTest } = await loadFixture(deployFixture) - - expect(await simpleTest.test()).to.equal(42) - }) - }) -}) diff --git a/packages/subgraph-service/contracts/DisputeManager.sol b/packages/subgraph-service/contracts/DisputeManager.sol index dc5f785f2..e74ba0f0b 100644 --- a/packages/subgraph-service/contracts/DisputeManager.sol +++ b/packages/subgraph-service/contracts/DisputeManager.sol @@ -2,19 +2,19 @@ pragma solidity ^0.8.24; pragma abicoder v2; -import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; +import { IHorizonStaking } from "@graphprotocol/horizon/contracts/interfaces/IHorizonStaking.sol"; import { IDisputeManager } from "./interfaces/IDisputeManager.sol"; import { ISubgraphService } from "./interfaces/ISubgraphService.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { DisputeManagerV1Storage } from "./DisputeManagerStorage.sol"; -import { GraphDirectory } from "./data-service/GraphDirectory.sol"; +import { GraphDirectory } from "@graphprotocol/horizon/contracts/data-service/GraphDirectory.sol"; import { AttestationManager } from "./utilities/AttestationManager.sol"; import { Math } from "@openzeppelin/contracts/utils/math/Math.sol"; import { TokenUtils } from "@graphprotocol/contracts/contracts/utils/TokenUtils.sol"; +import { PPMMath } from "@graphprotocol/horizon/contracts/libraries/PPMMath.sol"; import { Allocation } from "./libraries/Allocation.sol"; -import { PPMMath } from "./data-service/libraries/PPMMath.sol"; import { Attestation } from "./libraries/Attestation.sol"; /* @@ -670,7 +670,11 @@ contract DisputeManager is Ownable, GraphDirectory, AttestationManager, DisputeM function _slashIndexer(address _indexer, uint256 _slashAmount) private returns (uint256 rewardsAmount) { // Get slashable amount for indexer IHorizonStaking.Provision memory provision = GRAPH_STAKING.getProvision(_indexer, address(subgraphService)); - uint256 totalProvisionTokens = provision.tokens + provision.delegatedTokens; // slashable tokens + IHorizonStaking.DelegationPool memory pool = GRAPH_STAKING.getDelegationPool( + _indexer, + address(subgraphService) + ); + uint256 totalProvisionTokens = provision.tokens + pool.tokens; // slashable tokens // Get slash amount uint256 maxSlashAmount = uint256(maxSlashingPercentage).mulPPM(totalProvisionTokens); diff --git a/packages/subgraph-service/contracts/SubgraphService.sol b/packages/subgraph-service/contracts/SubgraphService.sol index 9489373ab..896314bf8 100644 --- a/packages/subgraph-service/contracts/SubgraphService.sol +++ b/packages/subgraph-service/contracts/SubgraphService.sol @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IGraphPayments } from "./interfaces/IGraphPayments.sol"; +import { IGraphPayments } from "@graphprotocol/horizon/contracts/interfaces/IGraphPayments.sol"; +import { ITAPVerifier } from "@graphprotocol/horizon/contracts/interfaces/ITAPVerifier.sol"; import { ISubgraphService } from "./interfaces/ISubgraphService.sol"; -import { ITAPVerifier } from "./interfaces/ITAPVerifier.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { DataService } from "./data-service/DataService.sol"; -import { DataServicePausable } from "./data-service/extensions/DataServicePausable.sol"; -import { DataServiceRescuable } from "./data-service/extensions/DataServiceRescuable.sol"; -import { DataServiceFees } from "./data-service/extensions/DataServiceFees.sol"; +import { DataServicePausable } from "@graphprotocol/horizon/contracts/data-service/extensions/DataServicePausable.sol"; +import { DataService } from "@graphprotocol/horizon/contracts/data-service/DataService.sol"; +import { DataServiceRescuable } from "@graphprotocol/horizon/contracts/data-service/extensions/DataServiceRescuable.sol"; +import { DataServiceFees } from "@graphprotocol/horizon/contracts/data-service/extensions/DataServiceFees.sol"; import { Directory } from "./utilities/Directory.sol"; import { AllocationManager } from "./utilities/AllocationManager.sol"; import { SubgraphServiceV1Storage } from "./SubgraphServiceStorage.sol"; -import { PPMMath } from "./data-service/libraries/PPMMath.sol"; +import { PPMMath } from "@graphprotocol/horizon/contracts/libraries/PPMMath.sol"; import { Allocation } from "./libraries/Allocation.sol"; import { LegacyAllocation } from "./libraries/LegacyAllocation.sol"; @@ -111,7 +111,7 @@ contract SubgraphService is data, (bytes32, uint256, address, bytes) ); - _allocate(indexer, allocationId, subgraphDeploymentId, tokens, allocationProof); + _allocate(indexer, allocationId, subgraphDeploymentId, tokens, allocationProof, delegationRatio); emit ServiceStarted(indexer); } @@ -138,7 +138,7 @@ contract SubgraphService is address allocationId, uint256 tokens ) external onlyProvisionAuthorized(indexer) onlyRegisteredIndexer(indexer) whenNotPaused { - _resizeAllocation(allocationId, tokens); + _resizeAllocation(allocationId, tokens, delegationRatio); } // TODO: Does this design allow custom payment types?! @@ -184,8 +184,8 @@ contract SubgraphService is return legacyAllocations[allocationId]; } - function encodeAllocationProof(address _indexer, address _allocationId) external view returns (bytes32) { - return _encodeAllocationProof(_indexer, _allocationId); + function encodeAllocationProof(address indexer, address allocationId) external view returns (bytes32) { + return _encodeAllocationProof(indexer, allocationId); } // -- Data service parameter getters -- diff --git a/packages/subgraph-service/contracts/SubgraphServiceStorage.sol b/packages/subgraph-service/contracts/SubgraphServiceStorage.sol index 27ebc13ff..c67702428 100644 --- a/packages/subgraph-service/contracts/SubgraphServiceStorage.sol +++ b/packages/subgraph-service/contracts/SubgraphServiceStorage.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; +import { IGraphPayments } from "@graphprotocol/horizon/contracts/interfaces/IGraphPayments.sol"; import { ISubgraphService } from "./interfaces/ISubgraphService.sol"; -import { IGraphPayments } from "./interfaces/IGraphPayments.sol"; abstract contract SubgraphServiceV1Storage { /// @notice Service providers registered in the data service diff --git a/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol b/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol index ab62a3d84..17dd7019c 100644 --- a/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol +++ b/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IDataServiceFees } from "../data-service/extensions/IDataServiceFees.sol"; +import { IDataServiceFees } from "@graphprotocol/horizon/contracts/data-service/extensions/IDataServiceFees.sol"; import { Allocation } from "../libraries/Allocation.sol"; import { LegacyAllocation } from "../libraries/LegacyAllocation.sol"; @@ -28,5 +28,5 @@ interface ISubgraphService is IDataServiceFees { function getLegacyAllocation(address allocationId) external view returns (LegacyAllocation.State memory); - function encodeAllocationProof(address _indexer, address _allocationId) external view returns (bytes32); + function encodeAllocationProof(address indexer, address allocationId) external view returns (bytes32); } diff --git a/packages/subgraph-service/contracts/utilities/AllocationManager.sol b/packages/subgraph-service/contracts/utilities/AllocationManager.sol index bcd7f1097..3e43fc0fb 100644 --- a/packages/subgraph-service/contracts/utilities/AllocationManager.sol +++ b/packages/subgraph-service/contracts/utilities/AllocationManager.sol @@ -1,17 +1,17 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { IGraphPayments } from "../interfaces/IGraphPayments.sol"; +import { IGraphPayments } from "@graphprotocol/horizon/contracts/interfaces/IGraphPayments.sol"; -import { GraphDirectory } from "../data-service/GraphDirectory.sol"; +import { GraphDirectory } from "@graphprotocol/horizon/contracts/data-service/GraphDirectory.sol"; import { AllocationManagerV1Storage } from "./AllocationManagerStorage.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; import { Allocation } from "../libraries/Allocation.sol"; import { LegacyAllocation } from "../libraries/LegacyAllocation.sol"; -import { PPMMath } from "../data-service/libraries/PPMMath.sol"; -import { ProvisionTracker } from "../data-service/libraries/ProvisionTracker.sol"; +import { PPMMath } from "@graphprotocol/horizon/contracts/libraries/PPMMath.sol"; +import { ProvisionTracker } from "@graphprotocol/horizon/contracts/data-service/libraries/ProvisionTracker.sol"; abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManagerV1Storage { using ProvisionTracker for mapping(address => uint256); @@ -89,7 +89,8 @@ abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManager address _allocationId, bytes32 _subgraphDeploymentId, uint256 _tokens, - bytes memory _allocationProof + bytes memory _allocationProof, + uint32 __delegationRatio ) internal returns (Allocation.State memory) { if (_allocationId == address(0)) revert AllocationManagerInvalidAllocationId(); @@ -108,7 +109,7 @@ abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManager ); // Check that the indexer has enough tokens available - allocationProvisionTracker.lock(GRAPH_STAKING, _indexer, _tokens); + allocationProvisionTracker.lock(GRAPH_STAKING, _indexer, _tokens, delegationRatio); // Update total allocated tokens for the subgraph deployment subgraphAllocatedTokens[allocation.subgraphDeploymentId] = @@ -146,13 +147,14 @@ abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManager // Distribute rewards to delegators // TODO: remove the uint8 cast when PRs are merged - uint256 delegatorCut = GRAPH_STAKING.getDelegationCut( + uint256 delegatorCut = GRAPH_STAKING.getDelegationFeeCut( allocation.indexer, + address(this), uint8(IGraphPayments.PaymentTypes.IndexingFee) ); uint256 tokensDelegationRewards = tokensRewards.mulPPM(delegatorCut); GRAPH_TOKEN.approve(address(GRAPH_STAKING), tokensDelegationRewards); - GRAPH_STAKING.addToDelegationPool(allocation.indexer, tokensDelegationRewards); + GRAPH_STAKING.addToDelegationPool(allocation.indexer, address(this), tokensDelegationRewards); // Distribute rewards to indexer uint256 tokensIndexerRewards = tokensRewards - tokensDelegationRewards; @@ -177,7 +179,11 @@ abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManager return tokensRewards; } - function _resizeAllocation(address _allocationId, uint256 _tokens) internal returns (Allocation.State memory) { + function _resizeAllocation( + address _allocationId, + uint256 _tokens, + uint3 _ _delegationRatio + ) internal returns (Allocation.State memory) { Allocation.State memory allocation = allocations.get(_allocationId); // Exit early if the allocation size is the same @@ -188,7 +194,7 @@ abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManager // Update provision tracker uint256 oldTokens = allocation.tokens; if (_tokens > oldTokens) { - allocationProvisionTracker.lock(GRAPH_STAKING, allocation.indexer, _tokens - oldTokens); + allocationProvisionTracker.lock(GRAPH_STAKING, allocation.indexer, _tokens - oldTokens, delegationRatio); } else { allocationProvisionTracker.release(allocation.indexer, oldTokens - _tokens); } diff --git a/packages/subgraph-service/contracts/utilities/Directory.sol b/packages/subgraph-service/contracts/utilities/Directory.sol index cd87de102..bc452f072 100644 --- a/packages/subgraph-service/contracts/utilities/Directory.sol +++ b/packages/subgraph-service/contracts/utilities/Directory.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; -import { ITAPVerifier } from "../interfaces/ITAPVerifier.sol"; +import { ITAPVerifier } from "@graphprotocol/horizon/contracts/interfaces/ITAPVerifier.sol"; import { IDisputeManager } from "../interfaces/IDisputeManager.sol"; import { ISubgraphService } from "../interfaces/ISubgraphService.sol"; import { ICuration } from "@graphprotocol/contracts/contracts/curation/ICuration.sol"; diff --git a/packages/subgraph-service/package.json b/packages/subgraph-service/package.json index 144263417..8ad66358e 100644 --- a/packages/subgraph-service/package.json +++ b/packages/subgraph-service/package.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@graphprotocol/contracts": "workspace:^7.0.0", + "@graphprotocol/horizon": "workspace:^0.0.1", "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.0", "@nomicfoundation/hardhat-foundry": "^1.1.1", diff --git a/packages/subgraph-service/remappings.txt b/packages/subgraph-service/remappings.txt index 1bd6482cd..d9bed44ec 100644 --- a/packages/subgraph-service/remappings.txt +++ b/packages/subgraph-service/remappings.txt @@ -1,4 +1,5 @@ @graphprotocol/contracts/=node_modules/@graphprotocol/contracts/ +@graphprotocol/horizon/=node_modules/@graphprotocol/horizon/ forge-std/=lib/forge-std/src/ ds-test/=lib/forge-std/lib/ds-test/src/ eth-gas-reporter/=node_modules/eth-gas-reporter/ diff --git a/packages/subgraph-service/test/mocks/MockHorizonStaking.sol b/packages/subgraph-service/test/mocks/MockHorizonStaking.sol index bd67a980c..b8f722bcf 100644 --- a/packages/subgraph-service/test/mocks/MockHorizonStaking.sol +++ b/packages/subgraph-service/test/mocks/MockHorizonStaking.sol @@ -3,10 +3,11 @@ pragma solidity ^0.8.24; import "forge-std/Test.sol"; -import { IHorizonStaking } from "@graphprotocol/contracts/contracts/staking/IHorizonStaking.sol"; +import { IHorizonStaking } from "@graphprotocol/horizon/contracts/interfaces/IHorizonStaking.sol"; +import { IHorizonStakingTypes } from "@graphprotocol/horizon/contracts/interfaces/IHorizonStakingTypes.sol"; import { MockGRTToken } from "./MockGRTToken.sol"; -contract MockHorizonStaking is IHorizonStaking { +contract MockHorizonStaking { mapping (address verifier => mapping (address serviceProvider => IHorizonStaking.Provision provision)) public _provisions; MockGRTToken public grtToken; @@ -22,15 +23,18 @@ contract MockHorizonStaking is IHorizonStaking { // create a provision function provision(uint256 tokens, address verifier, uint32 maxVerifierCut, uint64 thawingPeriod) external { - IHorizonStaking.Provision memory newProvision = IHorizonStaking.Provision({ - serviceProvider: msg.sender, + IHorizonStaking.Provision memory newProvision = IHorizonStakingTypes.Provision({ tokens: tokens, - delegatedTokens: 0, tokensThawing: 0, - createdAt: uint64(block.timestamp), - verifier: verifier, + sharesThawing: 0, maxVerifierCut: maxVerifierCut, - thawingPeriod: thawingPeriod + thawingPeriod: thawingPeriod, + createdAt: uint64(block.timestamp), + firstThawRequestId: bytes32(0), + lastThawRequestId: bytes32(0), + nThawRequests: 0, + maxVerifierCutPending: maxVerifierCut, + thawingPeriodPending: thawingPeriod }); _provisions[verifier][msg.sender] = newProvision; } @@ -86,9 +90,9 @@ contract MockHorizonStaking is IHorizonStaking { return _provisions[verifier][serviceProvider].tokens; } - function getServiceProvider(address serviceProvider) external view returns (ServiceProvider memory) {} + function getServiceProvider(address serviceProvider) external view returns (IHorizonStaking.ServiceProvider memory) {} - function getProvision(address serviceProvider, address verifier) external view returns (Provision memory) { + function getProvision(address serviceProvider, address verifier) external view returns (IHorizonStaking.Provision memory) { return _provisions[verifier][serviceProvider]; } diff --git a/yarn.lock b/yarn.lock index bed525f83..c105ba53f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2909,7 +2909,7 @@ __metadata: languageName: unknown linkType: soft -"@graphprotocol/horizon@workspace:packages/horizon": +"@graphprotocol/horizon@workspace:^0.0.1, @graphprotocol/horizon@workspace:packages/horizon": version: 0.0.0-use.local resolution: "@graphprotocol/horizon@workspace:packages/horizon" dependencies: @@ -2999,6 +2999,7 @@ __metadata: resolution: "@graphprotocol/subgraph-service@workspace:packages/subgraph-service" dependencies: "@graphprotocol/contracts": "workspace:^7.0.0" + "@graphprotocol/horizon": "workspace:^0.0.1" "@nomicfoundation/hardhat-chai-matchers": "npm:^2.0.0" "@nomicfoundation/hardhat-ethers": "npm:^3.0.0" "@nomicfoundation/hardhat-foundry": "npm:^1.1.1"