From a2b599fdb22e1559e5a16355a49efc4b99ca2477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wei=C3=9Fer=20Hase?= Date: Wed, 21 Aug 2024 12:16:51 +0200 Subject: [PATCH] feat: adding sync public method --- solidity/contracts/DataReceiver.sol | 21 ++++ test/e2e/data-receiver.spec.ts | 126 +++++++++++++++++++++++- test/e2e/oracle-sidechain.spec.ts | 32 ------ test/unit/DataReceiver.spec.ts | 108 ++++++++++++++++++-- yarn.lock | 146 ++++++++++++++++++++++++++-- 5 files changed, 382 insertions(+), 51 deletions(-) diff --git a/solidity/contracts/DataReceiver.sol b/solidity/contracts/DataReceiver.sol index 8a5ca82..b9080e5 100644 --- a/solidity/contracts/DataReceiver.sol +++ b/solidity/contracts/DataReceiver.sol @@ -84,6 +84,27 @@ contract DataReceiver is IDataReceiver, Governable { } } + function syncObservations(bytes32 _poolSalt, uint256 _maxObservations) external { + IOracleSidechain _oracle = deployedOracles[_poolSalt]; + if (address(_oracle) == address(0)) revert ZeroAddress(); + uint24 _currentNonce = _oracle.poolNonce(); + IOracleSidechain.ObservationData[] memory _cachedObservationsData = _cachedObservations[_poolSalt][_currentNonce]; + if (_cachedObservationsData.length == 0) revert ObservationsNotWritable(); + uint256 _i; + while (_maxObservations == 0 || _i < _maxObservations) { + _cachedObservationsData = _cachedObservations[_poolSalt][_currentNonce]; + if (_cachedObservationsData.length > 0) { + _oracle.write(_cachedObservationsData, _currentNonce); + emit ObservationsAdded(_poolSalt, _currentNonce, msg.sender); + delete _cachedObservations[_poolSalt][_currentNonce]; + _currentNonce++; + _i++; + } else { + break; + } + } + } + function whitelistAdapter(IBridgeReceiverAdapter _receiverAdapter, bool _isWhitelisted) external onlyGovernor { _whitelistAdapter(_receiverAdapter, _isWhitelisted); } diff --git a/test/e2e/data-receiver.spec.ts b/test/e2e/data-receiver.spec.ts index 0cd86b2..b0e7197 100644 --- a/test/e2e/data-receiver.spec.ts +++ b/test/e2e/data-receiver.spec.ts @@ -26,7 +26,7 @@ describe('@skip-on-coverage DataReceiver.sol', () => { let tx: ContractTransaction; let snapshotId: string; - const nonce = 1; + const nonce = 42; before(async () => { await evm.reset({ @@ -69,12 +69,15 @@ describe('@skip-on-coverage DataReceiver.sol', () => { }); context('when an oracle is registered', () => { + let caller: string; + beforeEach(async () => { - await dataReceiver.addObservations([[0, 0]] as unknown as IOracleSidechain.ObservationDataStruct[], salt, nonce - 1); + caller = connextReceiverAdapter.address; + await dataReceiver.addObservations([[0, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce); }); it('should add the observations', async () => { - tx = await dataReceiver.addObservations(observationsData, salt, nonce); + tx = await dataReceiver.addObservations(observationsData, salt, nonce + 1); ({ oracleSidechain } = await getOracle(oracleFactory.address, tokenA.address, tokenB.address, fee)); const slot0 = await oracleSidechain.slot0(); @@ -84,7 +87,49 @@ describe('@skip-on-coverage DataReceiver.sol', () => { .to.emit(oracleSidechain, 'Swap') .withArgs(...SWAP_EVENT_ARGS); - await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(salt, nonce, connextReceiverAdapter.address); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 1, caller); + }); + + it('should remember observations that arrived disordered', async () => { + const obs1 = [[1, 100]] as IOracleSidechain.ObservationDataStructOutput[]; + const obs2 = [[2, 100]] as IOracleSidechain.ObservationDataStructOutput[]; + const obs3 = [[3, 100]] as IOracleSidechain.ObservationDataStructOutput[]; + const obs4 = [[4, 100]] as IOracleSidechain.ObservationDataStructOutput[]; + + /* + - Creates a setup in which an observation arrives (3) before the previous nonce (2) has been processed. + - In this case, the observation should be cached and processed later (as long as the previous nonce is already processed). + - In this setup, observations arrive in the order (1), (3), (2), (4) and expected to be processed in numerical order. + - This will happen in the following way: + - (1) is processed immediately. + - then (3) is cached (current is 1). + - (2) is processed immediately. + - (4) is cached (current is 2). + - (3) is processed. + - (4) is processed (current is 3). + */ + + const tx1 = await dataReceiver.addObservations(obs1, salt, nonce + 1); // initial + const tx2 = await dataReceiver.addObservations(obs3, salt, nonce + 3); // disordered (before 2) + const tx3 = await dataReceiver.addObservations(obs2, salt, nonce + 2); // ordered (after 1) + const tx4 = await dataReceiver.addObservations(obs4, salt, nonce + 4); // should include 3 + + await expect(tx1) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 1, caller); + await expect(tx2).to.emit(dataReceiver, 'ObservationsCached'); + await expect(tx2).not.to.emit(dataReceiver, 'ObservationsAdded'); + await expect(tx3) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 2, caller); + await expect(tx4) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 3, caller); + await expect(tx4) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 4, caller); }); }); @@ -122,4 +167,77 @@ describe('@skip-on-coverage DataReceiver.sol', () => { }); }); }); + + describe('syncing observations', () => { + let connextReceiverAdapterSigner: JsonRpcSigner; + let dataReceiverSigner: JsonRpcSigner; + let blockTimestamp1 = 1000000; + let tick1 = 100; + let observationData1 = [blockTimestamp1, tick1] as IOracleSidechain.ObservationDataStructOutput; + let blockTimestamp2 = 3000000; + let tick2 = 300; + let observationData2 = [blockTimestamp2, tick2] as IOracleSidechain.ObservationDataStructOutput; + let observationsData = [observationData1, observationData2]; + + beforeEach(async () => { + connextReceiverAdapterSigner = await wallet.impersonate(connextReceiverAdapter.address); + dataReceiverSigner = await wallet.impersonate(dataReceiver.address); + await wallet.setBalance(connextReceiverAdapter.address, toUnit(10)); + await wallet.setBalance(dataReceiver.address, toUnit(10)); + dataReceiver = dataReceiver.connect(connextReceiverAdapterSigner); + oracleFactory = oracleFactory.connect(dataReceiverSigner); + }); + + context('when an oracle is registered', () => { + let caller: string; + + beforeEach(async () => { + caller = connextReceiverAdapter.address; + await dataReceiver.addObservations([[0, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce - 2); + }); + + context('when the cache at pool nonce is empty', () => { + it('should do nothing', async () => { + await expect(dataReceiver.syncObservations(salt, 0)).to.be.revertedWith('ObservationsNotWritable()'); + }); + }); + + context('when the cache is populated', () => { + beforeEach(async () => { + await dataReceiver.addObservations([[0, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce + 2); + await dataReceiver.addObservations([[1, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce + 1); + await dataReceiver.addObservations([[2, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce); + await dataReceiver.addObservations([[3, 0]] as IOracleSidechain.ObservationDataStructOutput[], salt, nonce - 1); + // NOTE: dataReceiver should be at poolNonce == nonce by now (with nonce, nonce+1 & nonce+2 in cache) + }); + + it('should all the observations when called without max', async () => { + tx = await dataReceiver.syncObservations(salt, 0); + + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(salt, nonce, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 1, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 2, caller); + }); + + it('should all observations limited by max argument', async () => { + tx = await dataReceiver.syncObservations(salt, 2); + + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(salt, nonce, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(salt, nonce + 1, caller); + }); + }); + }); + + context('when an oracle is not registered', () => { + it('should revert', async () => { + await expect(dataReceiver.syncObservations(salt, 0)).to.be.revertedWith('ZeroAddress()'); + }); + }); + }); }); diff --git a/test/e2e/oracle-sidechain.spec.ts b/test/e2e/oracle-sidechain.spec.ts index 85b78fc..a781956 100644 --- a/test/e2e/oracle-sidechain.spec.ts +++ b/test/e2e/oracle-sidechain.spec.ts @@ -91,36 +91,4 @@ describe('@skip-on-coverage OracleSidechain.sol', () => { expect(observation[3]); // initialized }); }); - - it('should remember observations that arrived disordered', async () => { - const obs1 = [[1, 100]] as IOracleSidechain.ObservationDataStructOutput[]; - const obs2 = [[2, 100]] as IOracleSidechain.ObservationDataStructOutput[]; - const obs3 = [[3, 100]] as IOracleSidechain.ObservationDataStructOutput[]; - const obs4 = [[4, 100]] as IOracleSidechain.ObservationDataStructOutput[]; - - /* - - Creates a setup in which an observation arrives (3) before the previous nonce (2) has been processed. - - In this case, the observation should be cached and processed later (as long as the previous nonce is already processed). - - In this setup, observations arrive in the order (1), (3), (2), (4) and expected to be processed in numerical order. - - This will happen in the following way: - - (1) is processed immediately. - - then (3) is cached (current is 1). - - (2) is processed immediately. - - (4) is cached (current is 2). - - (3) is processed. - - (4) is processed (current is 3). - */ - - const tx1 = await allowedDataReceiver.internalAddObservations(obs1, salt, 1); // initial - const tx2 = await allowedDataReceiver.internalAddObservations(obs3, salt, 3); // disordered (before 2) - const tx3 = await allowedDataReceiver.internalAddObservations(obs2, salt, 2); // ordered (after 1) - const tx4 = await allowedDataReceiver.internalAddObservations(obs4, salt, 4); // should include 3 - - await expect(tx1).to.emit(allowedDataReceiver, 'ObservationsAdded').withArgs(salt, 1, deployer.address); - await expect(tx2).to.emit(allowedDataReceiver, 'ObservationsCached'); - await expect(tx2).not.to.emit(allowedDataReceiver, 'ObservationsAdded'); - await expect(tx3).to.emit(allowedDataReceiver, 'ObservationsAdded').withArgs(salt, 2, deployer.address); - await expect(tx4).to.emit(allowedDataReceiver, 'ObservationsAdded').withArgs(salt, 3, deployer.address); - await expect(tx4).to.emit(allowedDataReceiver, 'ObservationsAdded').withArgs(salt, 4, deployer.address); - }); }); diff --git a/test/unit/DataReceiver.spec.ts b/test/unit/DataReceiver.spec.ts index e7b47c8..9f91cf0 100644 --- a/test/unit/DataReceiver.spec.ts +++ b/test/unit/DataReceiver.spec.ts @@ -16,6 +16,7 @@ describe('DataReceiver.sol', () => { let governor: SignerWithAddress; let fakeAdapter: SignerWithAddress; let randomAdapter: SignerWithAddress; + let randomWallet: SignerWithAddress; let dataReceiver: MockContract; let dataReceiverFactory: MockContractFactory; let oracleFactory: FakeContract; @@ -27,7 +28,7 @@ describe('DataReceiver.sol', () => { const randomNonce = 420; before(async () => { - [, governor, fakeAdapter, randomAdapter] = await ethers.getSigners(); + [randomWallet, governor, fakeAdapter, randomAdapter] = await ethers.getSigners(); oracleFactory = await smock.fake('IOracleFactory'); oracleSidechain = await smock.fake('IOracleSidechain'); @@ -57,13 +58,10 @@ describe('DataReceiver.sol', () => { }); describe('addObservations(...)', () => { - let blockTimestamp1 = 1000000; - let tick1 = 100; - let observationData1 = [blockTimestamp1, tick1]; - let blockTimestamp2 = 3000000; - let tick2 = 300; - let observationData2 = [blockTimestamp2, tick2]; - let observationsData = [observationData1, observationData2]; + let observationsData = [ + [1000000, 100], + [300, 3000000], + ] as IOracleSidechain.ObservationDataStructOutput[]; beforeEach(async () => { await dataReceiver.connect(governor).whitelistAdapter(fakeAdapter.address, true); @@ -230,6 +228,7 @@ describe('DataReceiver.sol', () => { await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce - 1); await dataReceiver.connect(fakeAdapter).addObservations(observationsData, randomSalt, randomNonce - 2); oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce - 2); + // oracleSidechain is at poolNonce = randomNonce - 2 and cache is populated with -2, -1, +1 , +2 (nonce is empty) oracleSidechain.write.reset(); }); @@ -285,6 +284,99 @@ describe('DataReceiver.sol', () => { }); }); + describe('syncObservations(...)', () => { + const observationsDataA = [[1, 10]] as IOracleSidechain.ObservationDataStructOutput[]; + const observationsDataB = [[2, 20]] as IOracleSidechain.ObservationDataStructOutput[]; + const observationsDataC = [[3, 30]] as IOracleSidechain.ObservationDataStructOutput[]; + + let caller: string; + + beforeEach(async () => { + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce); + caller = randomWallet.address; + }); + + context('when an oracle is registered', () => { + beforeEach(async () => { + await dataReceiver.setVariable('deployedOracles', { [randomSalt]: oracleSidechain.address }); + }); + + it('should revert when the cache is empty at the oracle nonce', async () => { + await expect(dataReceiver.syncObservations(randomSalt, 0)).to.be.revertedWith('ObservationsNotWritable()'); + }); + + context('when the cache is populated', () => { + beforeEach(async () => { + // Cache observations + // NOTE: smock doesn't support setting internal mapping(bytes32 => mapping(uint => Struct)) (yet) + oracleSidechain.poolNonce.whenCalledWith().returns(0); + await dataReceiver.connect(governor).whitelistAdapter(fakeAdapter.address, true); + await dataReceiver.connect(fakeAdapter).addObservations(observationsDataA, randomSalt, randomNonce); + await dataReceiver.connect(fakeAdapter).addObservations(observationsDataB, randomSalt, randomNonce + 1); + await dataReceiver.connect(fakeAdapter).addObservations(observationsDataC, randomSalt, randomNonce + 2); + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce); + // oracleSidechain is at poolNonce = randomNonce and cache is populated with nonce, +1, +2 + + oracleSidechain.write.reset(); + }); + + it('should revert when the cache at pool nonce is empty', async () => { + oracleSidechain.poolNonce.whenCalledWith().returns(randomNonce + 42); + await expect(dataReceiver.syncObservations(randomSalt, 0)).to.be.revertedWith('ObservationsNotWritable()'); + }); + + it('should all observations limited by max argument', async () => { + tx = await dataReceiver.syncObservations(randomSalt, 2); + + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataA, randomNonce); + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataB, randomNonce + 1); + expect(oracleSidechain.write).not.to.have.been.calledWith(observationsDataC, randomNonce + 2); + + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(randomSalt, randomNonce, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce + 1, caller); + }); + + it('should all the observations when called without max', async () => { + tx = await dataReceiver.syncObservations(randomSalt, 0); + + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataA, randomNonce); + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataB, randomNonce + 1); + expect(oracleSidechain.write).to.have.been.calledWith(observationsDataC, randomNonce + 2); + + await expect(tx).to.emit(dataReceiver, 'ObservationsAdded').withArgs(randomSalt, randomNonce, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce + 1, caller); + await expect(tx) + .to.emit(dataReceiver, 'ObservationsAdded') + .withArgs(randomSalt, randomNonce + 2, caller); + }); + + it.skip('should delete added cache observations', async () => { + // should sync nonce and nonce + 1 (nonce + 2 should remain in cache) + await dataReceiver.syncObservations(randomSalt, 2); + + // NOTE: smock having issues with internal mapping structs + const postCacheA = await dataReceiver.getVariable('_cachedObservations', [randomSalt, randomNonce.toString()]); + const postCacheB = await dataReceiver.getVariable('_cachedObservations', [randomSalt, (randomNonce + 1).toString()]); + const postCacheC = await dataReceiver.getVariable('_cachedObservations', [randomSalt, (randomNonce + 2).toString()]); + + expect(postCacheA).to.be.undefined; + expect(postCacheB).to.be.undefined; + expect(postCacheC).to.deep.eq(observationsDataC); + }); + }); + }); + + context('when an oracle is not registered', () => { + it('should revert', async () => { + await expect(dataReceiver.syncObservations(randomSalt, 0)).to.be.revertedWith('ZeroAddress()'); + }); + }); + }); + describe('whitelistAdapter(...)', () => { onlyGovernor( () => dataReceiver, diff --git a/yarn.lock b/yarn.lock index 271d2b6..551cd15 100644 --- a/yarn.lock +++ b/yarn.lock @@ -278,10 +278,10 @@ dependencies: "@openzeppelin/contracts" "4.3.0" -"@defi-wonderland/smock@2.3.3": - version "2.3.3" - resolved "https://registry.yarnpkg.com/@defi-wonderland/smock/-/smock-2.3.3.tgz#de0a7a399e8e33d776f89f5813ac1ba88ef30c31" - integrity sha512-tDAdr02pEhEFRs1cRvmXr/Fnj3tvHkjVI9r+oPHDKQb3tyDyJ4zYZHchWY2VZvA+Ep5yrbXImlSOA6BL53H5Zg== +"@defi-wonderland/smock@2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@defi-wonderland/smock/-/smock-2.3.5.tgz#2f4daa10b4f4c69627200128778f61c51f4b32cc" + integrity sha512-klANj1hUpc3cd2ShXdVH/bEGwxJd+LxOngkF5gLcIbg6b37RCgMPMmR/94/hgL62F8bfWtuNKsQD7K+c6M5fWQ== dependencies: "@nomicfoundation/ethereumjs-evm" "^1.0.0-rc.3" "@nomicfoundation/ethereumjs-util" "^8.0.0-rc.3" @@ -1595,6 +1595,18 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@nomicfoundation/ethereumjs-block@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.2.2.tgz#f317078c810a54381c682d0c12e1e81acfc11599" + integrity sha512-atjpt4gc6ZGZUPHBAQaUJsm1l/VCo7FmyQ780tMGO8QStjLdhz09dXynmhwVTy5YbRr0FOh/uX3QaEM0yIB2Zg== + dependencies: + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-trie" "5.0.5" + "@nomicfoundation/ethereumjs-tx" "4.1.2" + "@nomicfoundation/ethereumjs-util" "8.0.6" + ethereum-cryptography "0.1.3" + "@nomicfoundation/ethereumjs-block@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz#fdd5c045e7baa5169abeed0e1202bf94e4481c49" @@ -1607,6 +1619,24 @@ "@nomicfoundation/ethereumjs-util" "^8.0.0" ethereum-cryptography "0.1.3" +"@nomicfoundation/ethereumjs-blockchain@6.2.2": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.2.2.tgz#9f79dd2b3dc73f5d5a220f7d8a734330c4c26320" + integrity sha512-6AIB2MoTEPZJLl6IRKcbd8mUmaBAQ/NMe3O7OsAOIiDjMNPPH5KaUQiLfbVlegT4wKIg/GOsFH7XlH2KDVoJNg== + dependencies: + "@nomicfoundation/ethereumjs-block" "4.2.2" + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-ethash" "2.0.5" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-trie" "5.0.5" + "@nomicfoundation/ethereumjs-util" "8.0.6" + abstract-level "^1.0.3" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + level "^8.0.0" + lru-cache "^5.1.1" + memory-level "^1.0.0" + "@nomicfoundation/ethereumjs-blockchain@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz#1a8c243a46d4d3691631f139bfb3a4a157187b0c" @@ -1625,6 +1655,14 @@ lru-cache "^5.1.1" memory-level "^1.0.0" +"@nomicfoundation/ethereumjs-common@3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.1.2.tgz#041086da66ed40f2bf2a2116a1f2f0fcf33fb80d" + integrity sha512-JAEBpIua62dyObHM9KI2b4wHZcRQYYge9gxiygTWa3lNCr2zo+K0TbypDpgiNij5MCGNWP1eboNfNfx1a3vkvA== + dependencies: + "@nomicfoundation/ethereumjs-util" "8.0.6" + crc-32 "^1.2.0" + "@nomicfoundation/ethereumjs-common@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz#f6bcc7753994555e49ab3aa517fc8bcf89c280b9" @@ -1633,6 +1671,18 @@ "@nomicfoundation/ethereumjs-util" "^8.0.0" crc-32 "^1.2.0" +"@nomicfoundation/ethereumjs-ethash@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.5.tgz#0c605812f6f4589a9f6d597db537bbf3b86469db" + integrity sha512-xlLdcICGgAYyYmnI3r1t0R5fKGBJNDQSOQxXNjVO99JmxJIdXR5MgPo5CSJO1RpyzKOgzi3uIFn8agv564dZEQ== + dependencies: + "@nomicfoundation/ethereumjs-block" "4.2.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-util" "8.0.6" + abstract-level "^1.0.3" + bigint-crypto-utils "^3.0.23" + ethereum-cryptography "0.1.3" + "@nomicfoundation/ethereumjs-ethash@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz#11539c32fe0990e1122ff987d1b84cfa34774e81" @@ -1645,7 +1695,21 @@ bigint-crypto-utils "^3.0.23" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-evm@^1.0.0", "@nomicfoundation/ethereumjs-evm@^1.0.0-rc.3": +"@nomicfoundation/ethereumjs-evm@1.3.2", "@nomicfoundation/ethereumjs-evm@^1.0.0-rc.3": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.3.2.tgz#f9d6bafd5c23d07ab75b8649d589af1a43b60bfc" + integrity sha512-I00d4MwXuobyoqdPe/12dxUQxTYzX8OckSaWsMcWAfQhgVDvBx6ffPyP/w1aL0NW7MjyerySPcSVfDJAMHjilw== + dependencies: + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-util" "8.0.6" + "@types/async-eventemitter" "^0.2.1" + async-eventemitter "^0.2.4" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/ethereumjs-evm@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz#99cd173c03b59107c156a69c5e215409098a370b" integrity sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q== @@ -1659,11 +1723,29 @@ mcl-wasm "^0.7.1" rustbn.js "~0.2.0" +"@nomicfoundation/ethereumjs-rlp@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.3.tgz#8d9147fbd0d49e8f4c5ce729d226694a8fe03eb8" + integrity sha512-DZMzB/lqPK78T6MluyXqtlRmOMcsZbTTbbEyAjo0ncaff2mqu/k8a79PBcyvpgAhWD/R59Fjq/x3ro5Lof0AtA== + "@nomicfoundation/ethereumjs-rlp@^4.0.0", "@nomicfoundation/ethereumjs-rlp@^4.0.0-beta.2": version "4.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz#d9a9c5f0f10310c8849b6525101de455a53e771d" integrity sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw== +"@nomicfoundation/ethereumjs-statemanager@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.5.tgz#951cc9ff2c421d40233d2e9d0fe033db2391ee44" + integrity sha512-CAhzpzTR5toh/qOJIZUUOnWekUXuRqkkzaGAQrVcF457VhtCmr+ddZjjK50KNZ524c1XP8cISguEVNqJ6ij1sA== + dependencies: + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-trie" "5.0.5" + "@nomicfoundation/ethereumjs-util" "8.0.6" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + functional-red-black-tree "^1.0.1" + "@nomicfoundation/ethereumjs-statemanager@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz#14a9d4e1c828230368f7ab520c144c34d8721e4b" @@ -1677,6 +1759,16 @@ ethereum-cryptography "0.1.3" functional-red-black-tree "^1.0.1" +"@nomicfoundation/ethereumjs-trie@5.0.5": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.5.tgz#bf31c9306dcbba2007fad668e96109ddb147040c" + integrity sha512-+8sNZrXkzvA1NH5F4kz5RSYl1I6iaRz7mAZRsyxOm0IVY4UaP43Ofvfp/TwOalFunurQrYB5pRO40+8FBcxFMA== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-util" "8.0.6" + ethereum-cryptography "0.1.3" + readable-stream "^3.6.0" + "@nomicfoundation/ethereumjs-trie@^5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz#dcfbe3be53a94bc061c9767a396c16702bc2f5b7" @@ -1687,6 +1779,16 @@ ethereum-cryptography "0.1.3" readable-stream "^3.6.0" +"@nomicfoundation/ethereumjs-tx@4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.1.2.tgz#8659fad7f9094b7eb82aa6cc3c8097cb1c42ff31" + integrity sha512-emJBJZpmTdUa09cqxQqHaysbBI9Od353ZazeH7WgPb35miMgNY6mb7/3vBA98N5lUW/rgkiItjX0KZfIzihSoQ== + dependencies: + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-util" "8.0.6" + ethereum-cryptography "0.1.3" + "@nomicfoundation/ethereumjs-tx@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz#59dc7452b0862b30342966f7052ab9a1f7802f52" @@ -1697,7 +1799,15 @@ "@nomicfoundation/ethereumjs-util" "^8.0.0" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-util@^8.0.0", "@nomicfoundation/ethereumjs-util@^8.0.0-rc.3": +"@nomicfoundation/ethereumjs-util@8.0.6", "@nomicfoundation/ethereumjs-util@^8.0.0-rc.3": + version "8.0.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.6.tgz#dbce5d258b017b37aa58b3a7c330ad59d10ccf0b" + integrity sha512-jOQfF44laa7xRfbfLXojdlcpkvxeHrE2Xu7tSeITsWFgoII163MzjOwFEzSNozHYieFysyoEMhCdP+NY5ikstw== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-util@^8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz#deb2b15d2c308a731e82977aefc4e61ca0ece6c5" integrity sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A== @@ -1705,7 +1815,7 @@ "@nomicfoundation/ethereumjs-rlp" "^4.0.0-beta.2" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-vm@^6.0.0", "@nomicfoundation/ethereumjs-vm@^6.0.0-rc.3": +"@nomicfoundation/ethereumjs-vm@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz#2bb50d332bf41790b01a3767ffec3987585d1de6" integrity sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w== @@ -1727,6 +1837,28 @@ mcl-wasm "^0.7.1" rustbn.js "~0.2.0" +"@nomicfoundation/ethereumjs-vm@^6.0.0-rc.3": + version "6.4.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.4.2.tgz#af1cf62e6c0054bc2b7febc8556d032433d1b18c" + integrity sha512-PRTyxZMP6kx+OdAzBhuH1LD2Yw+hrSpaytftvaK//thDy2OI07S0nrTdbrdk7b8ZVPAc9H9oTwFBl3/wJ3w15g== + dependencies: + "@nomicfoundation/ethereumjs-block" "4.2.2" + "@nomicfoundation/ethereumjs-blockchain" "6.2.2" + "@nomicfoundation/ethereumjs-common" "3.1.2" + "@nomicfoundation/ethereumjs-evm" "1.3.2" + "@nomicfoundation/ethereumjs-rlp" "4.0.3" + "@nomicfoundation/ethereumjs-statemanager" "1.0.5" + "@nomicfoundation/ethereumjs-trie" "5.0.5" + "@nomicfoundation/ethereumjs-tx" "4.1.2" + "@nomicfoundation/ethereumjs-util" "8.0.6" + "@types/async-eventemitter" "^0.2.1" + async-eventemitter "^0.2.4" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + functional-red-black-tree "^1.0.1" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + "@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz#83a7367342bd053a76d04bbcf4f373fef07cf760"