From 5276bfda1f1cd4a9b711d80c5211ad4ac5b3302c Mon Sep 17 00:00:00 2001 From: bidyut-arianelabs Date: Wed, 21 Sep 2022 15:42:50 +0530 Subject: [PATCH] unit test --- contracts/domain/BosonConstants.sol | 4 +- .../mock/MockMetaTransactionsHandlerFacet.sol | 9 +++ .../protocol/facets/ConfigHandlerFacet.sol | 2 +- contracts/protocol/libs/EIP712Lib.sol | 4 +- scripts/util/test-utils.js | 4 +- test/protocol/MetaTransactionsHandlerTest.js | 81 ++++++++++++++++++- 6 files changed, 96 insertions(+), 8 deletions(-) diff --git a/contracts/domain/BosonConstants.sol b/contracts/domain/BosonConstants.sol index 314279566..ab8e181fa 100644 --- a/contracts/domain/BosonConstants.sol +++ b/contracts/domain/BosonConstants.sol @@ -159,8 +159,8 @@ string constant FEE_PERCENTAGE_INVALID = "Percentage representation must be less string constant VALUE_ZERO_NOT_ALLOWED = "Value must be greater than 0"; // EIP712Lib -string constant PROTOCOL_NAME = "BosonProtocolDiamond"; -string constant PROTOCOL_VERSION = "V1"; +string constant PROTOCOL_NAME = "Boson Protocol"; +string constant PROTOCOL_VERSION = "V2"; bytes32 constant EIP712_DOMAIN_TYPEHASH = keccak256( bytes("EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)") ); diff --git a/contracts/mock/MockMetaTransactionsHandlerFacet.sol b/contracts/mock/MockMetaTransactionsHandlerFacet.sol index 67663c080..26a96e858 100644 --- a/contracts/mock/MockMetaTransactionsHandlerFacet.sol +++ b/contracts/mock/MockMetaTransactionsHandlerFacet.sol @@ -18,4 +18,13 @@ contract MockMetaTransactionsHandlerFacet is ProtocolBase { protocolMetaTxInfo().isMetaTransaction = true; protocolMetaTxInfo().currentSenderAddress = _signerAddress; } + + /** + * @notice Sets the cached chain id value. + * + * @param _chainId - chain id + */ + function setCachedChainId(uint256 _chainId) public { + protocolMetaTxInfo().cachedChainId = _chainId; + } } diff --git a/contracts/protocol/facets/ConfigHandlerFacet.sol b/contracts/protocol/facets/ConfigHandlerFacet.sol index f9019bb64..adfafb635 100644 --- a/contracts/protocol/facets/ConfigHandlerFacet.sol +++ b/contracts/protocol/facets/ConfigHandlerFacet.sol @@ -66,7 +66,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { // Initialize protocol meta-transaction config params ProtocolLib.ProtocolMetaTxInfo storage pmti = protocolMetaTxInfo(); - pmti.domainSeparator = EIP712Lib.domainSeparator(PROTOCOL_NAME, PROTOCOL_VERSION); + pmti.domainSeparator = EIP712Lib.buildDomainSeparator(PROTOCOL_NAME, PROTOCOL_VERSION); pmti.cachedChainId = block.chainid; pmti.cachedThis = address(this); } diff --git a/contracts/protocol/libs/EIP712Lib.sol b/contracts/protocol/libs/EIP712Lib.sol index a876c9847..87592ef69 100644 --- a/contracts/protocol/libs/EIP712Lib.sol +++ b/contracts/protocol/libs/EIP712Lib.sol @@ -17,7 +17,7 @@ library EIP712Lib { * @param _version - The version of the protocol * @return the domain separator hash */ - function domainSeparator(string memory _name, string memory _version) internal view returns (bytes32) { + function buildDomainSeparator(string memory _name, string memory _version) internal view returns (bytes32) { return keccak256( abi.encode( @@ -74,7 +74,7 @@ library EIP712Lib { if (address(this) == cachedThis && block.chainid == cachedChainId) { return ProtocolLib.protocolMetaTxInfo().domainSeparator; } else { - return domainSeparator(PROTOCOL_NAME, PROTOCOL_VERSION); + return buildDomainSeparator(PROTOCOL_NAME, PROTOCOL_VERSION); } } diff --git a/scripts/util/test-utils.js b/scripts/util/test-utils.js index b4301f0d9..698a1790b 100644 --- a/scripts/util/test-utils.js +++ b/scripts/util/test-utils.js @@ -120,8 +120,8 @@ async function prepareDataSignatureParameters( ]; const domainData = { - name: "BosonProtocolDiamond", - version: "V1", + name: "Boson Protocol", + version: "V2", verifyingContract: metaTransactionsHandlerAddress, salt: ethers.utils.hexZeroPad(ethers.BigNumber.from(31337).toHexString(), 32), //hardhat default chain id is 31337 }; diff --git a/test/protocol/MetaTransactionsHandlerTest.js b/test/protocol/MetaTransactionsHandlerTest.js index 32146988d..fb9385644 100644 --- a/test/protocol/MetaTransactionsHandlerTest.js +++ b/test/protocol/MetaTransactionsHandlerTest.js @@ -29,6 +29,8 @@ const { mockExchange, } = require("../utils/mock"); const { oneWeek, oneMonth } = require("../utils/constants"); +const { getSelectors, FacetCutAction } = require("../../scripts/util/diamond-utils.js"); + /** * Test the Boson Meta transactions Handler interface */ @@ -60,7 +62,8 @@ describe("IBosonMetaTransactionsHandler", function () { pauseHandler, bosonToken, support, - result; + result, + mockMetaTransactionsHandler; let metaTransactionsHandler, nonce, functionSignature; let seller, offerId, buyerId; let validOfferDetails, @@ -231,6 +234,43 @@ describe("IBosonMetaTransactionsHandler", function () { [bosonToken, mockToken] = await deployMockTokens(gasLimit, ["BosonToken", "Foreign20"]); }); + async function upgradeMetaTransactionsHandlerFacet() { + // Upgrade the ExchangeHandlerFacet functions + // DiamondCutFacet + const cutFacetViaDiamond = await ethers.getContractAt("DiamondCutFacet", protocolDiamond.address); + + // Deploy MockMetaTransactionsHandlerFacet + const MockMetaTransactionsHandlerFacet = await ethers.getContractFactory("MockMetaTransactionsHandlerFacet"); + const mockMetaTransactionsHandlerFacet = await MockMetaTransactionsHandlerFacet.deploy(); + await mockMetaTransactionsHandlerFacet.deployed(); + + // Define the facet cut + const facetCuts = [ + { + facetAddress: mockMetaTransactionsHandlerFacet.address, + action: FacetCutAction.Add, + functionSelectors: getSelectors(mockMetaTransactionsHandlerFacet), + }, + ]; + + // Send the DiamondCut transaction + const tx = await cutFacetViaDiamond + .connect(deployer) + .diamondCut(facetCuts, ethers.constants.AddressZero, "0x", { gasLimit }); + + // Wait for transaction to confirm + const receipt = await tx.wait(); + + // Be certain transaction was successful + assert.equal(receipt.status, 1, `Diamond upgrade failed: ${tx.hash}`); + + // Cast Diamond to MockMetaTransactionsHandlerFacet + mockMetaTransactionsHandler = await ethers.getContractAt( + "MockMetaTransactionsHandlerFacet", + protocolDiamond.address + ); + } + // Interface support (ERC-156 provided by ProtocolDiamond, others by deployed facets) context("📋 Interfaces", async function () { context("👉 supportsInterface()", async function () { @@ -422,6 +462,45 @@ describe("IBosonMetaTransactionsHandler", function () { assert.equal(result, expectedResult, "Nonce is unused"); }); + it("Should build a new domain separator if cachedChainId does not match with chain id used in signature", async function () { + await upgradeMetaTransactionsHandlerFacet(); + + // update the cached chain id + await mockMetaTransactionsHandler.setCachedChainId(123456); + + // Prepare the function signature for the facet function. + functionSignature = accountHandler.interface.encodeFunctionData("createSeller", [ + seller, + emptyAuthToken, + voucherInitValues, + ]); + + message.functionSignature = functionSignature; + + // Collect the signature components + let { r, s, v } = await prepareDataSignatureParameters( + operator, + customTransactionType, + "MetaTransaction", + message, + metaTransactionsHandler.address + ); + + // send a meta transaction, does not revert + await expect( + metaTransactionsHandler + .connect(deployer) + .executeMetaTransaction(operator.address, message.functionName, functionSignature, nonce, r, s, v) + ) + .to.emit(metaTransactionsHandler, "MetaTransactionExecuted") + .withArgs(operator.address, deployer.address, message.functionName, nonce); + + // Verify that nonce is used. Expect true. + let expectedResult = true; + result = await metaTransactionsHandler.connect(operator).isUsedNonce(nonce); + assert.equal(result, expectedResult, "Nonce is unused"); + }); + it("does not modify revert reasons", async function () { // Set seller as inactive seller.active = false;