diff --git a/test/gas-report/poolsize.js b/test/gas-report/poolsize.js index 315340f1..13132cc8 100644 --- a/test/gas-report/poolsize.js +++ b/test/gas-report/poolsize.js @@ -1,5 +1,5 @@ import RPC from "../../utils/rpc" -import {web3, ethers} from "hardhat" +import {ethers} from "hardhat" import setupIntegrationTest from "../helpers/setupIntegrationTest" import chai from "chai" @@ -40,7 +40,7 @@ describe("transcoder pool size gas report", () => { } before(async () => { - rpc = new RPC(web3) + rpc = new RPC(ethers.provider) const fixture = await setupIntegrationTest() controller = await ethers.getContractAt( diff --git a/test/gas-report/redeemTicket.js b/test/gas-report/redeemTicket.js index ece7a59e..a12c0e3b 100644 --- a/test/gas-report/redeemTicket.js +++ b/test/gas-report/redeemTicket.js @@ -34,7 +34,7 @@ describe("redeem ticket gas report", () => { let signers before(async () => { - rpc = new RPC(web3) + rpc = new RPC(ethers.provider) signers = await ethers.getSigners() transcoder = signers[0] broadcaster = signers[1] diff --git a/test/helpers/signMsg.js b/test/helpers/signMsg.ts similarity index 51% rename from test/helpers/signMsg.js rename to test/helpers/signMsg.ts index 331b4eea..47d3887c 100644 --- a/test/helpers/signMsg.js +++ b/test/helpers/signMsg.ts @@ -1,36 +1,47 @@ -export const getLongSigV = signature => { +import {Signer} from "ethers" +import {ethers} from "hardhat" + +export const getLongSigV = (signature: string) => { return parseInt(signature.slice(signature.length - 2, signature.length), 16) } -export const getEIP2098V = signature => { +export const getEIP2098V = (signature: string) => { // uint8 v = uint8((uint256(vs) >> 255) + 27); - const sigToBytes = web3.utils.hexToBytes(signature) + const sigToBytes = ethers.utils.arrayify(signature) const v = (sigToBytes[32] >> 7) + 27 return v } -export const fixSig = sig => { +export const fixSig = (signature: string) => { // The recover() in ECDSA.sol from openzeppelin-solidity requires signatures to have a v-value that is 27/28 // ETH clients that implement eth_sign will return a signature with a v-value that is 27/28 or 0/1 (geth returns 27/28 and ganache returns 0/1) // In order to support all ETH clients that implement eth_sign, we can fix the signature by ensuring that the v-value is 27/28 - let v = getLongSigV(sig) + let v = getLongSigV(signature) if (v < 27) { v += 27 } - return sig.slice(0, sig.length - 2) + v.toString(16) + return signature.slice(0, signature.length - 2) + v.toString(16) } -export const web3Sign = async (msg, account) => { - return web3.eth.sign(msg, account) +export const sign = async (msg: string, account: string | Signer) => { + if (typeof account === "string") { + const acc = ethers.provider.getSigner(account) + return acc.signMessage(ethers.utils.arrayify(msg)) + } else { + return account.signMessage(ethers.utils.arrayify(msg)) + } } -export default async (msg, account) => { - return fixSig(await web3Sign(msg, account)) +export default async (msg: string, account: string) => { + return fixSig(await sign(msg, account)) } -export const flipV = sig => { - let v = parseInt(sig.slice(sig.length - 2, sig.length), 16) +export const flipV = (signature: string) => { + let v = parseInt( + signature.slice(signature.length - 2, signature.length), + 16 + ) if (v === 27) { v = 28 } else if (v === 28) { @@ -38,13 +49,15 @@ export const flipV = sig => { } else { throw new Error(`unrecognized V value ${v}`) } - const result = sig.slice(0, sig.length - 2).concat(v.toString(16)) + const result = signature + .slice(0, signature.length - 2) + .concat(v.toString(16)) return result } // from openzeppelin [https://github.com/OpenZeppelin/openzeppelin-contracts/blob/5b28259dacf47fc208e03611eb3ba8eeaed63cc0/test/utils/cryptography/ECDSA.test.js#L12-L33] -export function to2098Format(signature) { - const long = web3.utils.hexToBytes(signature) +export function to2098Format(signature: string) { + const long = ethers.utils.arrayify(signature) if (long.length !== 65) { throw new Error("invalid signature length (expected long format)") @@ -54,16 +67,19 @@ export function to2098Format(signature) { } const short = long.slice(0, 64) short[32] |= long[64] % 27 << 7 // set the first bit of the 32nd byte to the v parity bit - return web3.utils.bytesToHex(short) + return ethers.utils.hexlify(short) } // from openzeppelin [https://github.com/OpenZeppelin/openzeppelin-contracts/blob/5b28259dacf47fc208e03611eb3ba8eeaed63cc0/test/utils/cryptography/ECDSA.test.js#L12-L33] -export function from2098Format(signature) { - const short = web3.utils.hexToBytes(signature) +export function from2098Format(signature: string) { + const short = ethers.utils.arrayify(signature) if (short.length !== 64) { throw new Error("invalid signature length (expected short format)") } - short.push((short[32] >> 7) + 27) - short[32] &= (1 << 7) - 1 // zero out the first bit of 1 the 32nd byte - return web3.utils.bytesToHex(short) + const long = new Uint8Array(65) + long.set(short, 0) + long[64] = (short[32] >> 7) + 27 + + long[32] &= (1 << 7) - 1 // zero out the first bit of 1 the 32nd byte + return ethers.utils.hexlify(long) } diff --git a/test/integration/PoolUpdatesWithHints.js b/test/integration/PoolUpdatesWithHints.js index 71df97d1..908896d6 100644 --- a/test/integration/PoolUpdatesWithHints.js +++ b/test/integration/PoolUpdatesWithHints.js @@ -80,7 +80,7 @@ describe("PoolUpdatesWithHints", () => { transcoders = signers.slice(0, 10) delegator = signers[11] newTranscoder = signers[12] - rpc = new RPC(web3) + rpc = new RPC(ethers.provider) const fixture = await setupIntegrationTest() controller = await ethers.getContractAt( diff --git a/test/unit/BondingManager.js b/test/unit/BondingManager.js index b98e44d5..bcb812cc 100644 --- a/test/unit/BondingManager.js +++ b/test/unit/BondingManager.js @@ -7,7 +7,7 @@ import { import {constants} from "../../utils/constants" import math from "../helpers/math" import {assert} from "chai" -import {ethers, web3} from "hardhat" +import {ethers} from "hardhat" const BigNumber = ethers.BigNumber import chai from "chai" import {solidity} from "ethereum-waffle" @@ -49,7 +49,7 @@ describe("BondingManager", () => { let signers before(async () => { signers = await ethers.getSigners() - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) await fixture.deploy() const llFac = await ethers.getContractFactory("SortedDoublyLL") diff --git a/test/unit/Controller.js b/test/unit/Controller.js index 7669ce70..e77a534e 100644 --- a/test/unit/Controller.js +++ b/test/unit/Controller.js @@ -1,6 +1,6 @@ import Fixture from "./helpers/Fixture" import {contractId} from "../../utils/helpers" -import {web3, ethers} from "hardhat" +import {ethers} from "hardhat" import chai, {expect, assert} from "chai" import {solidity} from "ethereum-waffle" @@ -14,7 +14,7 @@ describe("Controller", () => { before(async () => { signers = await ethers.getSigners() - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) await fixture.deploy() controller = fixture.controller commitHash = fixture.commitHash diff --git a/test/unit/Governor.js b/test/unit/Governor.js index e04ff8f1..e0f97569 100644 --- a/test/unit/Governor.js +++ b/test/unit/Governor.js @@ -16,7 +16,7 @@ describe("Governor", () => { before(async () => { signers = await ethers.getSigners() - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) await fixture.deploy() const govFac = await ethers.getContractFactory("Governor") governor = await govFac.deploy() diff --git a/test/unit/LivepeerTokenFaucet.js b/test/unit/LivepeerTokenFaucet.js index ce84c822..65c9b11c 100644 --- a/test/unit/LivepeerTokenFaucet.js +++ b/test/unit/LivepeerTokenFaucet.js @@ -15,7 +15,7 @@ describe("LivepeerTokenFaucet", () => { let signers before(async () => { - rpc = new RPC(web3) + rpc = new RPC(ethers.provider) signers = await ethers.getSigners() const tokenFac = await ethers.getContractFactory("LivepeerToken") const faucetFac = await ethers.getContractFactory("LivepeerTokenFaucet") diff --git a/test/unit/ManagerProxy.js b/test/unit/ManagerProxy.js index 71f2137b..2851ff5f 100644 --- a/test/unit/ManagerProxy.js +++ b/test/unit/ManagerProxy.js @@ -38,7 +38,7 @@ describe("ManagerProxy", () => { before(async () => { signers = await ethers.getSigners() - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) await fixture.deploy() await fixture.deployAndRegister( await ethers.getContractFactory("ManagerProxyTargetMockV1"), diff --git a/test/unit/MerkleSnapshot.js b/test/unit/MerkleSnapshot.js index 3d03ce1d..9e5cf2aa 100644 --- a/test/unit/MerkleSnapshot.js +++ b/test/unit/MerkleSnapshot.js @@ -1,7 +1,7 @@ import {keccak256, bufferToHex} from "ethereumjs-util" import MerkleTree from "../../utils/merkleTree" import Fixture from "./helpers/Fixture" -import {web3, ethers} from "hardhat" +import {ethers} from "hardhat" import chai, {expect, assert} from "chai" import {solidity} from "ethereum-waffle" chai.use(solidity) @@ -13,7 +13,7 @@ describe("MerkleSnapshot", () => { before(async () => { signers = await ethers.getSigners() - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) await fixture.deploy() const merkleFac = await ethers.getContractFactory("MerkleSnapshot") merkleSnapshot = await merkleFac.deploy(fixture.controller.address) diff --git a/test/unit/Minter.js b/test/unit/Minter.js index b329f21c..de6f97d6 100644 --- a/test/unit/Minter.js +++ b/test/unit/Minter.js @@ -98,7 +98,7 @@ describe("Minter", () => { }) before(async () => { - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) await fixture.deploy() minter = await fixture.deployAndRegister( diff --git a/test/unit/Poll.js b/test/unit/Poll.js index 2cb97158..a91a6a8b 100644 --- a/test/unit/Poll.js +++ b/test/unit/Poll.js @@ -15,7 +15,7 @@ describe("Poll", () => { before(async () => { signers = await ethers.getSigners() - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) }) beforeEach(async () => { diff --git a/test/unit/PollCreator.js b/test/unit/PollCreator.js index 4b3c0a16..5a846220 100644 --- a/test/unit/PollCreator.js +++ b/test/unit/PollCreator.js @@ -1,5 +1,5 @@ import Fixture from "./helpers/Fixture" -import {web3, ethers} from "hardhat" +import {ethers} from "hardhat" import {expect, use} from "chai" import {solidity} from "ethereum-waffle" @@ -22,7 +22,7 @@ describe("PollCreator", () => { before(async () => { ;[, mockBondingManagerEOA] = await ethers.getSigners() - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) bondingManagerMock = await smock.fake( "contracts/polling/PollCreator.sol:IBondingManager", diff --git a/test/unit/RoundsManager.js b/test/unit/RoundsManager.js index 65597380..61bab0b4 100644 --- a/test/unit/RoundsManager.js +++ b/test/unit/RoundsManager.js @@ -21,7 +21,7 @@ describe("RoundsManager", () => { before(async () => { signers = await ethers.getSigners() - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) await fixture.deploy() roundsManager = await fixture.deployAndRegister( diff --git a/test/unit/ServiceRegistry.js b/test/unit/ServiceRegistry.js index 30924d4e..2c0fec42 100644 --- a/test/unit/ServiceRegistry.js +++ b/test/unit/ServiceRegistry.js @@ -1,5 +1,5 @@ import Fixture from "./helpers/Fixture" -import {web3, ethers} from "hardhat" +import {ethers} from "hardhat" import chai, {expect, assert} from "chai" import {solidity} from "ethereum-waffle" @@ -12,7 +12,7 @@ describe("ServiceRegistry", () => { let controller before(async () => { signers = await ethers.getSigners() - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) // Use dummy Controller in these unit tests // We are testing the logic of ServiceRegistry directly so we do not // interact with the contract via a proxy diff --git a/test/unit/TicketBroker.js b/test/unit/TicketBroker.js index ea1f1130..73cb4574 100644 --- a/test/unit/TicketBroker.js +++ b/test/unit/TicketBroker.js @@ -43,7 +43,7 @@ describe("TicketBroker", () => { sender = signers[0].address recipient = signers[1].address funder = signers[3] - fixture = new Fixture(web3) + fixture = new Fixture(ethers.provider) await fixture.deploy() broker = await ( @@ -889,7 +889,7 @@ describe("TicketBroker", () => { const recipientRand = 5 const recipientRandHash = web3.utils.soliditySha3(recipientRand) - const sig = await signMsg("junk", sender) + const sig = await signMsg("0xdabbad00", sender) await expect( broker.redeemWinningTicket( diff --git a/test/unit/helpers/Fixture.js b/test/unit/helpers/Fixture.js index e806dfdf..f8e12983 100644 --- a/test/unit/helpers/Fixture.js +++ b/test/unit/helpers/Fixture.js @@ -3,8 +3,8 @@ import {contractId} from "../../../utils/helpers" import {ethers} from "hardhat" export default class Fixture { - constructor(web3) { - this.rpc = new RPC(web3) + constructor(provider) { + this.rpc = new RPC(provider) this.commitHash = "0x3031323334353637383930313233343536373839" } diff --git a/utils/rpc.js b/utils/rpc.js deleted file mode 100644 index 970ac47e..00000000 --- a/utils/rpc.js +++ /dev/null @@ -1,94 +0,0 @@ -export default class RPC { - constructor(web3) { - this.web3 = web3 - } - - sendAsync(method, arg) { - const req = { - jsonrpc: "2.0", - method: method, - id: new Date().getTime() - } - - if (arg) req.params = arg - - return new Promise((resolve, reject) => { - return this.web3.currentProvider.send(req, (err, result) => { - if (err) { - reject(err) - } else if (result && result.error) { - reject(new Error("RPC Error: " + (result.error.message || result.error))) - } else { - resolve(result) - } - }) - }) - } - - // Change block time using TestRPC call evm_setTimestamp - // https://github.com/numerai/contract/blob/master/test/numeraire.js - increaseTime(time) { - return this.sendAsync("evm_increaseTime", [time]) - } - - mine() { - return this.sendAsync("evm_mine") - } - - snapshot() { - return this.sendAsync("evm_snapshot") - .then(res => res.result) - } - - revert(snapshotId) { - return this.sendAsync("evm_revert", [snapshotId]) - } - - async wait(blocks = 1, seconds = 20) { - const currentBlock = await this.getBlockNumberAsync() - const targetBlock = currentBlock + blocks - await this.waitUntilBlock(targetBlock, seconds) - } - - async waitUntilBlock(targetBlock, seconds = 20) { - let currentBlock = await this.getBlockNumberAsync() - - while (currentBlock < targetBlock) { - await this.increaseTime(seconds) - await this.mine() - currentBlock++ - } - } - - async waitUntilNextBlockMultiple(blockMultiple, multiples = 1, seconds = 20) { - const currentBlock = await this.getBlockNumberAsync() - const additionalBlocks = (multiples - 1) * blockMultiple - await this.waitUntilBlock(this.nextBlockMultiple(currentBlock, blockMultiple) + additionalBlocks) - } - - getBlockNumberAsync() { - return new Promise((resolve, reject) => { - return this.web3.eth.getBlockNumber((err, blockNum) => { - if (err) { - reject(err) - } else { - resolve(blockNum) - } - }) - }) - } - - nextBlockMultiple(currentBlockNum, blockMultiple) { - if (blockMultiple === 0) { - return currentBlockNum - } - - const remainder = currentBlockNum % blockMultiple - - if (remainder === 0) { - return currentBlockNum - } - - return currentBlockNum + blockMultiple - remainder - } -} diff --git a/utils/rpc.ts b/utils/rpc.ts new file mode 100644 index 00000000..a4f5491e --- /dev/null +++ b/utils/rpc.ts @@ -0,0 +1,79 @@ +import {ethers} from "ethers" + +export default class RPC { + constructor(public provider: ethers.providers.JsonRpcProvider) {} + + sendAsync(method: string, arg: any[]) { + try { + return this.provider.send(method, arg) + } catch (error: any) { + throw error + } + } + + // Change block time using TestRPC call evm_setTimestamp + // https://github.com/numerai/contract/blob/master/test/numeraire.js + increaseTime(time: number) { + return this.sendAsync("evm_increaseTime", [time]) + } + + mine() { + return this.sendAsync("evm_mine", []) + } + + async snapshot() { + const id = await this.sendAsync("evm_snapshot", []) + return id + } + + revert(snapshotId: number) { + return this.sendAsync("evm_revert", [snapshotId]) + } + + async wait(blocks = 1, seconds = 20) { + const currentBlock = await this.provider.getBlockNumber() + const targetBlock = currentBlock + blocks + await this.waitUntilBlock(targetBlock, seconds) + } + + async getBlockNumberAsync() { + return this.provider.getBlockNumber() + } + + async waitUntilBlock(targetBlock: number, seconds = 20) { + let currentBlock = await this.provider.getBlockNumber() + + while (currentBlock < targetBlock) { + await this.increaseTime(seconds) + await this.mine() + currentBlock++ + } + } + + async waitUntilNextBlockMultiple( + blockMultiple: number, + multiples = 1, + seconds = 20 + ) { + const currentBlock = await this.provider.getBlockNumber() + const additionalBlocks = (multiples - 1) * blockMultiple + await this.waitUntilBlock( + this.nextBlockMultiple(currentBlock, blockMultiple) + + additionalBlocks + ) + } + + nextBlockMultiple(currentBlockNum: number, blockMultiple: number) { + if (blockMultiple === 0) { + return currentBlockNum + } + + const remainder = currentBlockNum % blockMultiple + + if (remainder === 0) { + return currentBlockNum + } + + return currentBlockNum + blockMultiple - remainder + } +}