From 011278a8a79c2d2d91dfb0789e2274de79b6b6dd Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Wed, 2 Feb 2022 08:05:07 -0800 Subject: [PATCH 01/17] improve: Destructure RelayData params in FilledRelay event --- contracts/SpokePool.sol | 68 ++++++++++++++++++++++++++------------- test/SpokePool.Fixture.ts | 50 +++++++++++++++++----------- test/SpokePool.Relay.ts | 66 ++++++++++++++++++++++++++++--------- 3 files changed, 128 insertions(+), 56 deletions(-) diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index fdedfee8e..d823b52ff 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -44,7 +44,7 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { mapping(address => mapping(uint256 => bool)) public enabledDepositRoutes; struct RelayData { - address sender; + address depositor; address recipient; address destinationToken; uint64 realizedLpFeePct; @@ -72,15 +72,22 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { uint64 quoteTimestamp, address indexed originToken, address recipient, - address indexed sender + address indexed depositor ); event FilledRelay( bytes32 indexed relayHash, + uint256 totalRelayAmount, uint256 newFilledAmount, - uint256 indexed repaymentChain, uint256 amountSentToRecipient, + uint256 indexed repaymentChain, + uint256 originChainId, + uint64 depositId, + uint64 relayerFeePct, + uint64 realizedLpFeePct, + address destinationToken, address indexed relayer, - RelayData relayData + address depositor, + address recipient ); constructor( @@ -175,7 +182,7 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { } function fillRelay( - address sender, + address depositor, address recipient, address destinationToken, uint64 realizedLpFeePct, @@ -196,7 +203,7 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // such as the origin chain ID and the deposit ID, and the data in a relay attempt such as who the recipient // is, which chain and currency the recipient wants to receive funds on, and the relay fees. RelayData memory relayData = RelayData({ - sender: sender, + depositor: depositor, recipient: recipient, destinationToken: destinationToken, realizedLpFeePct: realizedLpFeePct, @@ -212,24 +219,27 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // so this will start at 0 and increment with each fill. require(maxTokensToSend > 0 && relayFills[relayHash] < totalRelayAmount, "Cannot send 0, or relay filled"); - // Compute the equivalent amount to be sent by the relayer before fees have been taken out. This is the amount - // that we'll add to the `relayFills` counter, and we do this math here in the contract for the user's - // convenience so that they don't have to do this math before calling this function. The user can simply - // pass in `maxTokensToSend` and assume that the contract will pull exactly that amount of tokens (or revert). - uint256 fillAmountPreFees = _computeAmountPreFees(maxTokensToSend, (realizedLpFeePct + relayerFeePct)); - // If user's specified max amount to send is greater than the amount of the relay remaining pre-fees, // we'll pull exactly enough tokens to complete the relay. uint256 amountToSend; - if (totalRelayAmount - relayFills[relayHash] < fillAmountPreFees) { - amountToSend = _computeAmountPostFees( - totalRelayAmount - relayFills[relayHash], - (realizedLpFeePct + relayerFeePct) - ); - relayFills[relayHash] = totalRelayAmount; - } else { - amountToSend = maxTokensToSend; - relayFills[relayHash] += fillAmountPreFees; + + // Adding brackets around `fillAmountPreFees` to address "stack too deep" solidity error. + { + // Compute the equivalent amount to be sent by the relayer before fees have been taken out. This is the amount + // that we'll add to the `relayFills` counter, and we do this math here in the contract for the user's + // convenience so that they don't have to do this math before calling this function. The user can simply + // pass in `maxTokensToSend` and assume that the contract will pull exactly that amount of tokens (or revert). + uint256 fillAmountPreFees = _computeAmountPreFees(maxTokensToSend, (realizedLpFeePct + relayerFeePct)); + if (totalRelayAmount - relayFills[relayHash] < fillAmountPreFees) { + amountToSend = _computeAmountPostFees( + totalRelayAmount - relayFills[relayHash], + (realizedLpFeePct + relayerFeePct) + ); + relayFills[relayHash] = totalRelayAmount; + } else { + amountToSend = maxTokensToSend; + relayFills[relayHash] += fillAmountPreFees; + } } // If relay token is weth then unwrap and send eth. @@ -239,7 +249,21 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // Else, this is a normal ERC20 token. Send to recipient. } else IERC20(destinationToken).safeTransferFrom(msg.sender, recipient, amountToSend); - emit FilledRelay(relayHash, relayFills[relayHash], repaymentChain, amountToSend, msg.sender, relayData); + emit FilledRelay( + relayHash, + relayData.relayAmount, + relayFills[relayHash], + amountToSend, + repaymentChain, + relayData.originChainId, + relayData.depositId, + relayData.relayerFeePct, + relayData.realizedLpFeePct, + relayData.destinationToken, + msg.sender, + relayData.depositor, + relayData.recipient + ); } function initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) public {} diff --git a/test/SpokePool.Fixture.ts b/test/SpokePool.Fixture.ts index 6b78dd694..3277db8c4 100644 --- a/test/SpokePool.Fixture.ts +++ b/test/SpokePool.Fixture.ts @@ -69,34 +69,46 @@ export async function deposit( currentSpokePoolTime ); } +export interface RelayData { + depositor: string; + recipient: string; + destinationToken: string; + realizedLpFeePct: string; + relayerFeePct: string; + depositId: string; + originChainId: string; + relayAmount: string; +} export function getRelayHash( - sender: string, - recipient: string, - depositId: number, - originChainId: number, - destinationToken: string, - relayAmount?: string, + _depositor: string, + _recipient: string, + _depositId: number, + _originChainId: number, + _destinationToken: string, + _relayAmount?: string, _realizedLpFeePct?: string, - relayerFeePct?: string -): { relayHash: string; relayData: string[] } { - const relayData = [ - sender, - recipient, - destinationToken, - _realizedLpFeePct || realizedLpFeePct.toString(), - relayerFeePct || depositRelayerFeePct.toString(), - depositId.toString(), - originChainId.toString(), - relayAmount || amountToDeposit.toString(), - ]; + _relayerFeePct?: string +): { relayHash: string; relayData: RelayData; relayDataValues: string[] } { + const relayData = { + depositor: _depositor, + recipient: _recipient, + destinationToken: _destinationToken, + realizedLpFeePct: _realizedLpFeePct || realizedLpFeePct.toString(), + relayerFeePct: _relayerFeePct || depositRelayerFeePct.toString(), + depositId: _depositId.toString(), + originChainId: _originChainId.toString(), + relayAmount: _relayAmount || amountToDeposit.toString(), + }; + const relayDataValues = Object.values(relayData); const relayHash = keccak256( defaultAbiCoder.encode( ["address", "address", "address", "uint64", "uint64", "uint64", "uint256", "uint256"], - relayData + relayDataValues ) ); return { relayHash, relayData, + relayDataValues, }; } diff --git a/test/SpokePool.Relay.ts b/test/SpokePool.Relay.ts index e9c967fe1..d9b6ee969 100644 --- a/test/SpokePool.Relay.ts +++ b/test/SpokePool.Relay.ts @@ -44,7 +44,7 @@ describe("SpokePool Relayer Logic", async function () { ]); }); it("Relaying ERC20 tokens correctly pulls tokens and changes contract state", async function () { - const { relayHash, relayData } = getRelayHash( + const { relayHash, relayData, relayDataValues } = getRelayHash( depositor.address, recipient.address, firstDepositId, @@ -52,9 +52,23 @@ describe("SpokePool Relayer Logic", async function () { destErc20.address ); - await expect(spokePool.connect(relayer).fillRelay(...relayData, amountToRelay, repaymentChainId)) + await expect(spokePool.connect(relayer).fillRelay(...relayDataValues, amountToRelay, repaymentChainId)) .to.emit(spokePool, "FilledRelay") - .withArgs(relayHash, amountToRelayPreFees, repaymentChainId, amountToRelay, relayer.address, relayData); + .withArgs( + relayHash, + relayData.relayAmount, + amountToRelayPreFees, + amountToRelay, + repaymentChainId, + relayData.originChainId, + relayData.depositId, + relayData.relayerFeePct, + relayData.realizedLpFeePct, + relayData.destinationToken, + relayer.address, + relayData.depositor, + relayData.recipient + ); // The collateral should have transferred from relayer to recipient. expect(await destErc20.balanceOf(relayer.address)).to.equal(amountToSeedWallets.sub(amountToRelay)); @@ -69,15 +83,22 @@ describe("SpokePool Relayer Logic", async function () { const fullRelayAmountPostFees = fullRelayAmount.mul(totalPostFeesPct).div(toBN(oneHundredPct)); const amountRemainingInRelay = fullRelayAmount.sub(amountToRelayPreFees); const amountRemainingInRelayPostFees = amountRemainingInRelay.mul(totalPostFeesPct).div(toBN(oneHundredPct)); - await expect(spokePool.connect(relayer).fillRelay(...relayData, fullRelayAmount, repaymentChainId)) + await expect(spokePool.connect(relayer).fillRelay(...relayDataValues, fullRelayAmount, repaymentChainId)) .to.emit(spokePool, "FilledRelay") .withArgs( relayHash, + relayData.relayAmount, fullRelayAmount, - repaymentChainId, amountRemainingInRelayPostFees, + repaymentChainId, + relayData.originChainId, + relayData.depositId, + relayData.relayerFeePct, + relayData.realizedLpFeePct, + relayData.destinationToken, relayer.address, - relayData + relayData.depositor, + relayData.recipient ); expect(await destErc20.balanceOf(relayer.address)).to.equal(amountToSeedWallets.sub(fullRelayAmountPostFees)); expect(await destErc20.balanceOf(recipient.address)).to.equal(fullRelayAmountPostFees); @@ -86,7 +107,7 @@ describe("SpokePool Relayer Logic", async function () { expect(await spokePool.relayFills(relayHash)).to.equal(fullRelayAmount); }); it("Relaying WETH correctly unwraps into ETH", async function () { - const { relayHash, relayData } = getRelayHash( + const { relayHash, relayData, relayDataValues } = getRelayHash( depositor.address, recipient.address, firstDepositId, @@ -95,9 +116,23 @@ describe("SpokePool Relayer Logic", async function () { ); const startingRecipientBalance = await recipient.getBalance(); - await expect(spokePool.connect(relayer).fillRelay(...relayData, amountToRelay, repaymentChainId)) + await expect(spokePool.connect(relayer).fillRelay(...relayDataValues, amountToRelay, repaymentChainId)) .to.emit(spokePool, "FilledRelay") - .withArgs(relayHash, amountToRelayPreFees, repaymentChainId, amountToRelay, relayer.address, relayData); + .withArgs( + relayHash, + relayData.relayAmount, + amountToRelayPreFees, + amountToRelay, + repaymentChainId, + relayData.originChainId, + relayData.depositId, + relayData.relayerFeePct, + relayData.realizedLpFeePct, + relayData.destinationToken, + relayer.address, + relayData.depositor, + relayData.recipient + ); // The collateral should have unwrapped to ETH and then transferred to recipient. expect(await weth.balanceOf(relayer.address)).to.equal(amountToSeedWallets.sub(amountToRelay)); @@ -121,7 +156,7 @@ describe("SpokePool Relayer Logic", async function () { amountToDeposit.toString(), toWei("0.51").toString(), toWei("0.5").toString() - ).relayData, + ).relayDataValues, amountToRelay, repaymentChainId ) @@ -139,7 +174,7 @@ describe("SpokePool Relayer Logic", async function () { amountToDeposit.toString(), toWei("0.5").toString(), toWei("0.51").toString() - ).relayData, + ).relayDataValues, amountToRelay, repaymentChainId ) @@ -157,7 +192,7 @@ describe("SpokePool Relayer Logic", async function () { amountToDeposit.toString(), toWei("0.5").toString(), toWei("0.5").toString() - ).relayData, + ).relayDataValues, amountToRelay, repaymentChainId ) @@ -169,7 +204,7 @@ describe("SpokePool Relayer Logic", async function () { .connect(relayer) .fillRelay( ...getRelayHash(depositor.address, recipient.address, firstDepositId, originChainId, destErc20.address) - .relayData, + .relayDataValues, "0", repaymentChainId ) @@ -177,7 +212,8 @@ describe("SpokePool Relayer Logic", async function () { // Relay already filled await spokePool.connect(relayer).fillRelay( - ...getRelayHash(depositor.address, recipient.address, firstDepositId, originChainId, destErc20.address).relayData, + ...getRelayHash(depositor.address, recipient.address, firstDepositId, originChainId, destErc20.address) + .relayDataValues, amountToDeposit, // Send the full relay amount repaymentChainId ); @@ -186,7 +222,7 @@ describe("SpokePool Relayer Logic", async function () { .connect(relayer) .fillRelay( ...getRelayHash(depositor.address, recipient.address, firstDepositId, originChainId, destErc20.address) - .relayData, + .relayDataValues, "1", repaymentChainId ) From edecc6f0fb3be375226d9266dae8d3a95b2ad5ea Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Thu, 3 Feb 2022 09:35:31 -0800 Subject: [PATCH 02/17] use fillAmount not amountToSend in FillRelay event --- contracts/SpokePool.sol | 45 +++++++++++++++++------------------------ test/SpokePool.Relay.ts | 10 ++++----- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index d823b52ff..e61aaf83d 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -77,8 +77,8 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { event FilledRelay( bytes32 indexed relayHash, uint256 totalRelayAmount, - uint256 newFilledAmount, - uint256 amountSentToRecipient, + uint256 totalFilledAmount, + uint256 fillAmount, uint256 indexed repaymentChain, uint256 originChainId, uint64 depositId, @@ -219,41 +219,32 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // so this will start at 0 and increment with each fill. require(maxTokensToSend > 0 && relayFills[relayHash] < totalRelayAmount, "Cannot send 0, or relay filled"); - // If user's specified max amount to send is greater than the amount of the relay remaining pre-fees, - // we'll pull exactly enough tokens to complete the relay. - uint256 amountToSend; + // Stores the equivalent amount to be sent by the relayer before fees have been taken out. + uint256 fillAmountPreFees = _computeAmountPreFees(maxTokensToSend, (realizedLpFeePct + relayerFeePct)); - // Adding brackets around `fillAmountPreFees` to address "stack too deep" solidity error. + // Adding brackets "stack too deep" solidity error. { - // Compute the equivalent amount to be sent by the relayer before fees have been taken out. This is the amount - // that we'll add to the `relayFills` counter, and we do this math here in the contract for the user's - // convenience so that they don't have to do this math before calling this function. The user can simply - // pass in `maxTokensToSend` and assume that the contract will pull exactly that amount of tokens (or revert). - uint256 fillAmountPreFees = _computeAmountPreFees(maxTokensToSend, (realizedLpFeePct + relayerFeePct)); + // If user's specified max amount to send is greater than the amount of the relay remaining pre-fees, + // we'll pull exactly enough tokens to complete the relay. + uint256 amountToSend = maxTokensToSend; if (totalRelayAmount - relayFills[relayHash] < fillAmountPreFees) { - amountToSend = _computeAmountPostFees( - totalRelayAmount - relayFills[relayHash], - (realizedLpFeePct + relayerFeePct) - ); - relayFills[relayHash] = totalRelayAmount; - } else { - amountToSend = maxTokensToSend; - relayFills[relayHash] += fillAmountPreFees; + fillAmountPreFees = totalRelayAmount - relayFills[relayHash]; + amountToSend = _computeAmountPostFees(fillAmountPreFees, (realizedLpFeePct + relayerFeePct)); } + relayFills[relayHash] += fillAmountPreFees; + // If relay token is weth then unwrap and send eth. + if (destinationToken == address(weth)) { + IERC20(destinationToken).safeTransferFrom(msg.sender, address(this), amountToSend); + _unwrapWETHTo(payable(recipient), amountToSend); + // Else, this is a normal ERC20 token. Send to recipient. + } else IERC20(destinationToken).safeTransferFrom(msg.sender, recipient, amountToSend); } - // If relay token is weth then unwrap and send eth. - if (destinationToken == address(weth)) { - IERC20(destinationToken).safeTransferFrom(msg.sender, address(this), amountToSend); - _unwrapWETHTo(payable(recipient), amountToSend); - // Else, this is a normal ERC20 token. Send to recipient. - } else IERC20(destinationToken).safeTransferFrom(msg.sender, recipient, amountToSend); - emit FilledRelay( relayHash, relayData.relayAmount, relayFills[relayHash], - amountToSend, + fillAmountPreFees, repaymentChain, relayData.originChainId, relayData.depositId, diff --git a/test/SpokePool.Relay.ts b/test/SpokePool.Relay.ts index d9b6ee969..0375af49f 100644 --- a/test/SpokePool.Relay.ts +++ b/test/SpokePool.Relay.ts @@ -18,7 +18,7 @@ import { let spokePool: Contract, weth: Contract, erc20: Contract, destErc20: Contract; let depositor: SignerWithAddress, recipient: SignerWithAddress, relayer: SignerWithAddress; -describe("SpokePool Relayer Logic", async function () { +describe.only("SpokePool Relayer Logic", async function () { beforeEach(async function () { [depositor, recipient, relayer] = await ethers.getSigners(); ({ weth, erc20, spokePool, destErc20 } = await deploySpokePoolTestHelperContracts(depositor)); @@ -58,7 +58,7 @@ describe("SpokePool Relayer Logic", async function () { relayHash, relayData.relayAmount, amountToRelayPreFees, - amountToRelay, + amountToRelayPreFees, repaymentChainId, relayData.originChainId, relayData.depositId, @@ -82,14 +82,14 @@ describe("SpokePool Relayer Logic", async function () { const fullRelayAmount = amountToDeposit; const fullRelayAmountPostFees = fullRelayAmount.mul(totalPostFeesPct).div(toBN(oneHundredPct)); const amountRemainingInRelay = fullRelayAmount.sub(amountToRelayPreFees); - const amountRemainingInRelayPostFees = amountRemainingInRelay.mul(totalPostFeesPct).div(toBN(oneHundredPct)); + // const amountRemainingInRelayPostFees = amountRemainingInRelay.mul(totalPostFeesPct).div(toBN(oneHundredPct)); await expect(spokePool.connect(relayer).fillRelay(...relayDataValues, fullRelayAmount, repaymentChainId)) .to.emit(spokePool, "FilledRelay") .withArgs( relayHash, relayData.relayAmount, fullRelayAmount, - amountRemainingInRelayPostFees, + amountRemainingInRelay, repaymentChainId, relayData.originChainId, relayData.depositId, @@ -122,7 +122,7 @@ describe("SpokePool Relayer Logic", async function () { relayHash, relayData.relayAmount, amountToRelayPreFees, - amountToRelay, + amountToRelayPreFees, repaymentChainId, relayData.originChainId, relayData.depositId, From be559ea14987a2ddf8faa9293ccdfcdc70d31bae Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Thu, 3 Feb 2022 09:41:37 -0800 Subject: [PATCH 03/17] Remove exclusive test --- test/SpokePool.Relay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SpokePool.Relay.ts b/test/SpokePool.Relay.ts index 0375af49f..322ceaef6 100644 --- a/test/SpokePool.Relay.ts +++ b/test/SpokePool.Relay.ts @@ -18,7 +18,7 @@ import { let spokePool: Contract, weth: Contract, erc20: Contract, destErc20: Contract; let depositor: SignerWithAddress, recipient: SignerWithAddress, relayer: SignerWithAddress; -describe.only("SpokePool Relayer Logic", async function () { +describe("SpokePool Relayer Logic", async function () { beforeEach(async function () { [depositor, recipient, relayer] = await ethers.getSigners(); ({ weth, erc20, spokePool, destErc20 } = await deploySpokePoolTestHelperContracts(depositor)); From 3897440b3ef9a1fd84b590fc4d3cdac425d3ded5 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Thu, 3 Feb 2022 10:14:57 -0800 Subject: [PATCH 04/17] feat: Implement _initiateRelayerRefund and Optimism-specific adapter --- contracts/Optimism_SpokePool.sol | 65 ++++++++++++++++++++++++++++++++ contracts/SpokePool.sol | 20 +++++++++- contracts/test/MockSpokePool.sol | 4 ++ package.json | 1 + test/SpokePool.RelayerRefund.ts | 7 ++++ 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 contracts/Optimism_SpokePool.sol create mode 100644 test/SpokePool.RelayerRefund.ts diff --git a/contracts/Optimism_SpokePool.sol b/contracts/Optimism_SpokePool.sol new file mode 100644 index 000000000..0633e481a --- /dev/null +++ b/contracts/Optimism_SpokePool.sol @@ -0,0 +1,65 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +import "@eth-optimism/contracts/libraries/bridge/CrossDomainEnabled.sol"; +import "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol"; +import "./SpokePool.sol"; + +/** + * @notice OVM specific SpokePool. + * @dev Uses OVM cross-domain-enabled logic for access control. + */ + +contract Optimism_SpokePool is CrossDomainEnabled, SpokePool { + // Address of the L1 contract that acts as the owner of this SpokePool. + address public crossDomainAdmin; + + event SetXDomainAdmin(address indexed newAdmin); + + constructor( + address _crossDomainAdmin, + address _wethAddress, + uint64 _depositQuoteTimeBuffer, + address timerAddress + ) + CrossDomainEnabled(Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER) + SpokePool(_wethAddress, _depositQuoteTimeBuffer, timerAddress) + { + _setCrossDomainAdmin(_crossDomainAdmin); + } + + /************************************** + * ADMIN FUNCTIONS * + **************************************/ + + // TODO: + function setEnableRoute( + address originToken, + uint256 destinationChainId, + bool enable + ) public onlyFromCrossDomainAccount(crossDomainAdmin) { + _setEnableRoute(originToken, destinationChainId, enable); + } + + // TODO: + function setDepositQuoteTimeBuffer(uint64 buffer) public onlyFromCrossDomainAccount(crossDomainAdmin) { + _setDepositQuoteTimeBuffer(buffer); + } + + function initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) + public + onlyFromCrossDomainAccount(crossDomainAdmin) + { + _initializeRelayerRefund(relayerRepaymentDistributionProof); + } + + /************************************** + * INTERNAL FUNCTIONS * + **************************************/ + + function _setCrossDomainAdmin(address newCrossDomainAdmin) internal { + require(newCrossDomainAdmin != address(0), "Bad bridge router address"); + crossDomainAdmin = newCrossDomainAdmin; + emit SetXDomainAdmin(crossDomainAdmin); + } +} diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index e61aaf83d..e21d2fe5c 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -43,6 +43,16 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // Origin token to destination token routings can be turned on or off. mapping(address => mapping(uint256 => bool)) public enabledDepositRoutes; + // Associates relayer refund distribution proofs to unique IDs. + mapping(uint256 => bytes32) public relayerRefundRoots; + + // Count of additions to `relayerRefundRoots`. + uint256 public relayerRefundRootCount; + + // This is a 2D bitmap tracking which leafs in the relayer refund roots have been claimed, with max size of + // 256 elements, limiting us to 256 relayer refund leafs per distribution proof. + mapping(uint256 => uint256) public relayerRefundRootClaimsBitmap; + struct RelayData { address depositor; address recipient; @@ -89,6 +99,7 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { address depositor, address recipient ); + event InitializedRelayerRefund(uint256 indexed relayerRefundRootCount, bytes32 relayerRepaymentDistributionProof); constructor( address _wethAddress, @@ -257,7 +268,14 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { ); } - function initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) public {} + // This internal method should be called by an external "initializeRelayerRefund" function that validates the + // cross domain sender is the HubPool. This validation step differs for each L2, which is why the implementation + // specifics are left to the implementor of this abstract contract. + function _initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) internal { + relayerRefundRoots[relayerRefundRootCount] = relayerRepaymentDistributionProof; + emit InitializedRelayerRefund(relayerRefundRootCount, relayerRepaymentDistributionProof); + relayerRefundRootCount += 1; + } function distributeRelayerRefund( uint256 relayerRefundId, diff --git a/contracts/test/MockSpokePool.sol b/contracts/test/MockSpokePool.sol index c5f9e5545..5407a20bb 100644 --- a/contracts/test/MockSpokePool.sol +++ b/contracts/test/MockSpokePool.sol @@ -25,4 +25,8 @@ contract MockSpokePool is SpokePool { function setDepositQuoteTimeBuffer(uint64 buffer) public { _setDepositQuoteTimeBuffer(buffer); } + + function initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) public { + _initializeRelayerRefund(relayerRepaymentDistributionProof); + } } diff --git a/package.json b/package.json index d837eab0d..3d4339da2 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "test": "yarn hardhat test" }, "dependencies": { + "@eth-optimism/contracts": "^0.5.5", "@openzeppelin/contracts": "^4.4.2", "@uma/common": "^2.17.0", "@uma/contracts-node": "^0.2.0", diff --git a/test/SpokePool.RelayerRefund.ts b/test/SpokePool.RelayerRefund.ts new file mode 100644 index 000000000..b4d9321eb --- /dev/null +++ b/test/SpokePool.RelayerRefund.ts @@ -0,0 +1,7 @@ +// TODO: +// - initiateRelayerRefund(): +// - Test that distribution root is stored and even is emitted. +// - Count of roots should increment. + +// TODO: +// - Figure out best structure to test L2-specific contracts. From 3543a9f1934a5c49f663f4a1a250ccde23fde7d5 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Thu, 3 Feb 2022 10:35:10 -0800 Subject: [PATCH 05/17] Update SpokePool.sol --- contracts/SpokePool.sol | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index e21d2fe5c..84c07ed3f 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -43,15 +43,14 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // Origin token to destination token routings can be turned on or off. mapping(address => mapping(uint256 => bool)) public enabledDepositRoutes; - // Associates relayer refund distribution proofs to unique IDs. - mapping(uint256 => bytes32) public relayerRefundRoots; - - // Count of additions to `relayerRefundRoots`. - uint256 public relayerRefundRootCount; - - // This is a 2D bitmap tracking which leafs in the relayer refund roots have been claimed, with max size of - // 256 elements, limiting us to 256 relayer refund leafs per distribution proof. - mapping(uint256 => uint256) public relayerRefundRootClaimsBitmap; + struct RelayerRefund { + // Merkle root of relayer refunds. + bytes32 distributionRoot; + // This is a 2D bitmap tracking which leafs in the relayer refund roots have been claimed, with max size of + // 256 elements, limiting us to 256 relayer refund leafs per distribution proof. + mapping(uint256 => uint256) claimsBitmap; + } + RelayerRefund[] public relayerRefunds; struct RelayData { address depositor; @@ -99,7 +98,7 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { address depositor, address recipient ); - event InitializedRelayerRefund(uint256 indexed relayerRefundRootCount, bytes32 relayerRepaymentDistributionProof); + event InitializedRelayerRefund(uint256 indexed relayerRefundId, bytes32 relayerRepaymentDistributionProof); constructor( address _wethAddress, @@ -272,9 +271,10 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // cross domain sender is the HubPool. This validation step differs for each L2, which is why the implementation // specifics are left to the implementor of this abstract contract. function _initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) internal { - relayerRefundRoots[relayerRefundRootCount] = relayerRepaymentDistributionProof; - emit InitializedRelayerRefund(relayerRefundRootCount, relayerRepaymentDistributionProof); - relayerRefundRootCount += 1; + relayerRefunds.push(); + uint256 relayerRefundId = relayerRefunds.length - 1; + relayerRefunds[relayerRefundId].distributionRoot = relayerRepaymentDistributionProof; + emit InitializedRelayerRefund(relayerRefundId, relayerRepaymentDistributionProof); } function distributeRelayerRefund( From e6c247c4e5d20ddfd96b4cb210a6fa7f0c5ab116 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Thu, 3 Feb 2022 10:38:47 -0800 Subject: [PATCH 06/17] update comment + bump eth-optimism version --- contracts/SpokePool.sol | 4 +- package.json | 2 +- yarn.lock | 500 ++++++++++++++++++++-------------------- 3 files changed, 249 insertions(+), 257 deletions(-) diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index 84c07ed3f..e973a6941 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -46,8 +46,8 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { struct RelayerRefund { // Merkle root of relayer refunds. bytes32 distributionRoot; - // This is a 2D bitmap tracking which leafs in the relayer refund roots have been claimed, with max size of - // 256 elements, limiting us to 256 relayer refund leafs per distribution proof. + // This is a 2D bitmap tracking which leafs in the relayer refund root have been claimed, with max size of + // 256x256 leaves per root. mapping(uint256 => uint256) claimsBitmap; } RelayerRefund[] public relayerRefunds; diff --git a/package.json b/package.json index 1264a9f22..ab40f36eb 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "test": "yarn hardhat test" }, "dependencies": { - "@eth-optimism/contracts": "^0.5.5", + "@eth-optimism/contracts": "^0.5.11", "@openzeppelin/contracts": "^4.4.2", "@uma/common": "^2.17.0", "@uma/contracts-node": "^0.2.0", diff --git a/yarn.lock b/yarn.lock index 55d0fcac5..b0e0e96a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,16 +26,16 @@ "@babel/highlight" "^7.16.7" "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" - integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" + integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== -"@babel/generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" - integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== +"@babel/generator@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e" + integrity sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw== dependencies: - "@babel/types" "^7.16.8" + "@babel/types" "^7.17.0" jsesc "^2.5.1" source-map "^0.5.0" @@ -131,15 +131,15 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.16.10", "@babel/parser@^7.16.7": - version "7.16.12" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6" - integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A== +"@babel/parser@^7.16.7", "@babel/parser@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c" + integrity sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw== "@babel/plugin-transform-runtime@^7.5.5": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.10.tgz#53d9fd3496daedce1dd99639097fa5d14f4c7c2c" - integrity sha512-9nwTiqETv2G7xI4RvXHNfpGdr8pAA+Q/YtN3yLK7OoK7n9OibVm/xymJ838a9A6E/IciOLPj82lZk0fW6O4O7w== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz#0a2e08b5e2b2d95c4b1d3b3371a2180617455b70" + integrity sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A== dependencies: "@babel/helper-module-imports" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" @@ -157,9 +157,9 @@ regenerator-runtime "^0.13.4" "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" - integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.0.tgz#b8d142fc0f7664fb3d9b5833fd40dcbab89276c0" + integrity sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ== dependencies: regenerator-runtime "^0.13.4" @@ -173,25 +173,25 @@ "@babel/types" "^7.16.7" "@babel/traverse@^7.13.0": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" - integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30" + integrity sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg== dependencies: "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" + "@babel/generator" "^7.17.0" "@babel/helper-environment-visitor" "^7.16.7" "@babel/helper-function-name" "^7.16.7" "@babel/helper-hoist-variables" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.16.10" - "@babel/types" "^7.16.8" + "@babel/parser" "^7.17.0" + "@babel/types" "^7.17.0" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.16.7", "@babel/types@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" - integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== +"@babel/types@^7.16.7", "@babel/types@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== dependencies: "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" @@ -279,20 +279,20 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@eth-optimism/contracts@^0.5.5": - version "0.5.8" - resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.5.8.tgz#975313a219b5537bad7f4f98f8841c98592882d0" - integrity sha512-INvIMiE72Y6tjxm+BZyN9f3+LiMKJgmNpR0qEimrvpg49hK8gOXQTnI+0C7/qIIGvgaQgDyejG9AfkxZizjLVQ== +"@eth-optimism/contracts@^0.5.11", "@eth-optimism/contracts@^0.5.5": + version "0.5.11" + resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.5.11.tgz#935a776be3f0d27dd26fa9e892c02c6b0fe86e93" + integrity sha512-W1xgY4qgJO9IHG1qOe98kjDMOH0mqpO3oiaSxeIFmzzshNiWGw3XSDbEvHqdsAapFYzfrmwavY3FAg7G5iqGEA== dependencies: - "@eth-optimism/core-utils" "0.7.3" + "@eth-optimism/core-utils" "0.7.5" "@ethersproject/abstract-provider" "^5.4.1" "@ethersproject/abstract-signer" "^5.4.1" "@ethersproject/hardware-wallets" "^5.4.0" -"@eth-optimism/core-utils@0.7.3": - version "0.7.3" - resolved "https://registry.yarnpkg.com/@eth-optimism/core-utils/-/core-utils-0.7.3.tgz#67a7ec3cd65a555c6b5ef50d03ea66aa8df9f6c8" - integrity sha512-e531gfcMN6LWvGgJGfB37cU8HNUXfCkT6OO84KT8qKHMT4mOxyUqnApTYOHBxXGetLd3z/n67KwBCkJLZBr9jw== +"@eth-optimism/core-utils@0.7.5": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@eth-optimism/core-utils/-/core-utils-0.7.5.tgz#31b11171fdd816fd17459437f7ac67d26ebad422" + integrity sha512-rinXC0msmLipPAkxVzwkSGmmoCvd1WuYPYcBh3rKc5ZCroDZ0UpxTfjDwBB0lAWUQ04OH+/70RUFMENOn6WYUA== dependencies: "@ethersproject/abstract-provider" "^5.4.1" "@ethersproject/bytes" "^5.5.0" @@ -363,16 +363,16 @@ postinstall-postinstall "^2.1.0" "@ethereumjs/block@^3.5.0", "@ethereumjs/block@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.6.0.tgz#5cf89ea748607597a3f8b038abc986e4ac0b05db" - integrity sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ== + version "3.6.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.6.1.tgz#50574d3e993ae247dcfe2abbdb91d2a4a22accb9" + integrity sha512-o5d/zpGl4SdVfdTfrsq9ZgYMXddc0ucKMiFW5OphBCX+ep4xzYnSjboFcZXT2V/tcSBr84VrKWWp21CGVb3DGw== dependencies: - "@ethereumjs/common" "^2.6.0" - "@ethereumjs/tx" "^3.4.0" - ethereumjs-util "^7.1.3" - merkle-patricia-tree "^4.2.2" + "@ethereumjs/common" "^2.6.1" + "@ethereumjs/tx" "^3.5.0" + ethereumjs-util "^7.1.4" + merkle-patricia-tree "^4.2.3" -"@ethereumjs/blockchain@^5.5.0": +"@ethereumjs/blockchain@^5.5.0", "@ethereumjs/blockchain@^5.5.1": version "5.5.1" resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz#60f1f50592c06cc47e1704800b88b7d32f609742" integrity sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA== @@ -386,13 +386,13 @@ lru-cache "^5.1.1" semaphore-async-await "^1.5.1" -"@ethereumjs/common@^2.3.0", "@ethereumjs/common@^2.4.0", "@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.0.tgz#feb96fb154da41ee2cc2c5df667621a440f36348" - integrity sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA== +"@ethereumjs/common@^2.3.0", "@ethereumjs/common@^2.4.0", "@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.0", "@ethereumjs/common@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.1.tgz#7cf8947b928506f84551f15e00af1bbb505f4dbd" + integrity sha512-eUe5RsYiOnazszPsgQOdaetCwgVquiiQHBpB59xNABOrBPNh/ZdTJz+uhHGzKvPm6Dr91ViBGYZcdclTgtki0g== dependencies: crc-32 "^1.2.0" - ethereumjs-util "^7.1.3" + ethereumjs-util "^7.1.4" "@ethereumjs/ethash@^1.1.0": version "1.1.0" @@ -405,30 +405,30 @@ ethereumjs-util "^7.1.1" miller-rabin "^4.0.0" -"@ethereumjs/tx@^3.2.1", "@ethereumjs/tx@^3.3.0", "@ethereumjs/tx@^3.3.2", "@ethereumjs/tx@^3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.4.0.tgz#7eb1947eefa55eb9cf05b3ca116fb7a3dbd0bce7" - integrity sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw== +"@ethereumjs/tx@^3.2.1", "@ethereumjs/tx@^3.3.0", "@ethereumjs/tx@^3.3.2", "@ethereumjs/tx@^3.4.0", "@ethereumjs/tx@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.0.tgz#783b0aeb08518b9991b23f5155763bbaf930a037" + integrity sha512-/+ZNbnJhQhXC83Xuvy6I9k4jT5sXiV0tMR9C+AzSSpcCV64+NB8dTE1m3x98RYMqb8+TLYWA+HML4F5lfXTlJw== dependencies: - "@ethereumjs/common" "^2.6.0" - ethereumjs-util "^7.1.3" + "@ethereumjs/common" "^2.6.1" + ethereumjs-util "^7.1.4" "@ethereumjs/vm@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.6.0.tgz#e0ca62af07de820143674c30b776b86c1983a464" - integrity sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ== + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.7.0.tgz#10c5ddca08c23d49346197b48db3bb4a368ae4f5" + integrity sha512-1ruJ6nmWYsh42I1cseIuzgCSU1MH8Bh3FSJnSNAYoS1HVmr87mB6FyIZa/OvO3W0hKYD6+/t5OsyKrq0v43fAQ== dependencies: "@ethereumjs/block" "^3.6.0" - "@ethereumjs/blockchain" "^5.5.0" - "@ethereumjs/common" "^2.6.0" - "@ethereumjs/tx" "^3.4.0" + "@ethereumjs/blockchain" "^5.5.1" + "@ethereumjs/common" "^2.6.1" + "@ethereumjs/tx" "^3.5.0" async-eventemitter "^0.2.4" core-js-pure "^3.0.1" - debug "^2.2.0" - ethereumjs-util "^7.1.3" + debug "^4.3.3" + ethereumjs-util "^7.1.4" functional-red-black-tree "^1.0.1" mcl-wasm "^0.7.1" - merkle-patricia-tree "^4.2.2" + merkle-patricia-tree "^4.2.3" rustbn.js "~0.2.0" "@ethersproject/abi@5.0.0-beta.153": @@ -877,10 +877,10 @@ bech32 "1.1.4" ws "7.2.3" -"@ethersproject/providers@5.5.2", "@ethersproject/providers@^5.4.4", "@ethersproject/providers@^5.4.5": - version "5.5.2" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.5.2.tgz#131ccf52dc17afd0ab69ed444b8c0e3a27297d99" - integrity sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ== +"@ethersproject/providers@5.5.3", "@ethersproject/providers@^5.4.4", "@ethersproject/providers@^5.4.5": + version "5.5.3" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.5.3.tgz#56c2b070542ac44eb5de2ed3cf6784acd60a3130" + integrity sha512-ZHXxXXXWHuwCQKrgdpIkbzMNJMvs+9YWemanwp1fA7XZEv7QlilseysPvQe0D7Q7DlkJX/w/bGA1MdgK2TbGvA== dependencies: "@ethersproject/abstract-provider" "^5.5.0" "@ethersproject/abstract-signer" "^5.5.0" @@ -1190,9 +1190,9 @@ integrity sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA== "@google-cloud/storage@^5.8.5": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-5.18.0.tgz#a8fcce68addd9f72d20f02326952d9c19887ef4d" - integrity sha512-T4Q4QS3RKU3os6UwcdJATb2gpLyGQUdQxdV8/wzuFpHlcC9YPhflOvVuvGvSlrbGSZXlznu6D2pN/rpMM9RX8A== + version "5.18.1" + resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-5.18.1.tgz#1bae7345b3ec2b38e874cdefc94e8b62130577ea" + integrity sha512-EeVIarDb6u9vE5Se3YaXA8tuW8Ae2xmYLHy43doutTwzkXwizGXVS2Qmc2pouq9ln8qMD9A2f3arvhgAPtK9LQ== dependencies: "@google-cloud/common" "^3.8.1" "@google-cloud/paginator" "^3.0.0" @@ -1218,9 +1218,9 @@ xdg-basedir "^4.0.0" "@grpc/grpc-js@~1.5.0": - version "1.5.3" - resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.5.3.tgz#fe78a40eab4e21a6044ff6f23798f712ea352a8f" - integrity sha512-q0xgaZ3ymUM+ZOhe1hdocVSdKHCnJ6llLSXcP+MqMXMyYPUZ3mzQOCxZ3Zkg+QZ7sZ950sn7hvueQrIJZumPZg== + version "1.5.4" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.5.4.tgz#dd0237ad7df80a7a24766fe516d7e4a22cb4855e" + integrity sha512-+nJTOsqpFAXnfFrMZ7Too4XXZ/J9O+8jYvSoaunupoC7I7b9H4iex1BRsbTdOmiowfPGJrWit7jUPmbENSUSpw== dependencies: "@grpc/proto-loader" "^0.6.4" "@types/node" ">=12.12.47" @@ -1723,10 +1723,10 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@truffle/abi-utils@^0.2.6": - version "0.2.6" - resolved "https://registry.yarnpkg.com/@truffle/abi-utils/-/abi-utils-0.2.6.tgz#99a618c5d16aad506f6022999d2e9fce1d556106" - integrity sha512-jF71kHK61/C1l42WtTGxFiOYmfsxsM1LuVcVrh2Qb3LkV1UjXP0dWTq8jOHNyy8oyAXoX0nTymBIgJDiOf7d0Q== +"@truffle/abi-utils@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@truffle/abi-utils/-/abi-utils-0.2.7.tgz#8aae0582cf65b0c752a3624fdbdcac9a7b454309" + integrity sha512-q3RTGAyCnNgf9oG70pvd747SxJcUcgxUcqdlwPREordd3NlWWIC7ijiI7RXOL8okXHihPlt1VqODIKaDciGgcw== dependencies: change-case "3.0.2" faker "^5.3.1" @@ -1739,18 +1739,18 @@ dependencies: source-map-support "^0.5.19" -"@truffle/blockchain-utils@^0.0.31": - version "0.0.31" - resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.0.31.tgz#0503d9fb2ce3e05c167c27294927f2f88d70a24d" - integrity sha512-BFo/nyxwhoHqPrqBQA1EAmSxeNnspGLiOCMa9pAL7WYSjyNBlrHaqCMO/F2O87G+NUK/u06E70DiSP2BFP0ZZw== +"@truffle/blockchain-utils@^0.0.32": + version "0.0.32" + resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.0.32.tgz#2bc92adbec26372ce0edc254068f6f407017f839" + integrity sha512-/4aNqvO3DbGIF5UzHE4UJ7qAr5fNcx5wNa+c/f+JCpimQ3fyO7r7YVBTar5tj24+0In6e92LEDdstR+m+c7qzw== -"@truffle/codec@^0.11.23": - version "0.11.23" - resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.11.23.tgz#b20289707f295470f31f6d1a3316a7b4766f02a5" - integrity sha512-pX/BnXDo3XWlNPkVptjDjuPKoydmiT+hmESh/Ypa7UmaBCL66LgNvCwmZ1kFAyrM6fEYdQGhR8qk+faxU4qIFw== +"@truffle/codec@^0.11.24": + version "0.11.24" + resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.11.24.tgz#caade626cc5819fdda2a4b85d2e6cb332f12e1e1" + integrity sha512-r7wGVDIdF+r68EE7WHDRhiAh/OhQtXZRMUzwGyghjGM3Xt1Weyf9I8zN+EvnN/4ipnHJMyAc2XcHdnP24C82FA== dependencies: - "@truffle/abi-utils" "^0.2.6" - "@truffle/compile-common" "^0.7.24" + "@truffle/abi-utils" "^0.2.7" + "@truffle/compile-common" "^0.7.25" big.js "^5.2.2" bn.js "^5.1.3" cbor "^5.1.0" @@ -1781,12 +1781,12 @@ utf8 "^3.0.0" web3-utils "1.2.9" -"@truffle/compile-common@^0.7.24": - version "0.7.24" - resolved "https://registry.yarnpkg.com/@truffle/compile-common/-/compile-common-0.7.24.tgz#a2ce11191a68b685cffcbfaa4d34d2b6880ff8fb" - integrity sha512-iF3zjXhxcFVAYEZfQA6Rh2vxQ4xSuk/7pKm7yKlLh3p9WjFaPE+dF8wbgQoehftUnBh6SY91uZI6XiD4QDuxYQ== +"@truffle/compile-common@^0.7.25": + version "0.7.25" + resolved "https://registry.yarnpkg.com/@truffle/compile-common/-/compile-common-0.7.25.tgz#8b8b2787284720faa60fbf45e093318653f85394" + integrity sha512-larNO2GEAQhdoak8+Mby1JEEKVHLUbKvIfpT0g3V1C97RCXyuUv82ceSPvqhaqEp37cPeIBTAmiQtGLJ4tjaPg== dependencies: - "@truffle/error" "^0.0.14" + "@truffle/error" "^0.0.15" colors "1.4.0" "@truffle/contract-schema@^3.2.5", "@truffle/contract-schema@^3.4.4": @@ -1798,16 +1798,16 @@ debug "^4.3.1" "@truffle/contract@^4.3.38": - version "4.4.5" - resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.4.5.tgz#c30f6aaf1c6ea6bcac76320be0d028fa1c0b7353" - integrity sha512-VxraukgvMCmlu8Fp+xzQJroqaPhhv0ozYVs9e5TsFTTwBSBgTjoA8ptbXgATp0WlFGYwPfkdVMReN6m0kP+POw== + version "4.4.6" + resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.4.6.tgz#c9e1cc70dce107fe0d5a575cf3fb698e849a9568" + integrity sha512-gNTBDCJx0dF4S/HsIw8Ec7pXYbhKCZP1D2MGzx29/DoeFFp3NqCt3N8upvFHmKkyD9lvASGC2cmCQF9AJ3Tw7w== dependencies: "@ensdomains/ensjs" "^2.0.1" - "@truffle/blockchain-utils" "^0.0.31" + "@truffle/blockchain-utils" "^0.0.32" "@truffle/contract-schema" "^3.4.4" - "@truffle/debug-utils" "^6.0.5" - "@truffle/error" "^0.0.14" - "@truffle/interface-adapter" "^0.5.9" + "@truffle/debug-utils" "^6.0.6" + "@truffle/error" "^0.0.15" + "@truffle/interface-adapter" "^0.5.10" bignumber.js "^7.2.1" debug "^4.3.1" ethers "^4.0.32" @@ -1829,12 +1829,12 @@ highlight.js "^9.15.8" highlightjs-solidity "^1.0.18" -"@truffle/debug-utils@^6.0.5": - version "6.0.5" - resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-6.0.5.tgz#423116a49d26ca345b3e97fc6f984eca21ea4aea" - integrity sha512-rZARm4k8BTdOLzgLUj6FPqo3BDInoleXnNQn5PwdDDAGj9Iym7B2cu8/axgyGEBhQR2n0/nfNBq/AnQe9IKjzg== +"@truffle/debug-utils@^6.0.6": + version "6.0.6" + resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-6.0.6.tgz#7d681fcd4a05b37d899d97a609eb808ae2848cb8" + integrity sha512-AgKGRnbrP9XMjgXkkGYol9D7o4+5rUAUZx0ObMGCweCpL79kgKcQj2I3hlSq31xs9tEQ+H9Ulf6j35Rsw4Z1eQ== dependencies: - "@truffle/codec" "^0.11.23" + "@truffle/codec" "^0.11.24" "@trufflesuite/chromafi" "^2.2.2" bn.js "^5.1.3" chalk "^2.4.2" @@ -1846,10 +1846,10 @@ resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.0.11.tgz#2789c0042d7e796dcbb840c7a9b5d2bcd8e0e2d8" integrity sha512-ju6TucjlJkfYMmdraYY/IBJaFb+Sa+huhYtOoyOJ+G29KcgytUVnDzKGwC7Kgk6IsxQMm62Mc1E0GZzFbGGipw== -"@truffle/error@^0.0.14": - version "0.0.14" - resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.0.14.tgz#59683b5407bede7bddf16d80dc5592f9c5e5fa05" - integrity sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA== +"@truffle/error@^0.0.15": + version "0.0.15" + resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.0.15.tgz#fa24de95c7eb37dd8ee71161e1a876320ddb41e6" + integrity sha512-keiYGlVAH7GLggqMpB+XorT7NkOlr3qeBc56thI2WP0eas3qstlyrc0WvckXJ2LXrOfcR2uH6f0Nk6FIxaKXSA== "@truffle/hdwallet-provider@eip1559-beta": version "1.5.1-alpha.1" @@ -1874,22 +1874,22 @@ ethers "^4.0.32" web3 "1.3.6" -"@truffle/interface-adapter@^0.5.9": - version "0.5.9" - resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.5.9.tgz#fa785bccf493705563297d4c6f816eb98d8c2009" - integrity sha512-LmzaRzA1pKChfXVnXy9AnOW0N+gugKQtUAnR1Za6KYKAtWSwRdkZo58Q03t4JkxxHDKoniNyQoaio/dhgW87xg== +"@truffle/interface-adapter@^0.5.10": + version "0.5.10" + resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.5.10.tgz#cc51f6559f610bb6e18c1c52eb5b2e87ba9a267e" + integrity sha512-Hb4vjv+hMCfzhUUKIy4hFzAmLoZMHBFF9I8AawEwUa3896kB5iRDNxyoPXXsb1di87ZYDUdtaX6ACWzNaiVdlg== dependencies: bn.js "^5.1.3" ethers "^4.0.32" web3 "1.5.3" "@truffle/provider@^0.2.24": - version "0.2.43" - resolved "https://registry.yarnpkg.com/@truffle/provider/-/provider-0.2.43.tgz#823a6a331c296806773e2273b088bddcfb9757df" - integrity sha512-xEm6q6WWCxw7gQC6KPlY5Xgh81/VNDzHcd4C7NSD6JZ2Ii69xMjU5Po205KcfwI16XY7ibcDILFIyjXarfb0BA== + version "0.2.44" + resolved "https://registry.yarnpkg.com/@truffle/provider/-/provider-0.2.44.tgz#59c81a380a3992d539b54ffbbf713cc75deeb3c0" + integrity sha512-hwQyu4u2a8J4nRLFlLrVA/m+Wa71F8ZXX4wlmzxVBc3svTEnsyg3cYLmM2NVIL/ZT5Hdz/bGkkyXLvWDsHbXlA== dependencies: - "@truffle/error" "^0.0.14" - "@truffle/interface-adapter" "^0.5.9" + "@truffle/error" "^0.0.15" + "@truffle/interface-adapter" "^0.5.10" web3 "1.5.3" "@trufflesuite/chromafi@^2.2.1", "@trufflesuite/chromafi@^2.2.2": @@ -2145,9 +2145,9 @@ form-data "^3.0.0" "@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0": - version "17.0.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.10.tgz#616f16e9d3a2a3d618136b1be244315d95bd7cab" - integrity sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog== + version "17.0.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.14.tgz#33b9b94f789a8fedd30a68efdbca4dbb06b61f20" + integrity sha512-SbjLmERksKOGzWzPNuW7fJM7fk3YXVTFiZWB/Hs99gwhk+/dnrQRPBQjPW9aO+fi1tAffi9PrwFvsmOKmDTyng== "@types/node@^10.0.3": version "10.17.60" @@ -2155,9 +2155,9 @@ integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== "@types/node@^12.0.0", "@types/node@^12.12.6": - version "12.20.42" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.42.tgz#2f021733232c2130c26f9eabbdd3bfd881774733" - integrity sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw== + version "12.20.43" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.43.tgz#6cf47894da4a4748c62fccf720ba269e1b1ff5a4" + integrity sha512-HCfJdaYqJX3BCzeihgZrD7b85Cu05OC/GVJ4kEYIflwUs4jbnUlLLWoq7hw1LBcdvUyehO+gr6P5JQ895/2ZfA== "@types/node@^8.0.0": version "8.10.66" @@ -2209,9 +2209,9 @@ "@types/sinon" "*" "@types/sinon@*": - version "10.0.8" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.8.tgz#e43c3722629248470a866c86ecc06e5523ac0b4e" - integrity sha512-XZbSLlox2KM7VaEJPZ5G/fMZXJNuAtYiFOax7UT51quZMAJRWKvugPMqNA0mV3jC9HIYpQSg6qbV+ilQMwLqyA== + version "10.0.10" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.10.tgz#f8acd72fbc2e87c4679f3e2c1ab3530dff1ab6e2" + integrity sha512-US5E539UfeL2DiWALzCyk0c4zKh6sCv86V/0lpda/afMJJ0oEm2SrKgedH5optvFWstnJ8e1MNYhLmPhAy4rvQ== dependencies: "@sinonjs/fake-timers" "^7.1.0" @@ -2336,14 +2336,14 @@ web3 "^1.6.0" "@uma/contracts-node@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@uma/contracts-node/-/contracts-node-0.2.0.tgz#81c76c9100a2a1d94eea59b04e091eecb0fb29cb" - integrity sha512-Z8x3UcpPbjplFlWNMV+qKzcxvbnQD6PTWIW5l05J9YwbN7lbxjt3fK+ns6RTHkfKJwHifQeSbJ8nzqV4zo/b1Q== + version "0.2.1" + resolved "https://registry.yarnpkg.com/@uma/contracts-node/-/contracts-node-0.2.1.tgz#29ebba6b2ecba7f0d2dc9b484bc34f0abbdefdaa" + integrity sha512-7wPkH/m8tD8UMLYUjSXN5gSp/5NsuPRF1icmwXNTWlhp/Mg4qmJHeANjsWP9JCDxlgdSDixA4hJ5qhVOPXFniA== "@uma/core@^2.18.0", "@uma/core@^2.24.0": - version "2.24.0" - resolved "https://registry.yarnpkg.com/@uma/core/-/core-2.24.0.tgz#fa831f08ea56863808e0a04d68db6c9fb8bfc5c0" - integrity sha512-H7JvIPsnO7Xo3eIhBC3h2lDvuEa1bAFRkSKVTsvva3DrxwJQImuq+QF1cjDFry1HTfRq6VYnDZmMcUlSc9eowQ== + version "2.24.1" + resolved "https://registry.yarnpkg.com/@uma/core/-/core-2.24.1.tgz#39f3d44a398f1fc2ba8eaed07c4d0a7f9425889f" + integrity sha512-edcSzLFqRjkY1UUZBQ6jLtoDbmXfAg2JJcer+9VIQeiePMSlWLuZ0YwpDs3c0UwuefuK8Aws5Y0Tt65PoGJFxg== dependencies: "@openzeppelin/contracts" "4.4.2" "@uma/common" "^2.17.0" @@ -2431,11 +2431,16 @@ "@uniswap/lib" "1.1.1" "@uniswap/v2-core" "1.0.0" -"@uniswap/v3-core@1.0.0", "@uniswap/v3-core@^1.0.0-rc.2": +"@uniswap/v3-core@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.0.tgz#6c24adacc4c25dceee0ba3ca142b35adbd7e359d" integrity sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA== +"@uniswap/v3-core@^1.0.0-rc.2": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.1.tgz#b6d2bdc6ba3c3fbd610bdc502395d86cd35264a0" + integrity sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ== + "@uniswap/v3-periphery@^1.0.0-beta.23": version "1.4.0" resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.4.0.tgz#9abb733fc596916718070c688b5f426fd8d01fe3" @@ -2528,12 +2533,12 @@ abstract-leveldown@~6.2.1: xtend "~4.0.0" accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" + mime-types "~2.1.34" + negotiator "0.6.3" acorn-dynamic-import@^2.0.0: version "2.0.2" @@ -3180,12 +3185,12 @@ babel-plugin-polyfill-corejs2@^0.3.0: semver "^6.1.1" babel-plugin-polyfill-corejs3@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz#d66183bf10976ea677f4149a7fcc4d8df43d4060" - integrity sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A== + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" + integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== dependencies: "@babel/helper-define-polyfill-provider" "^0.3.1" - core-js-compat "^3.20.0" + core-js-compat "^3.21.0" babel-plugin-polyfill-regenerator@^0.3.0: version "0.3.1" @@ -4048,9 +4053,9 @@ camelcase@^5.0.0: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001286: - version "1.0.30001301" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001301.tgz#ebc9086026534cab0dab99425d9c3b4425e5f450" - integrity sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA== + version "1.0.30001306" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001306.tgz#582592afe243bad2223081b8abab07bf289cc699" + integrity sha512-Wd1OuggRzg1rbnM5hv1wXs2VkxJH/AA+LuudlIqvZiCvivF+wJJe2mgBZC8gPMgI7D76PP5CTx8Luvaqc1V6OQ== caseless@^0.12.0, caseless@~0.12.0: version "0.12.0" @@ -4074,14 +4079,15 @@ center-align@^0.1.1: lazy-cache "^1.0.3" chai@^4.2.0, chai@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" - integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== + version "4.3.6" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" + integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== dependencies: assertion-error "^1.1.0" check-error "^1.0.2" deep-eql "^3.0.1" get-func-name "^2.0.0" + loupe "^2.3.1" pathval "^1.1.1" type-detect "^4.0.5" @@ -4540,11 +4546,16 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.1, cookie@^0.4.1: +cookie@0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== +cookie@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + cookiejar@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.3.tgz#fc7a6216e408e74414b90230050842dacda75acc" @@ -4555,18 +4566,18 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.20.0: - version "3.20.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.3.tgz#d71f85f94eb5e4bea3407412e549daa083d23bd6" - integrity sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw== +core-js-compat@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.0.tgz#bcc86aa5a589cee358e7a7fa0a4979d5a76c3885" + integrity sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A== dependencies: browserslist "^4.19.1" semver "7.0.0" core-js-pure@^3.0.1: - version "3.20.3" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.20.3.tgz#6cc4f36da06c61d95254efc54024fe4797fd5d02" - integrity sha512-Q2H6tQ5MtPtcC7f3HxJ48i4Q7T9ybPKgvWyuH7JXIoNa2pm0KuBnycsET/qw1SLLZYfbsbrZQNMeIOClb+6WIA== + version "3.21.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.0.tgz#819adc8dfb808205ce25b51d50591becd615db7e" + integrity sha512-VaJUunCZLnxuDbo1rNOzwbet9E1K9joiXS5+DQMPtgxd24wfsZbJZMMfQLGYMlCUvSxLfsRUUhoOR2x28mFfeg== core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: version "2.6.12" @@ -4613,12 +4624,12 @@ cosmiconfig@^7.0.0: yaml "^1.10.0" crc-32@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" - integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== + version "1.2.1" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.1.tgz#436d2bcaad27bcb6bd073a2587139d3024a16460" + integrity sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w== dependencies: exit-on-epipe "~1.0.1" - printj "~1.1.0" + printj "~1.3.1" create-ecdh@^4.0.0: version "4.0.4" @@ -4793,7 +4804,7 @@ debug@3.2.6: dependencies: ms "^2.1.1" -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== @@ -5153,9 +5164,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.17: - version "1.4.51" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.51.tgz#a432f5a5d983ace79278a33057300cf949627e63" - integrity sha512-JNEmcYl3mk1tGQmy0EvL5eik/CKSBuzAyGP0QFdG6LIgxQe3II0BL1m2zKc2MZMf3uGqHWE1TFddJML0RpjSHQ== + version "1.4.63" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.63.tgz#866db72d1221fda89419dc22669d03833e11625d" + integrity sha512-e0PX/LRJPFRU4kzJKLvTobxyFdnANCvcoDCe8XcyTqP58nTWIwdsHvXLIl1RkB39X5yaosLaroMASWB0oIsgCA== elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.4.1, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -5449,9 +5460,9 @@ eslint-import-resolver-node@^0.3.6: resolve "^1.20.0" eslint-module-utils@^2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz#1d0aa455dcf41052339b63cada8ab5fd57577129" - integrity sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg== + version "2.7.3" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz#ad7e3a10552fdd0642e1e55292781bd6e34876ee" + integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ== dependencies: debug "^3.2.7" find-up "^2.1.0" @@ -6171,10 +6182,10 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum rlp "^2.0.0" safe-buffer "^5.1.1" -ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.2, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz#b55d7b64dde3e3e45749e4c41288238edec32d23" - integrity sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw== +ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.2, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.3, ethereumjs-util@^7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz#a6885bcdd92045b06f596c7626c3e89ab3312458" + integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A== dependencies: "@types/bn.js" "^5.1.0" bn.js "^5.1.2" @@ -6301,9 +6312,9 @@ ethers@^4.0.0-beta.1, ethers@^4.0.32, ethers@^4.0.40: xmlhttprequest "1.8.0" ethers@^5.0.0, ethers@^5.0.1, ethers@^5.0.13, ethers@^5.0.2, ethers@^5.4.5, ethers@^5.4.7, ethers@^5.5.0, ethers@^5.5.2: - version "5.5.3" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.5.3.tgz#1e361516711c0c3244b6210e7e3ecabf0c75fca0" - integrity sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g== + version "5.5.4" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.5.4.tgz#e1155b73376a2f5da448e4a33351b57a885f4352" + integrity sha512-N9IAXsF8iKhgHIC6pquzRgPBJEzc9auw3JoRkaKe+y4Wl/LFBtDDunNe7YmdomontECAcC5APaAgWZBiu1kirw== dependencies: "@ethersproject/abi" "5.5.0" "@ethersproject/abstract-provider" "5.5.1" @@ -6323,7 +6334,7 @@ ethers@^5.0.0, ethers@^5.0.1, ethers@^5.0.13, ethers@^5.0.2, ethers@^5.4.5, ethe "@ethersproject/networks" "5.5.2" "@ethersproject/pbkdf2" "5.5.0" "@ethersproject/properties" "5.5.0" - "@ethersproject/providers" "5.5.2" + "@ethersproject/providers" "5.5.3" "@ethersproject/random" "5.5.1" "@ethersproject/rlp" "5.5.0" "@ethersproject/sha2" "5.5.0" @@ -6771,9 +6782,9 @@ flatted@^2.0.0: integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== flatted@^3.1.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" - integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== + version "3.2.5" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== flow-stoplight@^1.0.0: version "1.0.0" @@ -7187,7 +7198,7 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6: +glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6, glob@~7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -7199,18 +7210,6 @@ glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@~7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - global-modules@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -7241,9 +7240,9 @@ globals@^11.1.0, globals@^11.7.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: - version "13.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" - integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== + version "13.12.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb" + integrity sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw== dependencies: type-fest "^0.20.2" @@ -7294,9 +7293,9 @@ google-auth-library@^7.0.0, google-auth-library@^7.6.1, google-auth-library@^7.9 lru-cache "^6.0.0" google-gax@^2.24.1: - version "2.29.4" - resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-2.29.4.tgz#9126b9e6d58a88dd8217acef5109e5697ee1ec08" - integrity sha512-3o6cByD2fE1yIc6i1gpKMQlJStqlvu8Sa/Ly/HCQ6GPHpltpVfkTT4KVj2YLVa7WTSDoGbsLBDmJ1KfN1uNiRw== + version "2.29.5" + resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-2.29.5.tgz#876528a5a095109e5ca2744782da5ed886cfab5e" + integrity sha512-wJI+rgqujcl4/0eO4sRIwXAJAD+G8dFRqvGxc2lUuZtdzOToc5NHYbrTvplWQVO6Lw1YNsk9u1pKN3HcXembJg== dependencies: "@grpc/grpc-js" "~1.5.0" "@grpc/proto-loader" "^0.6.1" @@ -7308,7 +7307,7 @@ google-gax@^2.24.1: is-stream-ended "^0.1.4" node-fetch "^2.6.1" object-hash "^2.1.1" - proto3-json-serializer "^0.1.7" + proto3-json-serializer "^0.1.8" protobufjs "6.11.2" retry-request "^4.0.0" @@ -8058,7 +8057,7 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.2.0, is-core-module@^2.8.0, is-core-module@^2.8.1: +is-core-module@^2.8.0, is-core-module@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== @@ -8242,7 +8241,7 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.4, is-regex@^1.1.4, is-regex@~1.1.3: +is-regex@^1.0.4, is-regex@^1.1.4, is-regex@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -9085,6 +9084,13 @@ loose-envify@^1.0.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +loupe@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.2.tgz#799a566ba5aa8d11b93ddccc92c569bbae7e9490" + integrity sha512-QgVamnvj0jX1LMPlCAq0MK6hATORFtGqHoUKXTkwNe13BqlN6aePQCKnnTcFvdDYEEITcJ+gBl4mTW7YJtJbyQ== + dependencies: + get-func-name "^2.0.0" + lower-case-first@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1" @@ -9318,17 +9324,16 @@ merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: rlp "^2.0.0" semaphore ">=1.0.1" -merkle-patricia-tree@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.2.2.tgz#6dec17855370172458244c2f42c989dd60b773a3" - integrity sha512-eqZYNTshcYx9aESkSPr71EqwsR/QmpnObDEV4iLxkt/x/IoLYZYjJvKY72voP/27Vy61iMOrfOG6jrn7ttXD+Q== +merkle-patricia-tree@^4.2.2, merkle-patricia-tree@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.2.3.tgz#b4e5d485d231f02b255ed79a7852f9d12ee0c09f" + integrity sha512-S4xevdXl5KvdBGgUxhQcxoep0onqXiIhzfwZp4M78kIuJH3Pu9o9IUgqhzSFOR2ykLO6t265026Xb6PY0q2UFQ== dependencies: "@types/levelup" "^4.3.0" - ethereumjs-util "^7.1.2" + ethereumjs-util "^7.1.4" level-mem "^5.0.1" level-ws "^2.0.0" readable-stream "^3.6.0" - rlp "^2.2.4" semaphore-async-await "^1.5.1" methods@~1.1.2: @@ -9376,7 +9381,7 @@ mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== -mime-types@^2.0.8, mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@^2.0.8, mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.34" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== @@ -9678,10 +9683,10 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== neo-async@^2.5.0, neo-async@^2.6.0: version "2.6.2" @@ -9960,16 +9965,11 @@ object-hash@^2.1.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== -object-inspect@^1.11.0, object-inspect@^1.9.0: +object-inspect@^1.11.0, object-inspect@^1.9.0, object-inspect@~1.12.0: version "1.12.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -object-inspect@~1.11.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.1.tgz#d4bd7d7de54b9a75599f59a00bd698c1f1c6549b" - integrity sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA== - object-is@^1.0.1: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" @@ -10670,10 +10670,10 @@ pretty-quick@^2.0.1: mri "^1.1.4" multimatch "^4.0.0" -printj@~1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" - integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== +printj@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.3.1.tgz#9af6b1d55647a1587ac44f4c1654a4b95b8e12cb" + integrity sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg== private@^0.1.6, private@^0.1.8: version "0.1.8" @@ -10710,7 +10710,7 @@ promise@^8.0.0: dependencies: asap "~2.0.6" -proto3-json-serializer@^0.1.7: +proto3-json-serializer@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/proto3-json-serializer/-/proto3-json-serializer-0.1.8.tgz#f80f9afc1efe5ed9a9856bbbd17dc7cabd7ce9a3" integrity sha512-ACilkB6s1U1gWnl5jtICpnDai4VCxmI9GFxuEaYdxtDG2oVI3sVFIUsvUZcQbJgtPM6p+zqKbjTKQZp6Y4FpQw== @@ -11263,7 +11263,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.8.1: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.8.1, resolve@~1.22.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== @@ -11272,14 +11272,6 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.20 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@~1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -11720,18 +11712,18 @@ simple-concat@^1.0.0: integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== simple-get@^2.7.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" - integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== + version "2.8.2" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019" + integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== dependencies: decompress-response "^3.3.0" once "^1.3.1" simple-concat "^1.0.0" simple-get@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" - integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + version "3.1.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55" + integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== dependencies: decompress-response "^4.2.0" once "^1.3.1" @@ -12122,7 +12114,7 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string.prototype.trim@~1.2.4: +string.prototype.trim@~1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.5.tgz#a587bcc8bfad8cb9829a577f5de30dd170c1682c" integrity sha512-Lnh17webJVsD6ECeovpVN17RlAKjmz4rF9S+8Y45CkMc/ufVpTkU3vZIyIC7sllQ1FCvObZnnCdNs/HXTUOTlg== @@ -12361,24 +12353,24 @@ tapable@^0.2.7: integrity sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A== tape@^4.4.0, tape@^4.6.3: - version "4.14.0" - resolved "https://registry.yarnpkg.com/tape/-/tape-4.14.0.tgz#e4d46097e129817175b90925f2385f6b1bcfa826" - integrity sha512-z0+WrUUJuG6wIdWrl4W3rTte2CR26G6qcPOj3w1hfRdcmhF3kHBhOBW9VHsPVAkz08ZmGzp7phVpDupbLzrYKQ== + version "4.15.0" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.15.0.tgz#1b8a9563b4bc7e51302216c137732fb2ce6d1a99" + integrity sha512-SfRmG2I8QGGgJE/MCiLH8c11L5XxyUXxwK9xLRD0uiK5fehRkkSZGmR6Y1pxOt8vJ19m3sY+POTQpiaVv45/LQ== dependencies: call-bind "~1.0.2" deep-equal "~1.1.1" defined "~1.0.0" dotignore "~0.1.2" for-each "~0.3.3" - glob "~7.1.7" + glob "~7.2.0" has "~1.0.3" inherits "~2.0.4" - is-regex "~1.1.3" + is-regex "~1.1.4" minimist "~1.2.5" - object-inspect "~1.11.0" - resolve "~1.20.0" + object-inspect "~1.12.0" + resolve "~1.22.0" resumer "~0.0.0" - string.prototype.trim "~1.2.4" + string.prototype.trim "~1.2.5" through "~2.3.8" tar-fs@^2.0.0: @@ -12753,9 +12745,9 @@ type@^1.0.1: integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== type@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" - integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== typechain@^3.0.0: version "3.0.0" @@ -12841,9 +12833,9 @@ uglify-js@^2.8.29: uglify-to-browserify "~1.0.0" uglify-js@^3.1.4: - version "3.14.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.5.tgz#cdabb7d4954231d80cb4a927654c4655e51f4859" - integrity sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ== + version "3.15.0" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.0.tgz#2d6a689d94783cab43975721977a13c2afec28f1" + integrity sha512-x+xdeDWq7FiORDvyIJ0q/waWd4PhjBNOm5dQUOq2AKC0IEjxOS66Ha9tctiVDGcRQuh69K7fgU5oRuTK4cysSg== uglify-to-browserify@~1.0.0: version "1.0.2" From 7481c58858634681978cd3b0036d1a1f3ef4241b Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Thu, 3 Feb 2022 10:43:36 -0800 Subject: [PATCH 07/17] gas opt --- contracts/SpokePool.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index e973a6941..f76a849ed 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -271,8 +271,8 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // cross domain sender is the HubPool. This validation step differs for each L2, which is why the implementation // specifics are left to the implementor of this abstract contract. function _initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) internal { + uint256 relayerRefundId = relayerRefunds.length; relayerRefunds.push(); - uint256 relayerRefundId = relayerRefunds.length - 1; relayerRefunds[relayerRefundId].distributionRoot = relayerRepaymentDistributionProof; emit InitializedRelayerRefund(relayerRefundId, relayerRepaymentDistributionProof); } From a666d86cb63dbfdfba02af9d0ec74eec40fec68b Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Thu, 3 Feb 2022 11:08:17 -0800 Subject: [PATCH 08/17] Add tests --- test/Optimism_SpokePool.ts | 1 + test/SpokePool.RelayerRefund.ts | 27 +++++++++++++++++++++------ test/constants.ts | 6 +++++- 3 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 test/Optimism_SpokePool.ts diff --git a/test/Optimism_SpokePool.ts b/test/Optimism_SpokePool.ts new file mode 100644 index 000000000..74ebbcbca --- /dev/null +++ b/test/Optimism_SpokePool.ts @@ -0,0 +1 @@ +// TODO: Test OVM specific functionality and implementation of SpokePool internal methods. diff --git a/test/SpokePool.RelayerRefund.ts b/test/SpokePool.RelayerRefund.ts index b4d9321eb..91d39929a 100644 --- a/test/SpokePool.RelayerRefund.ts +++ b/test/SpokePool.RelayerRefund.ts @@ -1,7 +1,22 @@ -// TODO: -// - initiateRelayerRefund(): -// - Test that distribution root is stored and even is emitted. -// - Count of roots should increment. +import { expect } from "chai"; +import { Contract } from "ethers"; +import { ethers } from "hardhat"; +import { SignerWithAddress } from "./utils"; +import { spokePoolFixture } from "./SpokePool.Fixture"; +import { spokePoolRelayerRefundRoot, spokePoolRelayerRefundRootDefaultId } from "./constants"; -// TODO: -// - Figure out best structure to test L2-specific contracts. +let spokePool: Contract; +let caller: SignerWithAddress; + +describe.only("SpokePool Initialize Relayer Refund Logic", async function () { + beforeEach(async function () { + [caller] = await ethers.getSigners(); + ({ spokePool } = await spokePoolFixture()); + }); + it("Initializing root stores root and emits event", async function () { + await expect(spokePool.connect(caller).initializeRelayerRefund(spokePoolRelayerRefundRoot)) + .to.emit(spokePool, "InitializedRelayerRefund") + .withArgs(spokePoolRelayerRefundRootDefaultId, spokePoolRelayerRefundRoot); + expect(await spokePool.relayerRefunds(spokePoolRelayerRefundRootDefaultId)).to.equal(spokePoolRelayerRefundRoot); + }); +}); diff --git a/test/constants.ts b/test/constants.ts index 7474ab5b9..b1cad810b 100644 --- a/test/constants.ts +++ b/test/constants.ts @@ -1,4 +1,4 @@ -import { toWei, utf8ToHex, toBN } from "./utils"; +import { toWei, utf8ToHex, toBN, createRandomBytes32 } from "./utils"; export const amountToSeedWallets = toWei("1500"); @@ -39,3 +39,7 @@ export const zeroBytes32 = "0x00000000000000000000000000000000000000000000000000 export const identifier = utf8ToHex("IS_ACROSS_V2_RELAY_VALID"); export const zeroRawValue = { rawValue: "0" }; + +export const spokePoolRelayerRefundRoot = createRandomBytes32(); + +export const spokePoolRelayerRefundRootDefaultId = 0; From 35d9d87a98399809c8ceb4ba05504a6166b86884 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Thu, 3 Feb 2022 11:55:03 -0800 Subject: [PATCH 09/17] Add setCrossDomain func --- contracts/Optimism_SpokePool.sol | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/contracts/Optimism_SpokePool.sol b/contracts/Optimism_SpokePool.sol index 0633e481a..174f78d39 100644 --- a/contracts/Optimism_SpokePool.sol +++ b/contracts/Optimism_SpokePool.sol @@ -32,6 +32,17 @@ contract Optimism_SpokePool is CrossDomainEnabled, SpokePool { * ADMIN FUNCTIONS * **************************************/ + /** + * @notice Changes the L1 contract that can trigger admin functions on this contract. + * @dev This should be set to the address of the L1 contract that ultimately relays a cross-domain message, which + * is expected to be the Optimism_Adapter. + * @dev Only callable by the existing admin via the Optimism cross domain messenger. + * @param newCrossDomainAdmin address of the new L1 admin contract. + */ + function setCrossDomainAdmin(address newCrossDomainAdmin) public onlyFromCrossDomainAccount(crossDomainAdmin) { + _setCrossDomainAdmin(newCrossDomainAdmin); + } + // TODO: function setEnableRoute( address originToken, From 22ad18a77931800aacb2fdff09cbe94eafcbd765 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Thu, 3 Feb 2022 12:01:17 -0800 Subject: [PATCH 10/17] remove exclsuve test --- test/SpokePool.RelayerRefund.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SpokePool.RelayerRefund.ts b/test/SpokePool.RelayerRefund.ts index 91d39929a..5b9131188 100644 --- a/test/SpokePool.RelayerRefund.ts +++ b/test/SpokePool.RelayerRefund.ts @@ -8,7 +8,7 @@ import { spokePoolRelayerRefundRoot, spokePoolRelayerRefundRootDefaultId } from let spokePool: Contract; let caller: SignerWithAddress; -describe.only("SpokePool Initialize Relayer Refund Logic", async function () { +describe("SpokePool Initialize Relayer Refund Logic", async function () { beforeEach(async function () { [caller] = await ethers.getSigners(); ({ spokePool } = await spokePoolFixture()); From eb505e99ef67e9a7eedc1b9809847a8fa14d08fc Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Fri, 4 Feb 2022 07:38:42 -0800 Subject: [PATCH 11/17] Add interface --- contracts/Optimism_SpokePool.sol | 18 +++++++++++------- contracts/SpokePoolInterface.sol | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 contracts/SpokePoolInterface.sol diff --git a/contracts/Optimism_SpokePool.sol b/contracts/Optimism_SpokePool.sol index 174f78d39..cd6d36bc6 100644 --- a/contracts/Optimism_SpokePool.sol +++ b/contracts/Optimism_SpokePool.sol @@ -4,15 +4,16 @@ pragma solidity ^0.8.0; import "@eth-optimism/contracts/libraries/bridge/CrossDomainEnabled.sol"; import "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol"; import "./SpokePool.sol"; +import "./SpokePoolInterface.sol"; /** * @notice OVM specific SpokePool. * @dev Uses OVM cross-domain-enabled logic for access control. */ -contract Optimism_SpokePool is CrossDomainEnabled, SpokePool { +contract Optimism_SpokePool is CrossDomainEnabled, SpokePoolInterface, SpokePool { // Address of the L1 contract that acts as the owner of this SpokePool. - address public crossDomainAdmin; + address public override crossDomainAdmin; event SetXDomainAdmin(address indexed newAdmin); @@ -39,26 +40,29 @@ contract Optimism_SpokePool is CrossDomainEnabled, SpokePool { * @dev Only callable by the existing admin via the Optimism cross domain messenger. * @param newCrossDomainAdmin address of the new L1 admin contract. */ - function setCrossDomainAdmin(address newCrossDomainAdmin) public onlyFromCrossDomainAccount(crossDomainAdmin) { + function setCrossDomainAdmin(address newCrossDomainAdmin) + public + override + onlyFromCrossDomainAccount(crossDomainAdmin) + { _setCrossDomainAdmin(newCrossDomainAdmin); } - // TODO: function setEnableRoute( address originToken, uint256 destinationChainId, bool enable - ) public onlyFromCrossDomainAccount(crossDomainAdmin) { + ) public override onlyFromCrossDomainAccount(crossDomainAdmin) { _setEnableRoute(originToken, destinationChainId, enable); } - // TODO: - function setDepositQuoteTimeBuffer(uint64 buffer) public onlyFromCrossDomainAccount(crossDomainAdmin) { + function setDepositQuoteTimeBuffer(uint64 buffer) public override onlyFromCrossDomainAccount(crossDomainAdmin) { _setDepositQuoteTimeBuffer(buffer); } function initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) public + override onlyFromCrossDomainAccount(crossDomainAdmin) { _initializeRelayerRefund(relayerRepaymentDistributionProof); diff --git a/contracts/SpokePoolInterface.sol b/contracts/SpokePoolInterface.sol new file mode 100644 index 000000000..3ced7fc93 --- /dev/null +++ b/contracts/SpokePoolInterface.sol @@ -0,0 +1,18 @@ +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + +interface SpokePoolInterface { + function crossDomainAdmin() external returns (address); + + function setCrossDomainAdmin(address newCrossDomainAdmin) external; + + function setEnableRoute( + address originToken, + uint256 destinationChainId, + bool enable + ) external; + + function setDepositQuoteTimeBuffer(uint64 buffer) external; + + function initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) external; +} From 8fb750a0e40fbbf7f4f5cab6ed0bf3d4835a57a9 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Fri, 4 Feb 2022 10:06:19 -0800 Subject: [PATCH 12/17] Add comemnts and change interface --- contracts/SpokePool.sol | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index f76a849ed..e070ddf14 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -7,6 +7,7 @@ import "@openzeppelin/contracts/utils/Address.sol"; import "@uma/core/contracts/common/implementation/Testable.sol"; import "@uma/core/contracts/common/implementation/Lockable.sol"; import "@uma/core/contracts/common/implementation/MultiCaller.sol"; +import "./MerkleLib.sol"; interface WETH9Like { function withdraw(uint256 wad) external; @@ -270,6 +271,8 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // This internal method should be called by an external "initializeRelayerRefund" function that validates the // cross domain sender is the HubPool. This validation step differs for each L2, which is why the implementation // specifics are left to the implementor of this abstract contract. + // Once this method is executed and a distribution root is stored in this contract, then `distributeRelayerRefund` + // can be called to execute each leaf in the root. function _initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) internal { uint256 relayerRefundId = relayerRefunds.length; relayerRefunds.push(); @@ -277,13 +280,12 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { emit InitializedRelayerRefund(relayerRefundId, relayerRepaymentDistributionProof); } + // Call this method to execute a leaf within the `distributionRoot` stored on this contract. Caller must include a + // valid `inclusionProof` to verify that the leaf is contained within the root. The `relayerRefundId` is the index + // of the specific distribution root containing the passed in leaf. function distributeRelayerRefund( uint256 relayerRefundId, - uint256 leafId, - address l2TokenAddress, - uint256 netSendAmount, - address[] memory relayerRefundAddresses, - uint256[] memory relayerRefundAmounts, + MerkleLib.DestinationDistribution memory distributionLeaf, bytes32[] memory inclusionProof ) public {} From 67ef9d82e20a69f693282e991f377ded4ac942b6 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Fri, 4 Feb 2022 12:43:14 -0800 Subject: [PATCH 13/17] rebase master --- test/SpokePool.RelayerRefund.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/SpokePool.RelayerRefund.ts b/test/SpokePool.RelayerRefund.ts index 5b9131188..dfc46a2da 100644 --- a/test/SpokePool.RelayerRefund.ts +++ b/test/SpokePool.RelayerRefund.ts @@ -3,7 +3,7 @@ import { Contract } from "ethers"; import { ethers } from "hardhat"; import { SignerWithAddress } from "./utils"; import { spokePoolFixture } from "./SpokePool.Fixture"; -import { spokePoolRelayerRefundRoot, spokePoolRelayerRefundRootDefaultId } from "./constants"; +import { mockDestinationDistributionRoot } from "./constants"; let spokePool: Contract; let caller: SignerWithAddress; @@ -14,9 +14,9 @@ describe("SpokePool Initialize Relayer Refund Logic", async function () { ({ spokePool } = await spokePoolFixture()); }); it("Initializing root stores root and emits event", async function () { - await expect(spokePool.connect(caller).initializeRelayerRefund(spokePoolRelayerRefundRoot)) + await expect(spokePool.connect(caller).initializeRelayerRefund(mockDestinationDistributionRoot)) .to.emit(spokePool, "InitializedRelayerRefund") - .withArgs(spokePoolRelayerRefundRootDefaultId, spokePoolRelayerRefundRoot); - expect(await spokePool.relayerRefunds(spokePoolRelayerRefundRootDefaultId)).to.equal(spokePoolRelayerRefundRoot); + .withArgs(0, mockDestinationDistributionRoot); + expect(await spokePool.relayerRefunds(0)).to.equal(mockDestinationDistributionRoot); }); }); From ce78455928c6f000fc00df5273a90d3c9defe897 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Fri, 4 Feb 2022 15:50:47 -0800 Subject: [PATCH 14/17] Update SpokePool.sol --- contracts/SpokePool.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index 60386a9e3..e070ddf14 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -8,7 +8,6 @@ import "@uma/core/contracts/common/implementation/Testable.sol"; import "@uma/core/contracts/common/implementation/Lockable.sol"; import "@uma/core/contracts/common/implementation/MultiCaller.sol"; import "./MerkleLib.sol"; -import "./SpokePoolInterface.sol"; interface WETH9Like { function withdraw(uint256 wad) external; @@ -24,7 +23,7 @@ interface WETH9Like { * on the destination chain. Locked source chain tokens are later sent over the canonical token bridge to L1. * @dev This contract is designed to be deployed to L2's, not mainnet. */ -abstract contract SpokePool is SpokePoolInterface, Testable, Lockable, MultiCaller { +abstract contract SpokePool is Testable, Lockable, MultiCaller { using SafeERC20 for IERC20; using Address for address; From 37ef6bb2211075df722a2a49d353a36031ac50ec Mon Sep 17 00:00:00 2001 From: nicholaspai <9457025+nicholaspai@users.noreply.github.com> Date: Fri, 4 Feb 2022 15:51:06 -0800 Subject: [PATCH 15/17] Update contracts/SpokePool.sol Co-authored-by: Matt Rice --- contracts/SpokePool.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index e070ddf14..c17c8ef60 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -275,8 +275,7 @@ abstract contract SpokePool is Testable, Lockable, MultiCaller { // can be called to execute each leaf in the root. function _initializeRelayerRefund(bytes32 relayerRepaymentDistributionProof) internal { uint256 relayerRefundId = relayerRefunds.length; - relayerRefunds.push(); - relayerRefunds[relayerRefundId].distributionRoot = relayerRepaymentDistributionProof; + relayerRefunds.push().distributionRoot = relayerRepaymentDistributionProof; emit InitializedRelayerRefund(relayerRefundId, relayerRepaymentDistributionProof); } From a61f7778d7788b27b14e9e6d22c6f74491cdce96 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Fri, 4 Feb 2022 16:36:01 -0800 Subject: [PATCH 16/17] add todo --- contracts/HubPool.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/HubPool.sol b/contracts/HubPool.sol index 3b01c678c..2aa87c7b3 100644 --- a/contracts/HubPool.sol +++ b/contracts/HubPool.sol @@ -163,6 +163,8 @@ contract HubPool is Testable, Lockable, MultiCaller, Ownable { ) public onlyOwner { whitelistedRoutes[originToken][destinationChainId] = destinationToken; + // TODO: Should relay message to L2 for destinationChainId and call setEnableRoute(originToken, destinationChainId, true) + emit WhitelistRoute(originToken, destinationChainId, destinationToken); } From 2d417e965304833f32c5c993ed9af003fd0d0622 Mon Sep 17 00:00:00 2001 From: Nick Pai Date: Sat, 5 Feb 2022 15:27:38 -0800 Subject: [PATCH 17/17] rename file --- ...okePool.RelayerRefund.ts => SpokePool.RefundInitialization.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{SpokePool.RelayerRefund.ts => SpokePool.RefundInitialization.ts} (100%) diff --git a/test/SpokePool.RelayerRefund.ts b/test/SpokePool.RefundInitialization.ts similarity index 100% rename from test/SpokePool.RelayerRefund.ts rename to test/SpokePool.RefundInitialization.ts