From e0551e3151ff4b804b4f196d4219fd650966fed9 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Thu, 29 Sep 2022 18:05:40 +0400 Subject: [PATCH] format --- .eslintrc | 9 +- .prettierrc | 2 +- hardhat.networks.ts | 49 +- src/asserts.ts | 8 +- src/permit.ts | 78 +- src/prelude.ts | 21 +- src/profileEVM.ts | 90 +- src/utils.ts | 36 +- test/Permitable.test.ts | 91 ++- test/contracts/AddressArray.test.ts | 6 +- test/contracts/ECDSA.test.ts | 946 ++++++++++++++++++---- test/contracts/EthReceiver.test.ts | 12 +- test/contracts/RevertReasonParser.test.ts | 7 +- test/contracts/SafestERC20.test.ts | 55 +- test/contracts/StringUtil.test.ts | 32 +- test/contracts/UniERC20.test.ts | 50 +- test/contracts/WethReceiver.test.ts | 12 +- test/permit.test.ts | 13 +- test/profileEVM.test.ts | 60 +- test/utils.test.ts | 62 +- 20 files changed, 1183 insertions(+), 456 deletions(-) diff --git a/.eslintrc b/.eslintrc index 7378ae02..816db13d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -35,7 +35,8 @@ ], "quotes": [ 2, - "single" + "single", + {"avoidEscape": true} ], "semi": [ "error", @@ -43,16 +44,12 @@ ], "space-before-function-paren": [ "error", - "always" + {"anonymous": "always", "named": "never", "asyncArrow": "always"} ], "one-var-declaration-per-line": [ "error", "always" ], - "function-paren-newline": [ - "error", - "multiline" - ], "object-property-newline": [ "error", { "allowAllPropertiesOnSameLine": true } diff --git a/.prettierrc b/.prettierrc index 675f475d..8fb5c742 100644 --- a/.prettierrc +++ b/.prettierrc @@ -7,7 +7,7 @@ } }, { - "files": "*.js", + "files": "*.ts", "options": { "printWidth": 120, "singleQuote": true, diff --git a/hardhat.networks.ts b/hardhat.networks.ts index c31966ef..99d4ad42 100644 --- a/hardhat.networks.ts +++ b/hardhat.networks.ts @@ -5,12 +5,7 @@ dotenv.config(); const networks: NetworksUserConfig = {}; -function register ( - name: string, - chainId: number, - url?: string, - privateKey?: string -) { +function register(name: string, chainId: number, url?: string, privateKey?: string) { if (url && privateKey) { networks[name] = { url, @@ -23,44 +18,14 @@ function register ( } } -register( - 'mainnet', - 1, - process.env.MAINNET_RPC_URL, - process.env.MAINNET_PRIVATE_KEY -); +register('mainnet', 1, process.env.MAINNET_RPC_URL, process.env.MAINNET_PRIVATE_KEY); register('bsc', 56, process.env.BSC_RPC_URL, process.env.BSC_PRIVATE_KEY); register('kovan', 42, process.env.KOVAN_RPC_URL, process.env.KOVAN_PRIVATE_KEY); -register( - 'optimistic', - 10, - process.env.OPTIMISTIC_RPC_URL, - process.env.OPTIMISTIC_PRIVATE_KEY -); -register( - 'kovan-optimistic', - 69, - process.env.KOVAN_OPTIMISTIC_RPC_URL, - process.env.KOVAN_OPTIMISTIC_PRIVATE_KEY -); -register( - 'matic', - 137, - process.env.MATIC_RPC_URL, - process.env.MATIC_PRIVATE_KEY -); -register( - 'arbitrum', - 42161, - process.env.ARBITRUM_RPC_URL, - process.env.ARBITRUM_PRIVATE_KEY -); -register( - 'ropsten', - 3, - process.env.ROPSTEN_RPC_URL, - process.env.ROPSTEN_PRIVATE_KEY -); +register('optimistic', 10, process.env.OPTIMISTIC_RPC_URL, process.env.OPTIMISTIC_PRIVATE_KEY); +register('kovan-optimistic', 69, process.env.KOVAN_OPTIMISTIC_RPC_URL, process.env.KOVAN_OPTIMISTIC_PRIVATE_KEY); +register('matic', 137, process.env.MATIC_RPC_URL, process.env.MATIC_PRIVATE_KEY); +register('arbitrum', 42161, process.env.ARBITRUM_RPC_URL, process.env.ARBITRUM_PRIVATE_KEY); +register('ropsten', 3, process.env.ROPSTEN_RPC_URL, process.env.ROPSTEN_PRIVATE_KEY); register('xdai', 100, process.env.XDAI_RPC_URL, process.env.XDAI_PRIVATE_KEY); register('avax', 43114, process.env.AVAX_RPC_URL, process.env.AVAX_PRIVATE_KEY); diff --git a/src/asserts.ts b/src/asserts.ts index afd23c1b..1f05afe3 100644 --- a/src/asserts.ts +++ b/src/asserts.ts @@ -1,6 +1,10 @@ import { expect } from './prelude'; -export function assertRoughlyEqualValues (expected: string | number | bigint, actual: string | number | bigint, relativeDiff: number) { +export function assertRoughlyEqualValues( + expected: string | number | bigint, + actual: string | number | bigint, + relativeDiff: number, +) { let expectedBN = BigInt(expected); let actualBN = BigInt(actual); expect(expectedBN * actualBN).to.be.gte(0, 'Values are of different sign'); @@ -15,7 +19,7 @@ export function assertRoughlyEqualValues (expected: string | number | bigint, ac multiplerNumerator *= 10; } const diff = expectedBN > actualBN ? expectedBN - actualBN : actualBN - expectedBN; - const treshold = expectedBN * BigInt(multiplerNumerator) / multiplerDenominator; + const treshold = (expectedBN * BigInt(multiplerNumerator)) / multiplerDenominator; if (diff > treshold) { expect(actualBN).to.be.equal(expectedBN, `${actual} != ${expected} with ${relativeDiff} precision`); } diff --git a/src/permit.ts b/src/permit.ts index b5b3eb3b..d8cf7752 100644 --- a/src/permit.ts +++ b/src/permit.ts @@ -31,7 +31,7 @@ export const DaiLikePermit = [ { name: 'allowed', type: 'bool' }, ]; -export function trim0x (bigNumber: bigint | string) { +export function trim0x(bigNumber: bigint | string) { const s = bigNumber.toString(); if (s.startsWith('0x')) { return s.substring(2); @@ -39,21 +39,24 @@ export function trim0x (bigNumber: bigint | string) { return s; } -export function cutSelector (data: string) { +export function cutSelector(data: string) { const hexPrefix = '0x'; return hexPrefix + data.substr(hexPrefix.length + 8); } -export function domainSeparator (name: string, version: string, chainId: string, verifyingContract: string) { - return '0x' + TypedDataUtils.hashStruct( - 'EIP712Domain', - { name, version, chainId, verifyingContract }, - { EIP712Domain }, - TypedDataVersion - ).toString('hex'); +export function domainSeparator(name: string, version: string, chainId: string, verifyingContract: string) { + return ( + '0x' + + TypedDataUtils.hashStruct( + 'EIP712Domain', + { name, version, chainId, verifyingContract }, + { EIP712Domain }, + TypedDataVersion, + ).toString('hex') + ); } -export function buildData ( +export function buildData( name: string, version: string, chainId: number, @@ -62,7 +65,7 @@ export function buildData ( spender: string, value: string, nonce: string, - deadline: string = defaultDeadline.toString() + deadline: string = defaultDeadline.toString(), ) { return { types: { Permit }, @@ -71,7 +74,7 @@ export function buildData ( } as const; } -export function buildDataLikeDai ( +export function buildDataLikeDai( name: string, version: string, chainId: number, @@ -80,7 +83,7 @@ export function buildDataLikeDai ( spender: string, nonce: string, allowed: boolean, - expiry: string = defaultDeadline.toString() + expiry: string = defaultDeadline.toString(), ) { return { types: { Permit: DaiLikePermit }, @@ -97,45 +100,76 @@ export interface PermittableToken extends Token { /* * @param permitContract The contract object with ERC20Permit type and token address for which the permit creating. */ -export async function getPermit ( +export async function getPermit( owner: SignerWithAddress, permitContract: PermittableToken, tokenVersion: string, chainId: number, spender: string, value: string, - deadline = defaultDeadline.toString() + deadline = defaultDeadline.toString(), ) { const nonce = await permitContract.nonces(owner.address); const name = await permitContract.name(); - const data = buildData(name, tokenVersion, chainId, permitContract.address, owner.address, spender, value, nonce.toString(), deadline); + const data = buildData( + name, + tokenVersion, + chainId, + permitContract.address, + owner.address, + spender, + value, + nonce.toString(), + deadline, + ); const signature = await owner._signTypedData(data.domain, data.types, data.message); const { v, r, s } = fromRpcSig(signature); - const permitCall = permitContract.interface.encodeFunctionData('permit', [owner.address, spender, value, deadline, v, r, s]); + const permitCall = permitContract.interface.encodeFunctionData('permit', [ + owner.address, + spender, + value, + deadline, + v, + r, + s, + ]); return cutSelector(permitCall); } /* * @param permitContract The contract object with ERC20PermitLikeDai type and token address for which the permit creating. */ -export async function getPermitLikeDai ( +export async function getPermitLikeDai( holder: SignerWithAddress, permitContract: PermittableToken, tokenVersion: string, chainId: number, spender: string, allowed: boolean, - expiry = defaultDeadline.toString() + expiry = defaultDeadline.toString(), ) { const nonce = await permitContract.nonces(holder.address); const name = await permitContract.name(); - const data = buildDataLikeDai(name, tokenVersion, chainId, permitContract.address, holder.address, spender, nonce.toString(), allowed, expiry); + const data = buildDataLikeDai( + name, + tokenVersion, + chainId, + permitContract.address, + holder.address, + spender, + nonce.toString(), + allowed, + expiry, + ); const signature = await holder._signTypedData(data.domain, data.types, data.message); const { v, r, s } = fromRpcSig(signature); - const permitCall = permitContract.interface.encodeFunctionData('permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)', [holder.address, spender, nonce, expiry, allowed, v, r, s]); + const permitCall = permitContract.interface.encodeFunctionData( + 'permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)', + [holder.address, spender, nonce, expiry, allowed, v, r, s], + ); return cutSelector(permitCall); } -export function withTarget (target: bigint | string, data: bigint | string) { +export function withTarget(target: bigint | string, data: bigint | string) { return target.toString() + trim0x(data); } diff --git a/src/prelude.ts b/src/prelude.ts index 68567449..4a82b45e 100644 --- a/src/prelude.ts +++ b/src/prelude.ts @@ -6,27 +6,18 @@ export const constants = { ZERO_ADDRESS: '0x0000000000000000000000000000000000000000', EEE_ADDRESS: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', ZERO_BYTES32: '0x0000000000000000000000000000000000000000000000000000000000000000', - MAX_UINT256: (2n ** 256n) - 1n, - MAX_INT256: (2n ** 255n) - 1n, + MAX_UINT256: 2n ** 256n - 1n, + MAX_INT256: 2n ** 255n - 1n, MIN_INT256: -(2n ** 255n), - MAX_UINT128: (2n ** 128n) - 1n, + MAX_UINT128: 2n ** 128n - 1n, } as const; // utils -export { - time, -}; +export { time }; -export function ether (n: string): bigint { +export function ether(n: string): bigint { return BigInt(toWei(n, 'ether')); } // chai -export { - Assertion, - AssertionError, - assert, - expect, - config, - should, -}; +export { Assertion, AssertionError, assert, expect, config, should }; diff --git a/src/profileEVM.ts b/src/profileEVM.ts index 408aa41b..d086d421 100644 --- a/src/profileEVM.ts +++ b/src/profileEVM.ts @@ -8,32 +8,41 @@ export const gasspectOptionsDefault = { }; type Op = { - traceAddress: number[], - depth: number, - gasCost: number, - args?: unknown[], - res: unknown, - op: string, - gas: number - stack: string[], - memory: string[] + traceAddress: number[]; + depth: number; + gasCost: number; + args?: unknown[]; + res: unknown; + op: string; + gas: number; + stack: string[]; + memory: string[]; }; -function _normalizeOp (ops: Op[], i: number) { +function _normalizeOp(ops: Op[], i: number) { if (ops[i].op === 'STATICCALL') { ops[i].gasCost = ops[i].gasCost - ops[i + 1].gas; - if (ops[i].stack.length > 8 && ops[i].stack[ops[i].stack.length - 8] === '0000000000000000000000000000000000000000000000000000000000000001') { + if ( + ops[i].stack.length > 8 && + ops[i].stack[ops[i].stack.length - 8] === '0000000000000000000000000000000000000000000000000000000000000001' + ) { ops[i].op = 'STATICCALL-ECRECOVER'; - } else if (ops[i].stack.length > 8 && ops[i].stack[ops[i].stack.length - 8] <= '00000000000000000000000000000000000000000000000000000000000000FF') { + } else if ( + ops[i].stack.length > 8 && + ops[i].stack[ops[i].stack.length - 8] <= '00000000000000000000000000000000000000000000000000000000000000FF' + ) { ops[i].op = 'STATICCALL-' + ops[i].stack[ops[i].stack.length - 8].substr(62, 2); } else { ops[i].args = [ '0x' + ops[i].stack[ops[i].stack.length - 2].substring(24), - '0x' + (ops[i].memory || []).join('').substr( - 2 * Number(ops[i].stack[ops[i].stack.length - 3]), - 2 * Number(ops[i].stack[ops[i].stack.length - 4]), - ), + '0x' + + (ops[i].memory || []) + .join('') + .substr( + 2 * Number(ops[i].stack[ops[i].stack.length - 3]), + 2 * Number(ops[i].stack[ops[i].stack.length - 4]), + ), ]; if (ops[i].gasCost === 100) { ops[i].op += '_R'; @@ -43,10 +52,13 @@ function _normalizeOp (ops: Op[], i: number) { if (['CALL', 'DELEGATECALL', 'CALLCODE'].indexOf(ops[i].op) !== -1) { ops[i].args = [ '0x' + ops[i].stack[ops[i].stack.length - 2].substring(24), - '0x' + (ops[i].memory || []).join('').substr( - 2 * Number(ops[i].stack[ops[i].stack.length - 4]), - 2 * Number(ops[i].stack[ops[i].stack.length - 5]), - ), + '0x' + + (ops[i].memory || []) + .join('') + .substr( + 2 * Number(ops[i].stack[ops[i].stack.length - 4]), + 2 * Number(ops[i].stack[ops[i].stack.length - 5]), + ), ]; ops[i].gasCost = ops[i].gasCost - ops[i + 1].gas; ops[i].res = ops[i + 1].stack[ops[i + 1].stack.length - 1]; @@ -59,9 +71,7 @@ function _normalizeOp (ops: Op[], i: number) { ops[i].gasCost = 3; } if (['SSTORE', 'SLOAD'].indexOf(ops[i].op) !== -1) { - ops[i].args = [ - '0x' + ops[i].stack[ops[i].stack.length - 1], - ]; + ops[i].args = ['0x' + ops[i].stack[ops[i].stack.length - 1]]; if (ops[i].op === 'SSTORE') { ops[i].args!.push('0x' + ops[i].stack[ops[i].stack.length - 2]); } @@ -77,15 +87,13 @@ function _normalizeOp (ops: Op[], i: number) { } } if (ops[i].op === 'EXTCODESIZE') { - ops[i].args = [ - '0x' + ops[i].stack[ops[i].stack.length - 1].substring(24), - ]; + ops[i].args = ['0x' + ops[i].stack[ops[i].stack.length - 1].substring(24)]; ops[i].res = ops[i + 1].stack[ops[i + 1].stack.length - 1]; } } -export async function profileEVM (txHash: string, instruction: string[], optionalTraceFile?: PathLike | fs.FileHandle) { - const trace = await ethers.provider.send('debug_traceTransaction', [ txHash ]); +export async function profileEVM(txHash: string, instruction: string[], optionalTraceFile?: PathLike | fs.FileHandle) { + const trace = await ethers.provider.send('debug_traceTransaction', [txHash]); const str = JSON.stringify(trace); @@ -93,15 +101,19 @@ export async function profileEVM (txHash: string, instruction: string[], optiona await fs.writeFile(optionalTraceFile, str); } - return instruction.map(instr => { + return instruction.map((instr) => { return str.split('"' + instr.toUpperCase() + '"').length - 1; }); } -export async function gasspectEVM (txHash: string, gasspectOptions: Record = {}, optionalTraceFile?: PathLike | fs.FileHandle) { +export async function gasspectEVM( + txHash: string, + gasspectOptions: Record = {}, + optionalTraceFile?: PathLike | fs.FileHandle, +) { const options = { ...gasspectOptionsDefault, ...gasspectOptions }; - const trace = await ethers.provider.send('debug_traceTransaction', [ txHash ]); + const trace = await ethers.provider.send('debug_traceTransaction', [txHash]); const ops: Op[] = trace.structLogs; @@ -120,10 +132,18 @@ export async function gasspectEVM (txHash: string, gasspectOptions: Record op.gasCost > options.minOpGasCost).map(op => op.traceAddress.join('-') + '-' + op.op + - (options.args ? '(' + (op.args || []).join(',') + ')' : '') + - (options.res ? (op.res ? ':0x' + op.res : '') : '') + - ' = ' + op.gasCost); + const result = ops + .filter((op) => op.gasCost > options.minOpGasCost) + .map( + (op) => + op.traceAddress.join('-') + + '-' + + op.op + + (options.args ? '(' + (op.args || []).join(',') + ')' : '') + + (options.res ? (op.res ? ':0x' + op.res : '') : '') + + ' = ' + + op.gasCost, + ); if (optionalTraceFile) { await fs.writeFile(optionalTraceFile, JSON.stringify(trace)); diff --git a/src/utils.ts b/src/utils.ts index dbaabe3f..e87f00b4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,40 +4,38 @@ import { ethers } from 'hardhat'; import { BaseContract, BigNumber, Bytes, CallOverrides, ContractTransaction } from 'ethers'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -export async function timeIncreaseTo (seconds: number | string) { +export async function timeIncreaseTo(seconds: number | string) { const delay = 1000 - new Date().getMilliseconds(); - await new Promise(resolve => setTimeout(resolve, delay)); + await new Promise((resolve) => setTimeout(resolve, delay)); await time.increaseTo(seconds); } export interface Token extends BaseContract { - balanceOf( - account: string, - overrides?: CallOverrides - ): Promise; + balanceOf(account: string, overrides?: CallOverrides): Promise; } -export async function trackReceivedTokenAndTx ( - token: Token | {address: typeof constants.ZERO_ADDRESS} | {address: typeof constants.EEE_ADDRESS}, +export async function trackReceivedTokenAndTx( + token: Token | { address: typeof constants.ZERO_ADDRESS } | { address: typeof constants.EEE_ADDRESS }, wallet: string, txPromise: (...args: T) => Promise, ...args: T ) { const [balanceFunc, isETH] = - 'balanceOf' in token - ? [() => token.balanceOf(wallet), false] - : [async () => (await ethers.provider.getBalance(wallet)), true]; + 'balanceOf' in token + ? [() => token.balanceOf(wallet), false] + : [async () => await ethers.provider.getBalance(wallet), true]; const preBalance = await balanceFunc(); const txResult = await txPromise(...args); const txReceipt = await txResult.wait(); - const txFees = (wallet.toLowerCase() === txResult.from.toLowerCase() && isETH) - ? txReceipt.gasUsed.toBigInt() * txReceipt.effectiveGasPrice.toBigInt() - : 0n; + const txFees = + wallet.toLowerCase() === txResult.from.toLowerCase() && isETH + ? txReceipt.gasUsed.toBigInt() * txReceipt.effectiveGasPrice.toBigInt() + : 0n; const postBalance = await balanceFunc(); return [postBalance.sub(preBalance).add(txFees), txResult] as const; } -export function fixSignature (signature: string) { +export function fixSignature(signature: string) { // in geth its always 27/28, in ganache its 0/1. Change to 27/28 to prevent // signature malleability if version is 0/1 // see https://github.com/ethereum/go-ethereum/blob/v1.8.23/internal/ethapi/api.go#L465 @@ -49,16 +47,16 @@ export function fixSignature (signature: string) { return signature.slice(0, 130) + vHex; } -export async function signMessage (signer: SignerWithAddress, messageHex: string | Bytes = '0x') { +export async function signMessage(signer: SignerWithAddress, messageHex: string | Bytes = '0x') { return fixSignature(await signer.signMessage(messageHex)); } -export async function countInstructions (txHash: string, instructions: string[]) { - const trace = await ethers.provider.send('debug_traceTransaction', [ txHash ]); +export async function countInstructions(txHash: string, instructions: string[]) { + const trace = await ethers.provider.send('debug_traceTransaction', [txHash]); const str = JSON.stringify(trace); - return instructions.map(instr => { + return instructions.map((instr) => { return str.split('"' + instr.toUpperCase() + '"').length - 1; }); } diff --git a/test/Permitable.test.ts b/test/Permitable.test.ts index c4d7a10b..2773d02a 100644 --- a/test/Permitable.test.ts +++ b/test/Permitable.test.ts @@ -17,7 +17,7 @@ describe('Permitable', async function () { [signer1, signer2] = await ethers.getSigners(); }); - async function deployTokens () { + async function deployTokens() { const PermitableMock = await ethers.getContractFactory('PermitableMock'); const ERC20PermitMock = await ethers.getContractFactory('ERC20PermitMock'); const DaiLikePermitMock = await ethers.getContractFactory('DaiLikePermitMock'); @@ -43,13 +43,33 @@ describe('Permitable', async function () { const name = await erc20PermitMock.name(); const nonce = await erc20PermitMock.nonces(signer1.address); - const data = buildData(name, '1', chainId, erc20PermitMock.address, signer1.address, signer2.address, value.toString(), nonce.toString()); + const data = buildData( + name, + '1', + chainId, + erc20PermitMock.address, + signer1.address, + signer2.address, + value.toString(), + nonce.toString(), + ); const signature = await signer1._signTypedData(data.domain, data.types, data.message); const { v, r, s } = fromRpcSig(signature); // spender is signer1 but in signature spender was signer2 - const permit = cutSelector(erc20PermitMock.interface.encodeFunctionData('permit', [signer1.address, signer1.address, value, defaultDeadline, v, r, s])); - await expect(permitableMock.mockPermit(erc20PermitMock.address, permit)) - .to.be.revertedWith('ERC20Permit: invalid signature'); + const permit = cutSelector( + erc20PermitMock.interface.encodeFunctionData('permit', [ + signer1.address, + signer1.address, + value, + defaultDeadline, + v, + r, + s, + ]), + ); + await expect(permitableMock.mockPermit(erc20PermitMock.address, permit)).to.be.revertedWith( + 'ERC20Permit: invalid signature', + ); }); it('should be permitted for IDaiLikePermit', async function () { @@ -67,18 +87,30 @@ describe('Permitable', async function () { const name = await daiLikePermitMock.name(); const nonce = await daiLikePermitMock.nonces(signer1.address); - const data = buildDataLikeDai(name, '1', chainId, daiLikePermitMock.address, signer1.address, signer2.address, nonce.toString(), true); + const data = buildDataLikeDai( + name, + '1', + chainId, + daiLikePermitMock.address, + signer1.address, + signer2.address, + nonce.toString(), + true, + ); const signature = await signer1._signTypedData(data.domain, data.types, data.message); const { v, r, s } = fromRpcSig(signature); // spender is signer1 but in signature spender was signer2 - const permit = cutSelector(daiLikePermitMock.interface.encodeFunctionData( - 'permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)', - [signer1.address, signer1.address, nonce, defaultDeadline.toString(), true, v, r, s] - )); - - await expect(permitableMock.mockPermit(daiLikePermitMock.address, permit)) - .to.be.revertedWith('Dai/invalid-permit'); + const permit = cutSelector( + daiLikePermitMock.interface.encodeFunctionData( + 'permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)', + [signer1.address, signer1.address, nonce, defaultDeadline.toString(), true, v, r, s], + ), + ); + + await expect(permitableMock.mockPermit(daiLikePermitMock.address, permit)).to.be.revertedWith( + 'Dai/invalid-permit', + ); }); it('should be wrong permit length', async function () { @@ -86,13 +118,36 @@ describe('Permitable', async function () { const name = await erc20PermitMock.name(); const nonce = await erc20PermitMock.nonces(signer1.address); - const data = buildData(name, '1', chainId, erc20PermitMock.address, signer1.address, signer2.address, value.toString(), nonce.toString()); + const data = buildData( + name, + '1', + chainId, + erc20PermitMock.address, + signer1.address, + signer2.address, + value.toString(), + nonce.toString(), + ); const signature = await signer1._signTypedData(data.domain, data.types, data.message); const { v, r, s } = fromRpcSig(signature); - const permit = '0x' + cutSelector(erc20PermitMock.interface.encodeFunctionData('permit', [signer1.address, signer1.address, value, defaultDeadline, v, r, s])).substring(64); - - await expect(permitableMock.mockPermit(erc20PermitMock.address, permit)) - .to.be.revertedWithCustomError(permitableMock, 'SafePermitBadLength'); + const permit = + '0x' + + cutSelector( + erc20PermitMock.interface.encodeFunctionData('permit', [ + signer1.address, + signer1.address, + value, + defaultDeadline, + v, + r, + s, + ]), + ).substring(64); + + await expect(permitableMock.mockPermit(erc20PermitMock.address, permit)).to.be.revertedWithCustomError( + permitableMock, + 'SafePermitBadLength', + ); }); }); diff --git a/test/contracts/AddressArray.test.ts b/test/contracts/AddressArray.test.ts index 8feece96..167e2212 100644 --- a/test/contracts/AddressArray.test.ts +++ b/test/contracts/AddressArray.test.ts @@ -149,8 +149,10 @@ describe('AddressArray', async function () { describe('set', async function () { it('should throw when sets index out of bounds', async function () { const { addressArrayMock } = await loadFixture(deployAddressArrayMock); - await expect(addressArrayMock.set(0, signer1.address)) - .to.be.revertedWithCustomError(addressArrayMock, 'IndexOutOfBounds'); + await expect(addressArrayMock.set(0, signer1.address)).to.be.revertedWithCustomError( + addressArrayMock, + 'IndexOutOfBounds', + ); }); it('should set index 0 in array with 1 element', async function () { diff --git a/test/contracts/ECDSA.test.ts b/test/contracts/ECDSA.test.ts index 2058f09d..28d7c765 100644 --- a/test/contracts/ECDSA.test.ts +++ b/test/contracts/ECDSA.test.ts @@ -52,17 +52,21 @@ describe('ECDSA', async function () { }; // eslint-disable-next-line max-len - const longSignature = '0x01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'; + const longSignature = + '0x01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'; // Signature generated outside ganache const signerV0 = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8'; // eslint-disable-next-line max-len - const signatureWithoutVersionV0 = '0x064d3d0f049cc3b971476ba4bdbd5d0ccb5ac0ee7a03c2f063908ac2bdb59f944c7c5bf43804a7ff717f8c0a8749e0e5cb26ef96408313558acd130210604d9c'; + const signatureWithoutVersionV0 = + '0x064d3d0f049cc3b971476ba4bdbd5d0ccb5ac0ee7a03c2f063908ac2bdb59f944c7c5bf43804a7ff717f8c0a8749e0e5cb26ef96408313558acd130210604d9c'; const signerV1 = '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC'; // eslint-disable-next-line max-len - const signatureWithoutVersionV1 = '0x7bf43cd41b0fe2edad48ab66d2bc8e78d4aad37d0cf77e9fa4668560e1eac68277c325f777b8ee2f9d522c635c252bfdba6ba261edbf53c46c64d47824f2a009'; + const signatureWithoutVersionV1 = + '0x7bf43cd41b0fe2edad48ab66d2bc8e78d4aad37d0cf77e9fa4668560e1eac68277c325f777b8ee2f9d522c635c252bfdba6ba261edbf53c46c64d47824f2a009'; // eslint-disable-next-line max-len - const invalidSignature = '0x332ce75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c'; + const invalidSignature = + '0x332ce75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c'; describe('recover', async () => { describe('with invalid signature', async () => { @@ -88,7 +92,9 @@ describe('ECDSA', async function () { it('returns signer address with correct signature for arbitrary length message', async () => { const { ecdsa } = await loadFixture(deployContracts); const signature = await account.signMessage(NON_HASH_MESSAGE); - expect(await ecdsa.recover(ethers.utils.hashMessage(NON_HASH_MESSAGE), signature)).to.be.equals(account.address); + expect(await ecdsa.recover(ethers.utils.hashMessage(NON_HASH_MESSAGE), signature)).to.be.equals( + account.address, + ); }); it('returns a different address', async () => { @@ -99,7 +105,9 @@ describe('ECDSA', async function () { it('returns zero address with invalid signature', async () => { const { ecdsa } = await loadFixture(deployContracts); - expect(await ecdsa.recover(HASHED_TEST_MESSAGE, invalidSignature)).to.be.equals(constants.ZERO_ADDRESS); + expect(await ecdsa.recover(HASHED_TEST_MESSAGE, invalidSignature)).to.be.equals( + constants.ZERO_ADDRESS, + ); }); }); @@ -110,7 +118,9 @@ describe('ECDSA', async function () { const signature = signatureWithoutVersionV0 + version; expect(await ecdsa.recover(HASHED_TEST_MESSAGE, signature)).to.be.equals(constants.ZERO_ADDRESS); const [, r, s] = split3(signature); - expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, 0, r, s)).to.be.equals(constants.ZERO_ADDRESS); + expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, 0, r, s)).to.be.equals( + constants.ZERO_ADDRESS, + ); }); it('works with 27 as version value', async function () { @@ -119,16 +129,22 @@ describe('ECDSA', async function () { const signature = signatureWithoutVersionV0 + version; expect(await ecdsa.recover(HASHED_TEST_MESSAGE, signature)).to.be.equals(signerV0); expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(signerV0); - expect(await ecdsa.recover_r_vs(HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(signerV0); + expect(await ecdsa.recover_r_vs(HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal( + signerV0, + ); }); it('returns zero address when wrong version', async function () { const { ecdsa } = await loadFixture(deployContracts); // The last two hex digits are the signature version. // The only valid values are 0, 1, 27 and 28. - expect(await ecdsa.recover(HASHED_TEST_MESSAGE, signatureWithoutVersionV0 + '02')).to.be.equals(constants.ZERO_ADDRESS); + expect(await ecdsa.recover(HASHED_TEST_MESSAGE, signatureWithoutVersionV0 + '02')).to.be.equals( + constants.ZERO_ADDRESS, + ); const [, r, s] = split3(signatureWithoutVersionV0 + '00'); - expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals(constants.ZERO_ADDRESS); + expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals( + constants.ZERO_ADDRESS, + ); }); it('works with short EIP2098 format', async function () { @@ -136,7 +152,9 @@ describe('ECDSA', async function () { const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; expect(await ecdsa.recover(HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(signerV0); - expect(await ecdsa.recover(HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(signerV0); + expect( + await ecdsa.recover(HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature))), + ).to.be.equals(signerV0); }); }); @@ -147,7 +165,9 @@ describe('ECDSA', async function () { const signature = signatureWithoutVersionV1 + version; expect(await ecdsa.recover(HASHED_TEST_MESSAGE, signature)).to.be.equals(constants.ZERO_ADDRESS); const [, r, s] = split3(signature); - expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, 1, r, s)).to.be.equals(constants.ZERO_ADDRESS); + expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, 1, r, s)).to.be.equals( + constants.ZERO_ADDRESS, + ); }); it('works with 28 as version value', async function () { @@ -156,16 +176,22 @@ describe('ECDSA', async function () { const signature = signatureWithoutVersionV1 + version; expect(await ecdsa.recover(HASHED_TEST_MESSAGE, signature)).to.be.equals(signerV1); expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(signerV1); - expect(await ecdsa.recover_r_vs(HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(signerV1); + expect(await ecdsa.recover_r_vs(HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal( + signerV1, + ); }); it('returns zero address when wrong version', async function () { const { ecdsa } = await loadFixture(deployContracts); // The last two hex digits are the signature version. // The only valid values are 0, 1, 27 and 28. - expect(await ecdsa.recover(HASHED_TEST_MESSAGE, signatureWithoutVersionV1 + '02')).to.be.equals(constants.ZERO_ADDRESS); + expect(await ecdsa.recover(HASHED_TEST_MESSAGE, signatureWithoutVersionV1 + '02')).to.be.equals( + constants.ZERO_ADDRESS, + ); const [, r, s] = split3(signatureWithoutVersionV1 + '01'); - expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals(constants.ZERO_ADDRESS); + expect(await ecdsa.recover_v_r_s(HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals( + constants.ZERO_ADDRESS, + ); }); it('works with short EIP2098 format', async function () { @@ -173,7 +199,9 @@ describe('ECDSA', async function () { const version = '1c'; // 27 = 1b. const signature = signatureWithoutVersionV1 + version; expect(await ecdsa.recover(HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(signerV1); - expect(await ecdsa.recover(HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(signerV1); + expect( + await ecdsa.recover(HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature))), + ).to.be.equals(signerV1); }); }); }); @@ -183,12 +211,16 @@ describe('ECDSA', async function () { describe('with invalid signature', async () => { it('with short signature', async function () { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); - expect(await ecdsa.isValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, '0x1234')).to.be.equals(false); + expect(await ecdsa.isValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, '0x1234')).to.be.equals( + false, + ); }); it('with long signature', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); - expect(await ecdsa.isValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, longSignature)).to.be.equals(false); + expect( + await ecdsa.isValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, longSignature), + ).to.be.equals(false); }); }); @@ -197,20 +229,42 @@ describe('ECDSA', async function () { it('returns true with correct signature and only correct signer', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - expect(await ecdsa.isValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(true); - expect(await ecdsa.isValidSignature(randomAccount.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); + expect( + await ecdsa.isValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(true); + expect( + await ecdsa.isValidSignature(randomAccount.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(false); }); it('returns true with correct signature and only correct signer for arbitrary length message', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(NON_HASH_MESSAGE); - expect(await ecdsa.isValidSignature(erc1271wallet.address, ethers.utils.hashMessage(NON_HASH_MESSAGE), signature)).to.be.equals(true); - expect(await ecdsa.isValidSignature(randomAccount.address, ethers.utils.hashMessage(NON_HASH_MESSAGE), signature)).to.be.equals(false); + expect( + await ecdsa.isValidSignature( + erc1271wallet.address, + ethers.utils.hashMessage(NON_HASH_MESSAGE), + signature, + ), + ).to.be.equals(true); + expect( + await ecdsa.isValidSignature( + randomAccount.address, + ethers.utils.hashMessage(NON_HASH_MESSAGE), + signature, + ), + ).to.be.equals(false); }); it('returns false with invalid signature', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); - expect(await ecdsa.isValidSignature(erc1271wallet.address, ethers.utils.hashMessage(NON_HASH_MESSAGE), invalidSignature)).to.be.equals(false); + expect( + await ecdsa.isValidSignature( + erc1271wallet.address, + ethers.utils.hashMessage(NON_HASH_MESSAGE), + invalidSignature, + ), + ).to.be.equals(false); }); }); @@ -219,80 +273,196 @@ describe('ECDSA', async function () { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); const version = '00'; const signature = signatureWithoutVersionV0 + version; - expect(await ecdsa.isValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); + expect( + await ecdsa.isValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(false); const [, r, s] = split3(signature); - expect(await ecdsa.isValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, 0, r, s)).to.be.equals(false); + expect( + await ecdsa.isValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, 0, r, s), + ).to.be.equals(false); }); it('returns true with 27 as version value, and only for signer', async function () { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; - expect(await ecdsa.isValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(true); - expect(await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); - expect(await ecdsa.isValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(true); - expect(await ecdsa.isValidSignature_v_r_s(account.address, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(false); - expect(await ecdsa.isValidSignature_r_vs(erc1271walletV0.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(true); - expect(await ecdsa.isValidSignature_r_vs(account.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(false); + expect( + await ecdsa.isValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(true); + expect(await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, signature)).to.be.equals( + false, + ); + expect( + await ecdsa.isValidSignature_v_r_s( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.isValidSignature_v_r_s(account.address, HASHED_TEST_MESSAGE, ...split3(signature)), + ).to.be.equals(false); + expect( + await ecdsa.isValidSignature_r_vs( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(true); + expect( + await ecdsa.isValidSignature_r_vs( + account.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(false); }); it('returns false when wrong version', async function () { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); // The last two hex digits are the signature version. // The only valid values are 0, 1, 27 and 28. - expect(await ecdsa.isValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signatureWithoutVersionV0 + '02')).to.be.equals(false); + expect( + await ecdsa.isValidSignature( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + signatureWithoutVersionV0 + '02', + ), + ).to.be.equals(false); const [, r, s] = split3(signatureWithoutVersionV1 + '01'); - expect(await ecdsa.isValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals(false); + expect( + await ecdsa.isValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, 2, r, s), + ).to.be.equals(false); }); it('returns true with short EIP2098 format, and only for signer', async function () { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; - expect(await ecdsa.isValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(true); - expect(await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(false); - expect(await ecdsa.isValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(true); - expect(await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(false); + expect( + await ecdsa.isValidSignature( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + to2098Format(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, to2098Format(signature)), + ).to.be.equals(false); + expect( + await ecdsa.isValidSignature( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(true); + expect( + await ecdsa.isValidSignature( + account.address, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(false); }); }); describe('with v1 signature', function () { it('returns false with 01 as version value', async function () { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); - expect(await ecdsa.isValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signatureWithoutVersionV1 + '01')).to.be.equals(false); + expect( + await ecdsa.isValidSignature( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + signatureWithoutVersionV1 + '01', + ), + ).to.be.equals(false); const [, r, s] = split3(signatureWithoutVersionV1 + '01'); - expect(await ecdsa.isValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, 1, r, s)).to.be.equals(false); + expect( + await ecdsa.isValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, 1, r, s), + ).to.be.equals(false); }); it('returns true with 28 as version value, and only for signer', async function () { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); const version = '1c'; // 28 = 1c. const signature = signatureWithoutVersionV1 + version; - expect(await ecdsa.isValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(true); - expect(await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); - expect(await ecdsa.isValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(true); - expect(await ecdsa.isValidSignature_v_r_s(account.address, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(false); - expect(await ecdsa.isValidSignature_r_vs(erc1271walletV1.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(true); - expect(await ecdsa.isValidSignature_r_vs(account.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(false); + expect( + await ecdsa.isValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(true); + expect(await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, signature)).to.be.equals( + false, + ); + expect( + await ecdsa.isValidSignature_v_r_s( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.isValidSignature_v_r_s(account.address, HASHED_TEST_MESSAGE, ...split3(signature)), + ).to.be.equals(false); + expect( + await ecdsa.isValidSignature_r_vs( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(true); + expect( + await ecdsa.isValidSignature_r_vs( + account.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(false); }); it('returns false when wrong version', async function () { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); // The last two hex digits are the signature version. // The only valid values are 0, 1, 27 and 28. - expect(await ecdsa.isValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signatureWithoutVersionV1 + '02')).to.be.equals(false); + expect( + await ecdsa.isValidSignature( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + signatureWithoutVersionV1 + '02', + ), + ).to.be.equals(false); const [, r, s] = split3(signatureWithoutVersionV1 + '01'); - expect(await ecdsa.isValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals(false); + expect( + await ecdsa.isValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, 2, r, s), + ).to.be.equals(false); }); it('returns true with short EIP2098 format, and only for signer', async function () { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); const version = '1c'; // 27 = 1b. const signature = signatureWithoutVersionV1 + version; - expect(await ecdsa.isValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(true); - expect(await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(false); - expect(await ecdsa.isValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(true); - expect(await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(false); + expect( + await ecdsa.isValidSignature( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + to2098Format(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.isValidSignature(account.address, HASHED_TEST_MESSAGE, to2098Format(signature)), + ).to.be.equals(false); + expect( + await ecdsa.isValidSignature( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(true); + expect( + await ecdsa.isValidSignature( + account.address, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(false); }); }); @@ -300,20 +470,38 @@ describe('ECDSA', async function () { it('with matching signer and signature', async function () { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - expect(await ecdsa.isValidSignature65(erc1271wallet.address, HASHED_TEST_MESSAGE, ...split2(signature))).to.be.equals(true); + expect( + await ecdsa.isValidSignature65( + erc1271wallet.address, + HASHED_TEST_MESSAGE, + ...split2(signature), + ), + ).to.be.equals(true); }); it('with invalid signer', async function () { const { ecdsa } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - expect(await ecdsa.isValidSignature65(randomAccount.address, HASHED_TEST_MESSAGE, ...split2(signature))).to.be.equals(false); + expect( + await ecdsa.isValidSignature65( + randomAccount.address, + HASHED_TEST_MESSAGE, + ...split2(signature), + ), + ).to.be.equals(false); }); it('with invalid signature', async function () { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); const HASHED_WRONG_MESSAGE = ethers.utils.hashMessage(WRONG_MESSAGE); - expect(await ecdsa.isValidSignature65(erc1271wallet.address, HASHED_WRONG_MESSAGE, ...split2(signature))).to.be.equals(false); + expect( + await ecdsa.isValidSignature65( + erc1271wallet.address, + HASHED_WRONG_MESSAGE, + ...split2(signature), + ), + ).to.be.equals(false); }); }); }); @@ -323,14 +511,22 @@ describe('ECDSA', async function () { describe('with invalid signature', async () => { it('with short signature', async function () { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); - expect(await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, '0x1234')).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, '0x1234')).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, '0x1234'), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, '0x1234'), + ).to.be.equals(false); }); it('with long signature', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); - expect(await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, longSignature)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, longSignature)).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, longSignature), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, longSignature), + ).to.be.equals(false); }); }); @@ -339,23 +535,59 @@ describe('ECDSA', async function () { it('returns true with correct signature and only correct signer', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - expect(await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(randomAccount.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature(randomAccount.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(true); }); it('returns true with correct signature and only correct signer for arbitrary length message', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(NON_HASH_MESSAGE); - expect(await ecdsa.recoverOrIsValidSignature(account.address, ethers.utils.hashMessage(NON_HASH_MESSAGE), signature)).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(randomAccount.address, ethers.utils.hashMessage(NON_HASH_MESSAGE), signature)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(erc1271wallet.address, ethers.utils.hashMessage(NON_HASH_MESSAGE), signature)).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + account.address, + ethers.utils.hashMessage(NON_HASH_MESSAGE), + signature, + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + randomAccount.address, + ethers.utils.hashMessage(NON_HASH_MESSAGE), + signature, + ), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature( + erc1271wallet.address, + ethers.utils.hashMessage(NON_HASH_MESSAGE), + signature, + ), + ).to.be.equals(true); }); it('returns false with invalid signature', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); - expect(await ecdsa.recoverOrIsValidSignature(account.address, ethers.utils.hashMessage(NON_HASH_MESSAGE), invalidSignature)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(erc1271wallet.address, ethers.utils.hashMessage(NON_HASH_MESSAGE), invalidSignature)).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature( + account.address, + ethers.utils.hashMessage(NON_HASH_MESSAGE), + invalidSignature, + ), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature( + erc1271wallet.address, + ethers.utils.hashMessage(NON_HASH_MESSAGE), + invalidSignature, + ), + ).to.be.equals(false); }); }); @@ -364,49 +596,159 @@ describe('ECDSA', async function () { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); const version = '00'; const signature = signatureWithoutVersionV0 + version; - expect(await ecdsa.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(false); const [, r, s] = split3(signature); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(signerV0, HASHED_TEST_MESSAGE, 0, r, s)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, 0, r, s)).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s(signerV0, HASHED_TEST_MESSAGE, 0, r, s), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + 0, + r, + s, + ), + ).to.be.equals(false); }); it('returns true with 27 as version value, and only for signer', async function () { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; - expect(await ecdsa.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, signature)).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(signerV0, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(account.address, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature_r_vs(signerV0, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(true); - expect(await ecdsa.recoverOrIsValidSignature_r_vs(erc1271walletV0.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(true); - expect(await ecdsa.recoverOrIsValidSignature_r_vs(account.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(false); + expect( + await ecdsa.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + signerV0, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + account.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_r_vs( + signerV0, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(true); + expect( + await ecdsa.recoverOrIsValidSignature_r_vs( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(true); + expect( + await ecdsa.recoverOrIsValidSignature_r_vs( + account.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(false); }); it('returns false when wrong version', async function () { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); // The last two hex digits are the signature version. // The only valid values are 0, 1, 27 and 28. - expect(await ecdsa.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, signatureWithoutVersionV0 + '02')).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signatureWithoutVersionV0 + '02')).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature( + signerV0, + HASHED_TEST_MESSAGE, + signatureWithoutVersionV0 + '02', + ), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + signatureWithoutVersionV0 + '02', + ), + ).to.be.equals(false); const [, r, s] = split3(signatureWithoutVersionV0 + '00'); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(signerV0, HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s(signerV0, HASHED_TEST_MESSAGE, 2, r, s), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + 2, + r, + s, + ), + ).to.be.equals(false); }); it('returns true with short EIP2098 format, and only for signer', async function () { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; - expect(await ecdsa.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, to2098Format(signature)), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + to2098Format(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + account.address, + HASHED_TEST_MESSAGE, + to2098Format(signature), + ), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature( + signerV0, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + account.address, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(false); }); }); @@ -415,49 +757,159 @@ describe('ECDSA', async function () { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); const version = '01'; const signature = signatureWithoutVersionV1 + version; - expect(await ecdsa.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(false); const [, r, s] = split3(signature); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(signerV1, HASHED_TEST_MESSAGE, 1, r, s)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, 1, r, s)).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s(signerV1, HASHED_TEST_MESSAGE, 1, r, s), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + 1, + r, + s, + ), + ).to.be.equals(false); }); it('returns true with 28 as version value, and only for signer', async function () { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); const version = '1c'; // 28 = 1c. const signature = signatureWithoutVersionV1 + version; - expect(await ecdsa.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, signature)).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, signature)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(signerV1, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(account.address, HASHED_TEST_MESSAGE, ...split3(signature))).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature_r_vs(signerV1, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(true); - expect(await ecdsa.recoverOrIsValidSignature_r_vs(erc1271walletV1.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(true); - expect(await ecdsa.recoverOrIsValidSignature_r_vs(account.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))).to.equal(false); + expect( + await ecdsa.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, signature), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + signerV1, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + account.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_r_vs( + signerV1, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(true); + expect( + await ecdsa.recoverOrIsValidSignature_r_vs( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(true); + expect( + await ecdsa.recoverOrIsValidSignature_r_vs( + account.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ).to.equal(false); }); it('returns false when wrong version', async function () { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); // The last two hex digits are the signature version. // The only valid values are 0, 1, 27 and 28. - expect(await ecdsa.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, signatureWithoutVersionV1 + '02')).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signatureWithoutVersionV1 + '02')).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature( + signerV1, + HASHED_TEST_MESSAGE, + signatureWithoutVersionV1 + '02', + ), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + signatureWithoutVersionV1 + '02', + ), + ).to.be.equals(false); const [, r, s] = split3(signatureWithoutVersionV1 + '01'); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(signerV1, HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, 2, r, s)).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s(signerV1, HASHED_TEST_MESSAGE, 2, r, s), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature_v_r_s( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + 2, + r, + s, + ), + ).to.be.equals(false); }); it('returns true with short EIP2098 format, and only for signer', async function () { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); const version = '1c'; // 27 = 1b. const signature = signatureWithoutVersionV1 + version; - expect(await ecdsa.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, to2098Format(signature))).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, to2098Format(signature)), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + to2098Format(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + account.address, + HASHED_TEST_MESSAGE, + to2098Format(signature), + ), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature( + signerV1, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature( + account.address, + HASHED_TEST_MESSAGE, + from2098Format(to2098Format(signature)), + ), + ).to.be.equals(false); }); }); @@ -465,22 +917,52 @@ describe('ECDSA', async function () { it('with matching signer and signature', async function () { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - expect(await ecdsa.recoverOrIsValidSignature65(account.address, HASHED_TEST_MESSAGE, ...split2(signature))).to.be.equals(true); - expect(await ecdsa.recoverOrIsValidSignature65(erc1271wallet.address, HASHED_TEST_MESSAGE, ...split2(signature))).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature65( + account.address, + HASHED_TEST_MESSAGE, + ...split2(signature), + ), + ).to.be.equals(true); + expect( + await ecdsa.recoverOrIsValidSignature65( + erc1271wallet.address, + HASHED_TEST_MESSAGE, + ...split2(signature), + ), + ).to.be.equals(true); }); it('with invalid signer', async function () { const { ecdsa } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - expect(await ecdsa.recoverOrIsValidSignature65(randomAccount.address, HASHED_TEST_MESSAGE, ...split2(signature))).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature65( + randomAccount.address, + HASHED_TEST_MESSAGE, + ...split2(signature), + ), + ).to.be.equals(false); }); it('with invalid signature', async function () { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); const HASHED_WRONG_MESSAGE = ethers.utils.hashMessage(WRONG_MESSAGE); - expect(await ecdsa.recoverOrIsValidSignature65(account.address, HASHED_WRONG_MESSAGE, ...split2(signature))).to.be.equals(false); - expect(await ecdsa.recoverOrIsValidSignature65(erc1271wallet.address, HASHED_WRONG_MESSAGE, ...split2(signature))).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature65( + account.address, + HASHED_WRONG_MESSAGE, + ...split2(signature), + ), + ).to.be.equals(false); + expect( + await ecdsa.recoverOrIsValidSignature65( + erc1271wallet.address, + HASHED_WRONG_MESSAGE, + ...split2(signature), + ), + ).to.be.equals(false); }); }); }); @@ -493,7 +975,9 @@ describe('ECDSA', async function () { const msg = concat([ ethers.utils.toUtf8Bytes('\x19Ethereum Signed Message:\n'), ethers.utils.toUtf8Bytes(String(hashedTestMessageWithoutPrefix.length / 2)), - arrayify(hashedTestMessageWithoutPrefix, { allowMissingPrefix: true }), + arrayify(hashedTestMessageWithoutPrefix, { + allowMissingPrefix: true, + }), ]); const ethSignedMessage = ethers.utils.keccak256(msg); expect(await ecdsa.toEthSignedMessageHash(HASHED_TEST_MESSAGE)).to.be.equals(ethSignedMessage); @@ -505,11 +989,13 @@ describe('ECDSA', async function () { const { ecdsa } = await loadFixture(deployContracts); const domainSeparator = HASHED_TEST_MESSAGE.substring(2); const structHash = HASHED_TEST_MESSAGE.substring(2); - const typedDataHash = ethers.utils.keccak256(concat([ - ethers.utils.toUtf8Bytes('\x19\x01'), - arrayify(domainSeparator, { allowMissingPrefix: true }), - arrayify(String(structHash), { allowMissingPrefix: true }), - ])); + const typedDataHash = ethers.utils.keccak256( + concat([ + ethers.utils.toUtf8Bytes('\x19\x01'), + arrayify(domainSeparator, { allowMissingPrefix: true }), + arrayify(String(structHash), { allowMissingPrefix: true }), + ]), + ); expect(await ecdsa.toTypedDataHash(HASHED_TEST_MESSAGE, HASHED_TEST_MESSAGE)).to.be.equals(typedDataHash); }); }); @@ -527,8 +1013,15 @@ describe('ECDSA', async function () { const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; await account.sendTransaction(await ecdsa.populateTransaction.recover(HASHED_TEST_MESSAGE, signature)); - await account.sendTransaction(await ecdsa.populateTransaction.recover_v_r_s(HASHED_TEST_MESSAGE, ...split3(signature))); - await account.sendTransaction(await ecdsa.populateTransaction.recover_r_vs(HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))); + await account.sendTransaction( + await ecdsa.populateTransaction.recover_v_r_s(HASHED_TEST_MESSAGE, ...split3(signature)), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recover_r_vs( + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ); }); it('with v1 signature', async () => { @@ -536,8 +1029,15 @@ describe('ECDSA', async function () { const version = '1c'; // 28 = 1c. const signature = signatureWithoutVersionV1 + version; await account.sendTransaction(await ecdsa.populateTransaction.recover(HASHED_TEST_MESSAGE, signature)); - await account.sendTransaction(await ecdsa.populateTransaction.recover_v_r_s(HASHED_TEST_MESSAGE, ...split3(signature))); - await account.sendTransaction(await ecdsa.populateTransaction.recover_r_vs(HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))); + await account.sendTransaction( + await ecdsa.populateTransaction.recover_v_r_s(HASHED_TEST_MESSAGE, ...split3(signature)), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recover_r_vs( + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ); }); }); @@ -545,39 +1045,127 @@ describe('ECDSA', async function () { it('with signature', async function () { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature(account.address, HASHED_TEST_MESSAGE, signature)); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, signature)); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature( + account.address, + HASHED_TEST_MESSAGE, + signature, + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature( + erc1271wallet.address, + HASHED_TEST_MESSAGE, + signature, + ), + ); }); it('with v0 signature', async () => { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, signature)); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature)); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature_v_r_s(signerV0, HASHED_TEST_MESSAGE, ...split3(signature))); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, ...split3(signature))); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature_r_vs(signerV0, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature_r_vs(erc1271walletV0.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature(signerV0, HASHED_TEST_MESSAGE, signature), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + signature, + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature_v_r_s( + signerV0, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature_v_r_s( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature_r_vs( + signerV0, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature_r_vs( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ); }); it('with v1 signature', async () => { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, signature)); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signature)); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature_v_r_s(signerV1, HASHED_TEST_MESSAGE, ...split3(signature))); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, ...split3(signature))); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature_r_vs(signerV1, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature_r_vs(erc1271walletV1.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature(signerV1, HASHED_TEST_MESSAGE, signature), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + signature, + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature_v_r_s( + signerV1, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature_v_r_s( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature_r_vs( + signerV1, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature_r_vs( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ); }); it('recoverOrIsValidSignature65', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature65(account.address, HASHED_TEST_MESSAGE, ...split2(signature))); - await account.sendTransaction(await ecdsa.populateTransaction.recoverOrIsValidSignature65(erc1271wallet.address, HASHED_TEST_MESSAGE, ...split2(signature))); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature65( + account.address, + HASHED_TEST_MESSAGE, + ...split2(signature), + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.recoverOrIsValidSignature65( + erc1271wallet.address, + HASHED_TEST_MESSAGE, + ...split2(signature), + ), + ); }); }); @@ -585,43 +1173,95 @@ describe('ECDSA', async function () { it('with signature', async function () { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - await account.sendTransaction(await ecdsa.populateTransaction.isValidSignature(erc1271wallet.address, HASHED_TEST_MESSAGE, signature)); + await account.sendTransaction( + await ecdsa.populateTransaction.isValidSignature( + erc1271wallet.address, + HASHED_TEST_MESSAGE, + signature, + ), + ); }); it('with v0 signature', async () => { const { ecdsa, erc1271walletV0 } = await loadFixture(deployContracts); const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; - await account.sendTransaction(await ecdsa.populateTransaction.isValidSignature(erc1271walletV0.address, HASHED_TEST_MESSAGE, signature)); - await account.sendTransaction(await ecdsa.populateTransaction.isValidSignature_v_r_s(erc1271walletV0.address, HASHED_TEST_MESSAGE, ...split3(signature))); - await account.sendTransaction(await ecdsa.populateTransaction.isValidSignature_r_vs(erc1271walletV0.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))); + await account.sendTransaction( + await ecdsa.populateTransaction.isValidSignature( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + signature, + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.isValidSignature_v_r_s( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.isValidSignature_r_vs( + erc1271walletV0.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ); }); it('with v1 signature', async () => { const { ecdsa, erc1271walletV1 } = await loadFixture(deployContracts); const version = '1b'; // 27 = 1b. const signature = signatureWithoutVersionV0 + version; - await account.sendTransaction(await ecdsa.populateTransaction.isValidSignature(erc1271walletV1.address, HASHED_TEST_MESSAGE, signature)); - await account.sendTransaction(await ecdsa.populateTransaction.isValidSignature_v_r_s(erc1271walletV1.address, HASHED_TEST_MESSAGE, ...split3(signature))); - await account.sendTransaction(await ecdsa.populateTransaction.isValidSignature_r_vs(erc1271walletV1.address, HASHED_TEST_MESSAGE, ...split2(to2098Format(signature)))); + await account.sendTransaction( + await ecdsa.populateTransaction.isValidSignature( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + signature, + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.isValidSignature_v_r_s( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + ...split3(signature), + ), + ); + await account.sendTransaction( + await ecdsa.populateTransaction.isValidSignature_r_vs( + erc1271walletV1.address, + HASHED_TEST_MESSAGE, + ...split2(to2098Format(signature)), + ), + ); }); it('isValidSignature65', async () => { const { ecdsa, erc1271wallet } = await loadFixture(deployContracts); const signature = await account.signMessage(TEST_MESSAGE); - await account.sendTransaction(await ecdsa.populateTransaction.isValidSignature65(erc1271wallet.address, HASHED_TEST_MESSAGE, ...split2(signature))); + await account.sendTransaction( + await ecdsa.populateTransaction.isValidSignature65( + erc1271wallet.address, + HASHED_TEST_MESSAGE, + ...split2(signature), + ), + ); }); }); describe('Additional methods', async () => { it('toEthSignedMessageHash', async function () { const { ecdsa } = await loadFixture(deployContracts); - await account.sendTransaction(await ecdsa.populateTransaction.toEthSignedMessageHash(HASHED_TEST_MESSAGE)); + await account.sendTransaction( + await ecdsa.populateTransaction.toEthSignedMessageHash(HASHED_TEST_MESSAGE), + ); }); it('toTypedDataHash', async function () { const { ecdsa } = await loadFixture(deployContracts); - await account.sendTransaction(await ecdsa.populateTransaction.toTypedDataHash(HASHED_TEST_MESSAGE, HASHED_TEST_MESSAGE)); + await account.sendTransaction( + await ecdsa.populateTransaction.toTypedDataHash(HASHED_TEST_MESSAGE, HASHED_TEST_MESSAGE), + ); }); }); }); diff --git a/test/contracts/EthReceiver.test.ts b/test/contracts/EthReceiver.test.ts index 239b6b82..c6824191 100644 --- a/test/contracts/EthReceiver.test.ts +++ b/test/contracts/EthReceiver.test.ts @@ -18,11 +18,13 @@ contract('EthReceiver', function (accounts) { }); it('normal transfer', async function () { - await expect(web3.eth.sendTransaction({ - from: account, - to: this.receiver.address, - value: 100, - })).to.eventually.be.rejectedWith('EthDepositRejected'); + await expect( + web3.eth.sendTransaction({ + from: account, + to: this.receiver.address, + value: 100, + }), + ).to.eventually.be.rejectedWith('EthDepositRejected'); }); }); }); diff --git a/test/contracts/RevertReasonParser.test.ts b/test/contracts/RevertReasonParser.test.ts index 415f01fd..c1bc21e2 100644 --- a/test/contracts/RevertReasonParser.test.ts +++ b/test/contracts/RevertReasonParser.test.ts @@ -1,4 +1,3 @@ - import { expect } from '../../src/prelude'; import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; import { ethers } from 'hardhat'; @@ -43,8 +42,10 @@ describe('RevertReasonParser', async () => { it('should be reverted in _test()', async function () { const { revertReasonParserTest } = await loadFixture(deployRevertReasonParserTest); - await expect(revertReasonParserTest.testWithThrow()) - .to.be.revertedWithCustomError(revertReasonParserTest, 'TestDidNotThrow'); + await expect(revertReasonParserTest.testWithThrow()).to.be.revertedWithCustomError( + revertReasonParserTest, + 'TestDidNotThrow', + ); }); }); }); diff --git a/test/contracts/SafestERC20.test.ts b/test/contracts/SafestERC20.test.ts index f88d7784..993bb5b5 100644 --- a/test/contracts/SafestERC20.test.ts +++ b/test/contracts/SafestERC20.test.ts @@ -46,11 +46,7 @@ contract('SafeERC20', function (accounts) { this.wrapper = await SafeERC20Wrapper.new((await ERC20ReturnFalseMock.new()).address); }); - shouldRevertOnAllCalls([ - 'SafeTransferFailed()', - 'SafeTransferFromFailed()', - 'ForceApproveFailed()', - ]); + shouldRevertOnAllCalls(['SafeTransferFailed()', 'SafeTransferFromFailed()', 'ForceApproveFailed()']); }); describe('with token that returns true on all calls', function () { @@ -90,7 +86,7 @@ contract('SafeERC20', function (accounts) { }); }); - describe('with token that doesn\'t revert on invalid permit', function () { + describe("with token that doesn't revert on invalid permit", function () { const wallet = Wallet.generate(); const owner = wallet.getAddressString(); const spender = hasNoCode; @@ -104,8 +100,19 @@ contract('SafeERC20', function (accounts) { this.data = { primaryType: 'Permit', types: { EIP712Domain, Permit }, - domain: { name: 'ERC20PermitNoRevertMock', version: '1', chainId, verifyingContract: this.token.address }, - message: { owner, spender, value: '42', nonce: '0', deadline: constants.MAX_UINT256 }, + domain: { + name: 'ERC20PermitNoRevertMock', + version: '1', + chainId, + verifyingContract: this.token.address, + }, + message: { + owner, + spender, + value: '42', + nonce: '0', + deadline: constants.MAX_UINT256, + }, }; this.signature = fromRpcSig(signWithPk(wallet.getPrivateKey(), this.data)); }); @@ -198,7 +205,7 @@ contract('SafeERC20', function (accounts) { }); }); -function shouldRevertOnAllCalls (reasons: string[]) { +function shouldRevertOnAllCalls(reasons: string[]) { it('reverts on transfer', async function () { await expect(this.wrapper.transfer()).to.eventually.be.rejectedWith(reasons[0]); }); @@ -222,12 +229,12 @@ function shouldRevertOnAllCalls (reasons: string[]) { }); } -function shouldOnlyRevertOnErrors () { - it('doesn\'t revert on transfer', async function () { +function shouldOnlyRevertOnErrors() { + it("doesn't revert on transfer", async function () { await this.wrapper.transfer(); }); - it('doesn\'t revert on transferFrom', async function () { + it("doesn't revert on transferFrom", async function () { await this.wrapper.transferFrom(); }); @@ -237,21 +244,22 @@ function shouldOnlyRevertOnErrors () { await this.wrapper.setAllowance(0); }); - it('doesn\'t revert when approving a non-zero allowance', async function () { + it("doesn't revert when approving a non-zero allowance", async function () { await this.wrapper.approve(100); }); - it('doesn\'t revert when approving a zero allowance', async function () { + it("doesn't revert when approving a zero allowance", async function () { await this.wrapper.approve(0); }); - it('doesn\'t revert when increasing the allowance', async function () { + it("doesn't revert when increasing the allowance", async function () { await this.wrapper.increaseAllowance(10); }); it('reverts when decreasing the allowance', async function () { - await expect(this.wrapper.decreaseAllowance(10)) - .to.eventually.be.rejectedWith('SafeDecreaseAllowanceFailed()'); + await expect(this.wrapper.decreaseAllowance(10)).to.eventually.be.rejectedWith( + 'SafeDecreaseAllowanceFailed()', + ); }); }); @@ -260,25 +268,26 @@ function shouldOnlyRevertOnErrors () { await this.wrapper.setAllowance(100); }); - it('doesn\'t revert when approving a non-zero allowance', async function () { + it("doesn't revert when approving a non-zero allowance", async function () { await this.wrapper.approve(20); }); - it('doesn\'t revert when approving a zero allowance', async function () { + it("doesn't revert when approving a zero allowance", async function () { await this.wrapper.approve(0); }); - it('doesn\'t revert when increasing the allowance', async function () { + it("doesn't revert when increasing the allowance", async function () { await this.wrapper.increaseAllowance(10); }); - it('doesn\'t revert when decreasing the allowance to a positive value', async function () { + it("doesn't revert when decreasing the allowance to a positive value", async function () { await this.wrapper.decreaseAllowance(50); }); it('reverts when decreasing the allowance to a negative value', async function () { - await expect(this.wrapper.decreaseAllowance(200)) - .to.eventually.be.rejectedWith('SafeDecreaseAllowanceFailed()'); + await expect(this.wrapper.decreaseAllowance(200)).to.eventually.be.rejectedWith( + 'SafeDecreaseAllowanceFailed()', + ); }); }); }); diff --git a/test/contracts/StringUtil.test.ts b/test/contracts/StringUtil.test.ts index d17e1f4f..93827137 100644 --- a/test/contracts/StringUtil.test.ts +++ b/test/contracts/StringUtil.test.ts @@ -3,12 +3,9 @@ import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; import { ethers } from 'hardhat'; describe('StringUtil', async () => { - const uint256TestValue = - '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - const uint128TestValue = - '0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - const veryLongArray = - '0xffffffffffffffafafafbcbcbcbcbdeded' + 'aa'.repeat(50); + const uint256TestValue = '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; + const uint128TestValue = '0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; + const veryLongArray = '0xffffffffffffffafafafbcbcbcbcbdeded' + 'aa'.repeat(50); const extremelyLongArray = '0x' + '0f'.repeat(1000); const emptyBytes = '0x'; const singleByte = '0xaf'; @@ -62,36 +59,33 @@ describe('StringUtil', async () => { const testIncorrectGas = async (value: string, expectedGas: number) => { const { stringUtilTest } = await loadFixture(deployStringUtilTest); - await expect(stringUtilTest.toHexNaiveBytes(value, expectedGas)).to.be.revertedWithCustomError(stringUtilTest, 'GasCostDiffers'); + await expect(stringUtilTest.toHexNaiveBytes(value, expectedGas)).to.be.revertedWithCustomError( + stringUtilTest, + 'GasCostDiffers', + ); }; }); describe('Gas usage @skip-on-coverage', async () => { it('Uint 256', () => testGasUint256(uint256TestValue, 907)); - it('Uint 256 naive', () => - testGasNaiveUint256(uint256TestValue, 14175)); + it('Uint 256 naive', () => testGasNaiveUint256(uint256TestValue, 14175)); it('Uint 256 as bytes', () => testGasBytes(uint256TestValue, 782)); - it('Uint 256 as bytes naive', () => - testGasNaiveBytes(uint256TestValue, 14050)); + it('Uint 256 as bytes naive', () => testGasNaiveBytes(uint256TestValue, 14050)); it('Uint 128', () => testGasUint256(uint128TestValue, 907)); - it('Uint 128 naive', () => - testGasNaiveUint256(uint128TestValue, 14175)); + it('Uint 128 naive', () => testGasNaiveUint256(uint128TestValue, 14175)); it('Very long byte array gas', () => testGasBytes(veryLongArray, 1964)); - it('Very long byte array gas naive', () => - testGasNaiveBytes(veryLongArray, 28972)); + it('Very long byte array gas naive', () => testGasNaiveBytes(veryLongArray, 28972)); - it('Extremely long byte array gas', () => - testGasBytes(extremelyLongArray, 19121)); + it('Extremely long byte array gas', () => testGasBytes(extremelyLongArray, 19121)); - it('Extremely long byte array gas naive', () => - testGasNaiveBytes(extremelyLongArray, 426795)); + it('Extremely long byte array gas naive', () => testGasNaiveBytes(extremelyLongArray, 426795)); it('Empty bytes', () => testGasBytes(emptyBytes, 191)); diff --git a/test/contracts/UniERC20.test.ts b/test/contracts/UniERC20.test.ts index 10d84708..4a97bb55 100644 --- a/test/contracts/UniERC20.test.ts +++ b/test/contracts/UniERC20.test.ts @@ -160,32 +160,33 @@ contract('UniERC20', function (accounts) { }); it('uni approve must fail', async function () { - await expect(this.wrapper.approve(account, 100, { from: account1 })).to.be.rejectedWith('ApproveCalledOnETH'); + await expect(this.wrapper.approve(account, 100, { from: account1 })).to.be.rejectedWith( + 'ApproveCalledOnETH', + ); }); it('uni transfer from, success', async function () { const balBefore = toBN(await this.wrapper.balanceOf(this.wrapper.address)); - await this.wrapper.transferFrom( - account, - this.wrapper.address, - 100, - { value: 100 } - ); + await this.wrapper.transferFrom(account, this.wrapper.address, 100, { value: 100 }); const balAfter = toBN(await this.wrapper.balanceOf(this.wrapper.address)); expect(balAfter.sub(balBefore)).to.be.bignumber.equal(toBN(100)); }); it('uni transfer from, fail, not sender', async function () { - await expect(this.wrapper.transferFrom(account, this.wrapper.address, 100, { - from: account1, - value: 100, - })).to.be.rejectedWith('FromIsNotSender'); + await expect( + this.wrapper.transferFrom(account, this.wrapper.address, 100, { + from: account1, + value: 100, + }), + ).to.be.rejectedWith('FromIsNotSender'); }); it('uni transfer from, fail, receiver is not contract', async function () { - await expect(this.wrapper.transferFrom(account, account1, 100, { - value: 100, - })).to.be.rejectedWith('ToIsNotThis'); + await expect( + this.wrapper.transferFrom(account, account1, 100, { + value: 100, + }), + ).to.be.rejectedWith('ToIsNotThis'); }); it('uni name', async function () { @@ -200,22 +201,23 @@ contract('UniERC20', function (accounts) { describe('ETH with bad ether receiver', async function () { beforeEach(async function () { this.wrapper = await UniERC20Wrapper.new(constants.ZERO_ADDRESS); - this.receiver = await ETHBadReceiver.new( - constants.ZERO_ADDRESS, - this.wrapper.address - ); + this.receiver = await ETHBadReceiver.new(constants.ZERO_ADDRESS, this.wrapper.address); }); it('uni failed transfer', async function () { - await expect(this.wrapper.transfer(this.receiver.address, 100, { - value: 100, - })).to.eventually.be.rejectedWith('ETHTransferFailed'); + await expect( + this.wrapper.transfer(this.receiver.address, 100, { + value: 100, + }), + ).to.eventually.be.rejectedWith('ETHTransferFailed'); }); it('uni failed transferFrom', async function () { - await expect(this.receiver.transfer(this.wrapper.address, 100, { - value: 101, - })).to.eventually.be.rejectedWith('ETHTransferFailed'); + await expect( + this.receiver.transfer(this.wrapper.address, 100, { + value: 101, + }), + ).to.eventually.be.rejectedWith('ETHTransferFailed'); }); }); diff --git a/test/contracts/WethReceiver.test.ts b/test/contracts/WethReceiver.test.ts index 79a6ff6b..f852c6f4 100644 --- a/test/contracts/WethReceiver.test.ts +++ b/test/contracts/WethReceiver.test.ts @@ -18,11 +18,13 @@ contract('WethReceiver', function (accounts) { }); it('normal transfer', async function () { - await expect(web3.eth.sendTransaction({ - from: account, - to: this.receiver.address, - value: 100, - })).to.eventually.be.rejectedWith('EthDepositRejected'); + await expect( + web3.eth.sendTransaction({ + from: account, + to: this.receiver.address, + value: 100, + }), + ).to.eventually.be.rejectedWith('EthDepositRejected'); }); }); }); diff --git a/test/permit.test.ts b/test/permit.test.ts index 7bc38c65..57f39e93 100644 --- a/test/permit.test.ts +++ b/test/permit.test.ts @@ -12,7 +12,7 @@ describe('Permit library', async function () { [signer1] = await ethers.getSigners(); }); - async function deployTokens () { + async function deployTokens() { const ERC20PermitMock = await ethers.getContractFactory('ERC20PermitMock'); const DaiLikePermitMock = await ethers.getContractFactory('DaiLikePermitMock'); @@ -59,7 +59,16 @@ describe('Permit library', async function () { const { daiLikePermitMock, chainId } = await loadFixture(deployTokens); const name = await daiLikePermitMock.name(); - const data = buildDataLikeDai(name, '1', chainId, daiLikePermitMock.address, signer1.address, signer1.address, '1', true); + const data = buildDataLikeDai( + name, + '1', + chainId, + daiLikePermitMock.address, + signer1.address, + signer1.address, + '1', + true, + ); expect(data).to.be.deep.equal({ types: { Permit: DaiLikePermit, diff --git a/test/profileEVM.test.ts b/test/profileEVM.test.ts index ed178bc1..86a45939 100644 --- a/test/profileEVM.test.ts +++ b/test/profileEVM.test.ts @@ -25,16 +25,18 @@ describe('trace inspection', async function () { const { usdt } = await loadFixture(deployUSDT); const txn = await usdt.transfer(signer2.address, ether('1')); - expect(await profileEVM(txn.hash, ['STATICCALL', 'CALL', 'SSTORE', 'SLOAD'])) - .to.be.deep.equal([0, 0, 2, 2]); + expect(await profileEVM(txn.hash, ['STATICCALL', 'CALL', 'SSTORE', 'SLOAD'])).to.be.deep.equal([ + 0, 0, 2, 2, + ]); }); it('should be counted ERC20 Approve', async function () { const { usdt } = await loadFixture(deployUSDT); const txn = await usdt.approve(signer2.address, ether('1')); - expect(await profileEVM(txn.hash, ['STATICCALL', 'CALL', 'SSTORE', 'SLOAD'])) - .to.be.deep.equal([0, 0, 1, 0]); + expect(await profileEVM(txn.hash, ['STATICCALL', 'CALL', 'SSTORE', 'SLOAD'])).to.be.deep.equal([ + 0, 0, 1, 0, + ]); }); }); @@ -43,52 +45,58 @@ describe('trace inspection', async function () { const { usdt } = await loadFixture(deployUSDT); const txn = await usdt.transfer(signer2.address, ether('1')); - expect(await gasspectEVM(txn.hash)) - .to.be.deep.equal(['0-0-SLOAD = 2100', '0-0-SSTORE = 2900', '0-0-SLOAD = 2100', '0-0-SSTORE = 2900', '0-0-LOG3 = 1756']); + expect(await gasspectEVM(txn.hash)).to.be.deep.equal([ + '0-0-SLOAD = 2100', + '0-0-SSTORE = 2900', + '0-0-SLOAD = 2100', + '0-0-SSTORE = 2900', + '0-0-LOG3 = 1756', + ]); }); it('should be counted ERC20 Approve', async function () { const { usdt } = await loadFixture(deployUSDT); const txn = await usdt.approve(signer2.address, ether('1')); - expect(await gasspectEVM(txn.hash)) - .to.be.deep.equal(['0-0-SSTORE_I = 22100', '0-0-LOG3 = 1756']); + expect(await gasspectEVM(txn.hash)).to.be.deep.equal(['0-0-SSTORE_I = 22100', '0-0-LOG3 = 1756']); }); it('should be counted ERC20 Transfer with minOpGasCost = 2000', async function () { const { usdt } = await loadFixture(deployUSDT); const txn = await usdt.transfer(signer2.address, ether('1')); - expect(await gasspectEVM(txn.hash, { minOpGasCost: 2000 })) - .to.be.deep.equal(['0-0-SLOAD = 2100', '0-0-SSTORE = 2900', '0-0-SLOAD = 2100', '0-0-SSTORE = 2900']); + expect(await gasspectEVM(txn.hash, { minOpGasCost: 2000 })).to.be.deep.equal([ + '0-0-SLOAD = 2100', + '0-0-SSTORE = 2900', + '0-0-SLOAD = 2100', + '0-0-SSTORE = 2900', + ]); }); it('should be counted ERC20 Transfer with args', async function () { const { usdt } = await loadFixture(deployUSDT); const txn = await usdt.transfer(signer2.address, ether('1')); - expect(await gasspectEVM(txn.hash, { args: true })) - .to.be.deep.equal([ - '0-0-SLOAD(0x723077b8a1b173adc35e5f0e7e3662fd1208212cb629f9c128551ea7168da722) = 2100', - '0-0-SSTORE(0x723077b8a1b173adc35e5f0e7e3662fd1208212cb629f9c128551ea7168da722,0x00000000000000000000000000000000000000000000003627e8f712373c0000) = 2900', - '0-0-SLOAD(0x14e04a66bf74771820a7400ff6cf065175b3d7eb25805a5bd1633b161af5d101) = 2100', - '0-0-SSTORE(0x14e04a66bf74771820a7400ff6cf065175b3d7eb25805a5bd1633b161af5d101,0x00000000000000000000000000000000000000000000003643aa647986040000) = 2900', - '0-0-LOG3() = 1756', - ]); + expect(await gasspectEVM(txn.hash, { args: true })).to.be.deep.equal([ + '0-0-SLOAD(0x723077b8a1b173adc35e5f0e7e3662fd1208212cb629f9c128551ea7168da722) = 2100', + '0-0-SSTORE(0x723077b8a1b173adc35e5f0e7e3662fd1208212cb629f9c128551ea7168da722,0x00000000000000000000000000000000000000000000003627e8f712373c0000) = 2900', + '0-0-SLOAD(0x14e04a66bf74771820a7400ff6cf065175b3d7eb25805a5bd1633b161af5d101) = 2100', + '0-0-SSTORE(0x14e04a66bf74771820a7400ff6cf065175b3d7eb25805a5bd1633b161af5d101,0x00000000000000000000000000000000000000000000003643aa647986040000) = 2900', + '0-0-LOG3() = 1756', + ]); }); it('should be counted ERC20 Transfer with res', async function () { const { usdt } = await loadFixture(deployUSDT); const txn = await usdt.transfer(signer2.address, ether('1')); - expect(await gasspectEVM(txn.hash, { res: true })) - .to.be.deep.equal([ - '0-0-SLOAD:0x00000000000000000000000000000000000000000000003635c9adc5dea00000 = 2100', - '0-0-SSTORE = 2900', - '0-0-SLOAD:0x00000000000000000000000000000000000000000000003635c9adc5dea00000 = 2100', - '0-0-SSTORE = 2900', - '0-0-LOG3 = 1756', - ]); + expect(await gasspectEVM(txn.hash, { res: true })).to.be.deep.equal([ + '0-0-SLOAD:0x00000000000000000000000000000000000000000000003635c9adc5dea00000 = 2100', + '0-0-SSTORE = 2900', + '0-0-SLOAD:0x00000000000000000000000000000000000000000000003635c9adc5dea00000 = 2100', + '0-0-SSTORE = 2900', + '0-0-LOG3 = 1756', + ]); }); }); }); diff --git a/test/utils.test.ts b/test/utils.test.ts index c890ebcd..dd56fb6c 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -9,13 +9,13 @@ import { arrayify } from 'ethers/lib/utils'; describe('timeIncreaseTo', async function () { const precision = 2; - async function shouldIncrease (secs: number) { + async function shouldIncrease(secs: number) { const timeBefore = await time.latest(); await timeIncreaseTo(timeBefore + secs); const timeAfter = await time.latest(); expect(timeAfter).to.be.gt(timeBefore); - expect(timeAfter - timeBefore).to.be.lte(secs +precision); + expect(timeAfter - timeBefore).to.be.lte(secs + precision); expect(timeAfter - timeBefore).to.be.gte(secs); } @@ -32,18 +32,22 @@ describe('timeIncreaseTo', async function () { }); it('should be thrown with increase time to a moment in the past', async function () { - await expect(shouldIncrease(-1000)).to.be.rejectedWith(/Invalid timestamp \d+ is not larger than current timestamp \d+/); + await expect(shouldIncrease(-1000)).to.be.rejectedWith( + /Invalid timestamp \d+ is not larger than current timestamp \d+/, + ); }); }); describe('fixSignature', async function () { it('should not be fixed geth sign', async function () { - const signature = '0xb453386b73ba5608314e9b4c7890a4bd12cc24c2c7bdf5f87778960ff85c56a8520dabdbea357fc561120dd2625bd8a904f35bdb4b153cf706b6ff25bb0d898d1c'; + const signature = + '0xb453386b73ba5608314e9b4c7890a4bd12cc24c2c7bdf5f87778960ff85c56a8520dabdbea357fc561120dd2625bd8a904f35bdb4b153cf706b6ff25bb0d898d1c'; expect(signature).equal(fixSignature(signature)); }); it('should be fixed ganache sign', async function () { - const signature = '0x511fafdf71306ff89a063a76b52656c18e9a7d80d19e564c90f0126f732696bb673cde46003aad0ccb6dab2ca91ae38b82170824b0725883875194b273f709b901'; + const signature = + '0x511fafdf71306ff89a063a76b52656c18e9a7d80d19e564c90f0126f732696bb673cde46003aad0ccb6dab2ca91ae38b82170824b0725883875194b273f709b901'; const v = parseInt(signature.slice(130, 132), 16) + 27; const vHex = v.toString(16); expect(signature.slice(0, 130) + vHex).equal(fixSignature(signature)); @@ -79,7 +83,7 @@ describe('utils', async function () { }); }); - async function deployUSDT () { + async function deployUSDT() { const TokenMock = await ethers.getContractFactory('TokenMock'); const usdt = await TokenMock.deploy('USDT', 'USDT'); await usdt.mint(signer1.address, ether('1000')); @@ -90,10 +94,8 @@ describe('utils', async function () { it('should be tracked ERC20 Transfer', async function () { const { usdt } = await loadFixture(deployUSDT); - const [received, tx] = await trackReceivedTokenAndTx( - usdt, - signer2.address, - () => usdt.transfer(signer2.address, ether('1')), + const [received, tx] = await trackReceivedTokenAndTx(usdt, signer2.address, () => + usdt.transfer(signer2.address, ether('1')), ); expect(received).to.be.equal(ether('1')); expect(tx.data.length).equal(138); @@ -107,10 +109,8 @@ describe('utils', async function () { it('should be tracked ERC20 Approve', async function () { const { usdt } = await loadFixture(deployUSDT); - const [received, tx] = await trackReceivedTokenAndTx( - usdt, - signer2.address, - () => usdt.approve(signer2.address, ether('1')), + const [received, tx] = await trackReceivedTokenAndTx(usdt, signer2.address, () => + usdt.approve(signer2.address, ether('1')), ); expect(received).to.be.equal('0'); expect(tx.data.length).equal(138); @@ -126,10 +126,8 @@ describe('utils', async function () { it('should be tracked ERC20 Transfer', async function () { const { usdt } = await loadFixture(deployUSDT); - const [received] = await trackReceivedTokenAndTx( - usdt, - signer2.address, - () => usdt.transfer(signer2.address, ether('1')), + const [received] = await trackReceivedTokenAndTx(usdt, signer2.address, () => + usdt.transfer(signer2.address, ether('1')), ); expect(received).to.be.equal(ether('1')); }); @@ -137,10 +135,8 @@ describe('utils', async function () { it('should be tracked ERC20 Approve', async function () { const { usdt } = await loadFixture(deployUSDT); - const [received] = await trackReceivedTokenAndTx( - usdt, - signer2.address, - () => usdt.approve(signer2.address, ether('1')), + const [received] = await trackReceivedTokenAndTx(usdt, signer2.address, () => + usdt.approve(signer2.address, ether('1')), ); expect(received).to.be.equal('0'); }); @@ -150,25 +146,23 @@ describe('utils', async function () { it('should be counted ERC20 Transfer', async function () { const { usdt } = await loadFixture(deployUSDT); - const [, tx] = await trackReceivedTokenAndTx( - usdt, - signer2.address, - () => usdt.transfer(signer2.address, ether('1')), + const [, tx] = await trackReceivedTokenAndTx(usdt, signer2.address, () => + usdt.transfer(signer2.address, ether('1')), ); - expect(await countInstructions(tx.hash, ['STATICCALL', 'CALL', 'SSTORE', 'SLOAD'])) - .to.be.deep.equal([0, 0, 2, 2]); + expect(await countInstructions(tx.hash, ['STATICCALL', 'CALL', 'SSTORE', 'SLOAD'])).to.be.deep.equal([ + 0, 0, 2, 2, + ]); }); it('should be counted ERC20 Approve', async function () { const { usdt } = await loadFixture(deployUSDT); - const [, tx] = await trackReceivedTokenAndTx( - usdt, - signer2.address, - () => usdt.approve(signer2.address, ether('1')), + const [, tx] = await trackReceivedTokenAndTx(usdt, signer2.address, () => + usdt.approve(signer2.address, ether('1')), ); - expect(await countInstructions(tx.hash, ['STATICCALL', 'CALL', 'SSTORE', 'SLOAD'])) - .to.be.deep.equal([0, 0, 1, 0]); + expect(await countInstructions(tx.hash, ['STATICCALL', 'CALL', 'SSTORE', 'SLOAD'])).to.be.deep.equal([ + 0, 0, 1, 0, + ]); }); }); });