Update docs

This commit is contained in:
github-actions
2023-09-19 19:19:10 +00:00
commit dbe796d542
624 changed files with 107720 additions and 0 deletions

View File

@ -0,0 +1,245 @@
require('@openzeppelin/test-helpers');
const { expectRevertCustomError } = require('../../helpers/customError');
const { toEthSignedMessageHash } = require('../../helpers/sign');
const { expect } = require('chai');
const ECDSA = artifacts.require('$ECDSA');
const TEST_MESSAGE = web3.utils.sha3('OpenZeppelin');
const WRONG_MESSAGE = web3.utils.sha3('Nope');
const NON_HASH_MESSAGE = '0x' + Buffer.from('abcd').toString('hex');
function to2098Format(signature) {
const long = web3.utils.hexToBytes(signature);
if (long.length !== 65) {
throw new Error('invalid signature length (expected long format)');
}
if (long[32] >> 7 === 1) {
throw new Error("invalid signature 's' value");
}
const short = long.slice(0, 64);
short[32] |= long[64] % 27 << 7; // set the first bit of the 32nd byte to the v parity bit
return web3.utils.bytesToHex(short);
}
function split(signature) {
const raw = web3.utils.hexToBytes(signature);
switch (raw.length) {
case 64:
return [
web3.utils.bytesToHex(raw.slice(0, 32)), // r
web3.utils.bytesToHex(raw.slice(32, 64)), // vs
];
case 65:
return [
raw[64], // v
web3.utils.bytesToHex(raw.slice(0, 32)), // r
web3.utils.bytesToHex(raw.slice(32, 64)), // s
];
default:
expect.fail('Invalid signature length, cannot split');
}
}
contract('ECDSA', function (accounts) {
const [other] = accounts;
beforeEach(async function () {
this.ecdsa = await ECDSA.new();
});
context('recover with invalid signature', function () {
it('with short signature', async function () {
await expectRevertCustomError(this.ecdsa.$recover(TEST_MESSAGE, '0x1234'), 'ECDSAInvalidSignatureLength', [2]);
});
it('with long signature', async function () {
await expectRevertCustomError(
// eslint-disable-next-line max-len
this.ecdsa.$recover(
TEST_MESSAGE,
'0x01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789',
),
'ECDSAInvalidSignatureLength',
[85],
);
});
});
context('recover with valid signature', function () {
context('using web3.eth.sign', function () {
it('returns signer address with correct signature', async function () {
// Create the signature
const signature = await web3.eth.sign(TEST_MESSAGE, other);
// Recover the signer address from the generated message and signature.
expect(await this.ecdsa.$recover(toEthSignedMessageHash(TEST_MESSAGE), signature)).to.equal(other);
});
it('returns signer address with correct signature for arbitrary length message', async function () {
// Create the signature
const signature = await web3.eth.sign(NON_HASH_MESSAGE, other);
// Recover the signer address from the generated message and signature.
expect(await this.ecdsa.$recover(toEthSignedMessageHash(NON_HASH_MESSAGE), signature)).to.equal(other);
});
it('returns a different address', async function () {
const signature = await web3.eth.sign(TEST_MESSAGE, other);
expect(await this.ecdsa.$recover(WRONG_MESSAGE, signature)).to.not.equal(other);
});
it('reverts with invalid signature', async function () {
// eslint-disable-next-line max-len
const signature =
'0x332ce75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c';
await expectRevertCustomError(this.ecdsa.$recover(TEST_MESSAGE, signature), 'ECDSAInvalidSignature', []);
});
});
context('with v=27 signature', function () {
// Signature generated outside ganache with method web3.eth.sign(signer, message)
const signer = '0x2cc1166f6212628A0deEf2B33BEFB2187D35b86c';
// eslint-disable-next-line max-len
const signatureWithoutV =
'0x5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be892';
it('works with correct v value', async function () {
const v = '1b'; // 27 = 1b.
const signature = signatureWithoutV + v;
expect(await this.ecdsa.$recover(TEST_MESSAGE, signature)).to.equal(signer);
expect(
await this.ecdsa.methods['$recover(bytes32,uint8,bytes32,bytes32)'](TEST_MESSAGE, ...split(signature)),
).to.equal(signer);
expect(
await this.ecdsa.methods['$recover(bytes32,bytes32,bytes32)'](
TEST_MESSAGE,
...split(to2098Format(signature)),
),
).to.equal(signer);
});
it('rejects incorrect v value', async function () {
const v = '1c'; // 28 = 1c.
const signature = signatureWithoutV + v;
expect(await this.ecdsa.$recover(TEST_MESSAGE, signature)).to.not.equal(signer);
expect(
await this.ecdsa.methods['$recover(bytes32,uint8,bytes32,bytes32)'](TEST_MESSAGE, ...split(signature)),
).to.not.equal(signer);
expect(
await this.ecdsa.methods['$recover(bytes32,bytes32,bytes32)'](
TEST_MESSAGE,
...split(to2098Format(signature)),
),
).to.not.equal(signer);
});
it('reverts wrong v values', async function () {
for (const v of ['00', '01']) {
const signature = signatureWithoutV + v;
await expectRevertCustomError(this.ecdsa.$recover(TEST_MESSAGE, signature), 'ECDSAInvalidSignature', []);
await expectRevertCustomError(
this.ecdsa.methods['$recover(bytes32,uint8,bytes32,bytes32)'](TEST_MESSAGE, ...split(signature)),
'ECDSAInvalidSignature',
[],
);
}
});
it('rejects short EIP2098 format', async function () {
const v = '1b'; // 27 = 1b.
const signature = signatureWithoutV + v;
await expectRevertCustomError(
this.ecdsa.$recover(TEST_MESSAGE, to2098Format(signature)),
'ECDSAInvalidSignatureLength',
[64],
);
});
});
context('with v=28 signature', function () {
const signer = '0x1E318623aB09Fe6de3C9b8672098464Aeda9100E';
// eslint-disable-next-line max-len
const signatureWithoutV =
'0x331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e0';
it('works with correct v value', async function () {
const v = '1c'; // 28 = 1c.
const signature = signatureWithoutV + v;
expect(await this.ecdsa.$recover(TEST_MESSAGE, signature)).to.equal(signer);
expect(
await this.ecdsa.methods['$recover(bytes32,uint8,bytes32,bytes32)'](TEST_MESSAGE, ...split(signature)),
).to.equal(signer);
expect(
await this.ecdsa.methods['$recover(bytes32,bytes32,bytes32)'](
TEST_MESSAGE,
...split(to2098Format(signature)),
),
).to.equal(signer);
});
it('rejects incorrect v value', async function () {
const v = '1b'; // 27 = 1b.
const signature = signatureWithoutV + v;
expect(await this.ecdsa.$recover(TEST_MESSAGE, signature)).to.not.equal(signer);
expect(
await this.ecdsa.methods['$recover(bytes32,uint8,bytes32,bytes32)'](TEST_MESSAGE, ...split(signature)),
).to.not.equal(signer);
expect(
await this.ecdsa.methods['$recover(bytes32,bytes32,bytes32)'](
TEST_MESSAGE,
...split(to2098Format(signature)),
),
).to.not.equal(signer);
});
it('reverts invalid v values', async function () {
for (const v of ['00', '01']) {
const signature = signatureWithoutV + v;
await expectRevertCustomError(this.ecdsa.$recover(TEST_MESSAGE, signature), 'ECDSAInvalidSignature', []);
await expectRevertCustomError(
this.ecdsa.methods['$recover(bytes32,uint8,bytes32,bytes32)'](TEST_MESSAGE, ...split(signature)),
'ECDSAInvalidSignature',
[],
);
}
});
it('rejects short EIP2098 format', async function () {
const v = '1c'; // 27 = 1b.
const signature = signatureWithoutV + v;
await expectRevertCustomError(
this.ecdsa.$recover(TEST_MESSAGE, to2098Format(signature)),
'ECDSAInvalidSignatureLength',
[64],
);
});
});
it('reverts with high-s value signature', async function () {
const message = '0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9';
// eslint-disable-next-line max-len
const highSSignature =
'0xe742ff452d41413616a5bf43fe15dd88294e983d3d36206c2712f39083d638bde0a0fc89be718fbc1033e1d30d78be1c68081562ed2e97af876f286f3453231d1b';
const [r, v, s] = split(highSSignature);
await expectRevertCustomError(this.ecdsa.$recover(message, highSSignature), 'ECDSAInvalidSignatureS', [s]);
await expectRevertCustomError(
this.ecdsa.methods['$recover(bytes32,uint8,bytes32,bytes32)'](TEST_MESSAGE, r, v, s),
'ECDSAInvalidSignatureS',
[s],
);
expect(() => to2098Format(highSSignature)).to.throw("invalid signature 's' value");
});
});
});

View File

@ -0,0 +1,111 @@
const ethSigUtil = require('eth-sig-util');
const Wallet = require('ethereumjs-wallet').default;
const { getDomain, domainType, domainSeparator, hashTypedData } = require('../../helpers/eip712');
const { getChainId } = require('../../helpers/chainid');
const { mapValues } = require('../../helpers/iterate');
const EIP712Verifier = artifacts.require('$EIP712Verifier');
const Clones = artifacts.require('$Clones');
contract('EIP712', function (accounts) {
const [mailTo] = accounts;
const shortName = 'A Name';
const shortVersion = '1';
const longName = 'A'.repeat(40);
const longVersion = 'B'.repeat(40);
const cases = [
['short', shortName, shortVersion],
['long', longName, longVersion],
];
for (const [shortOrLong, name, version] of cases) {
describe(`with ${shortOrLong} name and version`, function () {
beforeEach('deploying', async function () {
this.eip712 = await EIP712Verifier.new(name, version);
this.domain = {
name,
version,
chainId: await getChainId(),
verifyingContract: this.eip712.address,
};
this.domainType = domainType(this.domain);
});
describe('domain separator', function () {
it('is internally available', async function () {
const expected = await domainSeparator(this.domain);
expect(await this.eip712.$_domainSeparatorV4()).to.equal(expected);
});
it("can be rebuilt using EIP-5267's eip712Domain", async function () {
const rebuildDomain = await getDomain(this.eip712);
expect(mapValues(rebuildDomain, String)).to.be.deep.equal(mapValues(this.domain, String));
});
if (shortOrLong === 'short') {
// Long strings are in storage, and the proxy will not be properly initialized unless
// the upgradeable contract variant is used and the initializer is invoked.
it('adjusts when behind proxy', async function () {
const factory = await Clones.new();
const cloneReceipt = await factory.$clone(this.eip712.address);
const cloneAddress = cloneReceipt.logs.find(({ event }) => event === 'return$clone').args.instance;
const clone = new EIP712Verifier(cloneAddress);
const cloneDomain = { ...this.domain, verifyingContract: clone.address };
const reportedDomain = await getDomain(clone);
expect(mapValues(reportedDomain, String)).to.be.deep.equal(mapValues(cloneDomain, String));
const expectedSeparator = await domainSeparator(cloneDomain);
expect(await clone.$_domainSeparatorV4()).to.equal(expectedSeparator);
});
}
});
it('hash digest', async function () {
const structhash = web3.utils.randomHex(32);
expect(await this.eip712.$_hashTypedDataV4(structhash)).to.be.equal(hashTypedData(this.domain, structhash));
});
it('digest', async function () {
const message = {
to: mailTo,
contents: 'very interesting',
};
const data = {
types: {
EIP712Domain: this.domainType,
Mail: [
{ name: 'to', type: 'address' },
{ name: 'contents', type: 'string' },
],
},
domain: this.domain,
primaryType: 'Mail',
message,
};
const wallet = Wallet.generate();
const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data });
await this.eip712.verify(signature, wallet.getAddressString(), message.to, message.contents);
});
it('name', async function () {
expect(await this.eip712.$_EIP712Name()).to.be.equal(name);
});
it('version', async function () {
expect(await this.eip712.$_EIP712Version()).to.be.equal(version);
});
});
}
});

View File

@ -0,0 +1,207 @@
const { expectRevert } = require('@openzeppelin/test-helpers');
const { MerkleTree } = require('merkletreejs');
const keccak256 = require('keccak256');
const { expect } = require('chai');
const { expectRevertCustomError } = require('../../helpers/customError');
const MerkleProof = artifacts.require('$MerkleProof');
contract('MerkleProof', function () {
beforeEach(async function () {
this.merkleProof = await MerkleProof.new();
});
describe('verify', function () {
it('returns true for a valid Merkle proof', async function () {
const elements = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split('');
const merkleTree = new MerkleTree(elements, keccak256, { hashLeaves: true, sortPairs: true });
const root = merkleTree.getHexRoot();
const leaf = keccak256(elements[0]);
const proof = merkleTree.getHexProof(leaf);
expect(await this.merkleProof.$verify(proof, root, leaf)).to.equal(true);
expect(await this.merkleProof.$verifyCalldata(proof, root, leaf)).to.equal(true);
// For demonstration, it is also possible to create valid proofs for certain 64-byte values *not* in elements:
const noSuchLeaf = keccak256(
Buffer.concat([keccak256(elements[0]), keccak256(elements[1])].sort(Buffer.compare)),
);
expect(await this.merkleProof.$verify(proof.slice(1), root, noSuchLeaf)).to.equal(true);
expect(await this.merkleProof.$verifyCalldata(proof.slice(1), root, noSuchLeaf)).to.equal(true);
});
it('returns false for an invalid Merkle proof', async function () {
const correctElements = ['a', 'b', 'c'];
const correctMerkleTree = new MerkleTree(correctElements, keccak256, { hashLeaves: true, sortPairs: true });
const correctRoot = correctMerkleTree.getHexRoot();
const correctLeaf = keccak256(correctElements[0]);
const badElements = ['d', 'e', 'f'];
const badMerkleTree = new MerkleTree(badElements);
const badProof = badMerkleTree.getHexProof(badElements[0]);
expect(await this.merkleProof.$verify(badProof, correctRoot, correctLeaf)).to.equal(false);
expect(await this.merkleProof.$verifyCalldata(badProof, correctRoot, correctLeaf)).to.equal(false);
});
it('returns false for a Merkle proof of invalid length', async function () {
const elements = ['a', 'b', 'c'];
const merkleTree = new MerkleTree(elements, keccak256, { hashLeaves: true, sortPairs: true });
const root = merkleTree.getHexRoot();
const leaf = keccak256(elements[0]);
const proof = merkleTree.getHexProof(leaf);
const badProof = proof.slice(0, proof.length - 5);
expect(await this.merkleProof.$verify(badProof, root, leaf)).to.equal(false);
expect(await this.merkleProof.$verifyCalldata(badProof, root, leaf)).to.equal(false);
});
});
describe('multiProofVerify', function () {
it('returns true for a valid Merkle multi proof', async function () {
const leaves = ['a', 'b', 'c', 'd', 'e', 'f'].map(keccak256).sort(Buffer.compare);
const merkleTree = new MerkleTree(leaves, keccak256, { sort: true });
const root = merkleTree.getRoot();
const proofLeaves = ['b', 'f', 'd'].map(keccak256).sort(Buffer.compare);
const proof = merkleTree.getMultiProof(proofLeaves);
const proofFlags = merkleTree.getProofFlags(proofLeaves, proof);
expect(await this.merkleProof.$multiProofVerify(proof, proofFlags, root, proofLeaves)).to.equal(true);
expect(await this.merkleProof.$multiProofVerifyCalldata(proof, proofFlags, root, proofLeaves)).to.equal(true);
});
it('returns false for an invalid Merkle multi proof', async function () {
const leaves = ['a', 'b', 'c', 'd', 'e', 'f'].map(keccak256).sort(Buffer.compare);
const merkleTree = new MerkleTree(leaves, keccak256, { sort: true });
const root = merkleTree.getRoot();
const badProofLeaves = ['g', 'h', 'i'].map(keccak256).sort(Buffer.compare);
const badMerkleTree = new MerkleTree(badProofLeaves);
const badProof = badMerkleTree.getMultiProof(badProofLeaves);
const badProofFlags = badMerkleTree.getProofFlags(badProofLeaves, badProof);
expect(await this.merkleProof.$multiProofVerify(badProof, badProofFlags, root, badProofLeaves)).to.equal(false);
expect(await this.merkleProof.$multiProofVerifyCalldata(badProof, badProofFlags, root, badProofLeaves)).to.equal(
false,
);
});
it('revert with invalid multi proof #1', async function () {
const fill = Buffer.alloc(32); // This could be anything, we are reconstructing a fake branch
const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare);
const badLeaf = keccak256('e');
const merkleTree = new MerkleTree(leaves, keccak256, { sort: true });
const root = merkleTree.getRoot();
await expectRevertCustomError(
this.merkleProof.$multiProofVerify(
[leaves[1], fill, merkleTree.layers[1][1]],
[false, false, false],
root,
[leaves[0], badLeaf], // A, E
),
'MerkleProofInvalidMultiproof',
[],
);
await expectRevertCustomError(
this.merkleProof.$multiProofVerifyCalldata(
[leaves[1], fill, merkleTree.layers[1][1]],
[false, false, false],
root,
[leaves[0], badLeaf], // A, E
),
'MerkleProofInvalidMultiproof',
[],
);
});
it('revert with invalid multi proof #2', async function () {
const fill = Buffer.alloc(32); // This could be anything, we are reconstructing a fake branch
const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare);
const badLeaf = keccak256('e');
const merkleTree = new MerkleTree(leaves, keccak256, { sort: true });
const root = merkleTree.getRoot();
await expectRevert(
this.merkleProof.$multiProofVerify(
[leaves[1], fill, merkleTree.layers[1][1]],
[false, false, false, false],
root,
[badLeaf, leaves[0]], // A, E
),
'reverted with panic code 0x32',
);
await expectRevert(
this.merkleProof.$multiProofVerifyCalldata(
[leaves[1], fill, merkleTree.layers[1][1]],
[false, false, false, false],
root,
[badLeaf, leaves[0]], // A, E
),
'reverted with panic code 0x32',
);
});
it('limit case: works for tree containing a single leaf', async function () {
const leaves = ['a'].map(keccak256).sort(Buffer.compare);
const merkleTree = new MerkleTree(leaves, keccak256, { sort: true });
const root = merkleTree.getRoot();
const proofLeaves = ['a'].map(keccak256).sort(Buffer.compare);
const proof = merkleTree.getMultiProof(proofLeaves);
const proofFlags = merkleTree.getProofFlags(proofLeaves, proof);
expect(await this.merkleProof.$multiProofVerify(proof, proofFlags, root, proofLeaves)).to.equal(true);
expect(await this.merkleProof.$multiProofVerifyCalldata(proof, proofFlags, root, proofLeaves)).to.equal(true);
});
it('limit case: can prove empty leaves', async function () {
const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare);
const merkleTree = new MerkleTree(leaves, keccak256, { sort: true });
const root = merkleTree.getRoot();
expect(await this.merkleProof.$multiProofVerify([root], [], root, [])).to.equal(true);
expect(await this.merkleProof.$multiProofVerifyCalldata([root], [], root, [])).to.equal(true);
});
it('reverts processing manipulated proofs with a zero-value node at depth 1', async function () {
// Create a merkle tree that contains a zero leaf at depth 1
const leaves = [keccak256('real leaf'), Buffer.alloc(32, 0)];
const merkleTree = new MerkleTree(leaves, keccak256, { sortPairs: true });
const root = merkleTree.getRoot();
// Now we can pass any **malicious** fake leaves as valid!
const maliciousLeaves = ['malicious', 'leaves'].map(keccak256).sort(Buffer.compare);
const maliciousProof = [leaves[0], leaves[0]];
const maliciousProofFlags = [true, true, false];
await expectRevertCustomError(
this.merkleProof.$multiProofVerify(maliciousProof, maliciousProofFlags, root, maliciousLeaves),
'MerkleProofInvalidMultiproof',
[],
);
await expectRevertCustomError(
this.merkleProof.$multiProofVerifyCalldata(maliciousProof, maliciousProofFlags, root, maliciousLeaves),
'MerkleProofInvalidMultiproof',
[],
);
});
});
});

View File

@ -0,0 +1,55 @@
require('@openzeppelin/test-helpers');
const { toEthSignedMessageHash, toDataWithIntendedValidatorHash } = require('../../helpers/sign');
const { domainSeparator, hashTypedData } = require('../../helpers/eip712');
const { expect } = require('chai');
const MessageHashUtils = artifacts.require('$MessageHashUtils');
contract('MessageHashUtils', function () {
beforeEach(async function () {
this.messageHashUtils = await MessageHashUtils.new();
this.message = '0x' + Buffer.from('abcd').toString('hex');
this.messageHash = web3.utils.sha3(this.message);
this.verifyingAddress = web3.utils.toChecksumAddress(web3.utils.randomHex(20));
});
context('toEthSignedMessageHash', function () {
it('prefixes bytes32 data correctly', async function () {
expect(await this.messageHashUtils.methods['$toEthSignedMessageHash(bytes32)'](this.messageHash)).to.equal(
toEthSignedMessageHash(this.messageHash),
);
});
it('prefixes dynamic length data correctly', async function () {
expect(await this.messageHashUtils.methods['$toEthSignedMessageHash(bytes)'](this.message)).to.equal(
toEthSignedMessageHash(this.message),
);
});
});
context('toDataWithIntendedValidatorHash', function () {
it('returns the digest correctly', async function () {
expect(
await this.messageHashUtils.$toDataWithIntendedValidatorHash(this.verifyingAddress, this.message),
).to.equal(toDataWithIntendedValidatorHash(this.verifyingAddress, this.message));
});
});
context('toTypedDataHash', function () {
it('returns the digest correctly', async function () {
const domain = {
name: 'Test',
version: 1,
chainId: 1,
verifyingContract: this.verifyingAddress,
};
const structhash = web3.utils.randomHex(32);
const expectedDomainSeparator = await domainSeparator(domain);
expect(await this.messageHashUtils.$toTypedDataHash(expectedDomainSeparator, structhash)).to.equal(
hashTypedData(domain, structhash),
);
});
});
});

View File

@ -0,0 +1,87 @@
const { toEthSignedMessageHash } = require('../../helpers/sign');
const { expect } = require('chai');
const SignatureChecker = artifacts.require('$SignatureChecker');
const ERC1271WalletMock = artifacts.require('ERC1271WalletMock');
const ERC1271MaliciousMock = artifacts.require('ERC1271MaliciousMock');
const TEST_MESSAGE = web3.utils.sha3('OpenZeppelin');
const WRONG_MESSAGE = web3.utils.sha3('Nope');
contract('SignatureChecker (ERC1271)', function (accounts) {
const [signer, other] = accounts;
before('deploying', async function () {
this.signaturechecker = await SignatureChecker.new();
this.wallet = await ERC1271WalletMock.new(signer);
this.malicious = await ERC1271MaliciousMock.new();
this.signature = await web3.eth.sign(TEST_MESSAGE, signer);
});
context('EOA account', function () {
it('with matching signer and signature', async function () {
expect(
await this.signaturechecker.$isValidSignatureNow(signer, toEthSignedMessageHash(TEST_MESSAGE), this.signature),
).to.equal(true);
});
it('with invalid signer', async function () {
expect(
await this.signaturechecker.$isValidSignatureNow(other, toEthSignedMessageHash(TEST_MESSAGE), this.signature),
).to.equal(false);
});
it('with invalid signature', async function () {
expect(
await this.signaturechecker.$isValidSignatureNow(signer, toEthSignedMessageHash(WRONG_MESSAGE), this.signature),
).to.equal(false);
});
});
context('ERC1271 wallet', function () {
for (const signature of ['isValidERC1271SignatureNow', 'isValidSignatureNow']) {
context(signature, function () {
it('with matching signer and signature', async function () {
expect(
await this.signaturechecker[`$${signature}`](
this.wallet.address,
toEthSignedMessageHash(TEST_MESSAGE),
this.signature,
),
).to.equal(true);
});
it('with invalid signer', async function () {
expect(
await this.signaturechecker[`$${signature}`](
this.signaturechecker.address,
toEthSignedMessageHash(TEST_MESSAGE),
this.signature,
),
).to.equal(false);
});
it('with invalid signature', async function () {
expect(
await this.signaturechecker[`$${signature}`](
this.wallet.address,
toEthSignedMessageHash(WRONG_MESSAGE),
this.signature,
),
).to.equal(false);
});
it('with malicious wallet', async function () {
expect(
await this.signaturechecker[`$${signature}`](
this.malicious.address,
toEthSignedMessageHash(TEST_MESSAGE),
this.signature,
),
).to.equal(false);
});
});
}
});
});