2021-08-05 09:29:49 +02:00
|
|
|
/* global network */
|
2021-06-06 19:31:32 +02:00
|
|
|
const crypto = require('crypto')
|
2021-06-09 12:56:33 +02:00
|
|
|
const { ethers } = require('hardhat')
|
2021-06-06 19:31:32 +02:00
|
|
|
const BigNumber = ethers.BigNumber
|
2021-06-09 12:56:33 +02:00
|
|
|
const { poseidon } = require('circomlib')
|
2021-06-06 19:31:32 +02:00
|
|
|
|
|
|
|
const poseidonHash = (items) => BigNumber.from(poseidon(items).toString())
|
|
|
|
const poseidonHash2 = (a, b) => poseidonHash([a, b])
|
|
|
|
|
2021-06-07 12:12:15 +02:00
|
|
|
const FIELD_SIZE = BigNumber.from(
|
|
|
|
'21888242871839275222246405745257275088548364400416034343698204186575808495617',
|
|
|
|
)
|
2021-06-16 02:07:32 +02:00
|
|
|
|
2021-06-06 19:31:32 +02:00
|
|
|
/** Generate random number of specified byte length */
|
|
|
|
const randomBN = (nbytes = 31) => BigNumber.from(crypto.randomBytes(nbytes))
|
|
|
|
|
2021-06-09 12:56:33 +02:00
|
|
|
function getExtDataHash({ recipient, relayer, encryptedOutput1, encryptedOutput2 }) {
|
2021-06-08 20:50:34 +02:00
|
|
|
const abi = new ethers.utils.AbiCoder()
|
|
|
|
|
2021-06-07 12:12:15 +02:00
|
|
|
const encodedData = abi.encode(
|
2021-06-08 20:50:34 +02:00
|
|
|
['tuple(address recipient,address relayer,bytes encryptedOutput1,bytes encryptedOutput2)'],
|
2021-06-09 12:56:33 +02:00
|
|
|
[
|
|
|
|
{
|
2021-06-08 20:50:34 +02:00
|
|
|
recipient: toFixedHex(recipient, 20),
|
|
|
|
relayer: toFixedHex(relayer, 20),
|
|
|
|
encryptedOutput1: encryptedOutput1,
|
|
|
|
encryptedOutput2: encryptedOutput2,
|
2021-06-09 12:56:33 +02:00
|
|
|
},
|
|
|
|
],
|
2021-06-07 12:12:15 +02:00
|
|
|
)
|
|
|
|
const hash = ethers.utils.keccak256(encodedData)
|
|
|
|
return BigNumber.from(hash).mod(FIELD_SIZE)
|
|
|
|
}
|
|
|
|
|
2021-06-06 19:31:32 +02:00
|
|
|
/** BigNumber to hex string of specified length */
|
|
|
|
const toFixedHex = (number, length = 32) =>
|
|
|
|
'0x' +
|
|
|
|
(number instanceof Buffer
|
2021-06-09 12:56:33 +02:00
|
|
|
? number.toString('hex')
|
|
|
|
: BigNumber.from(number).toHexString().slice(2)
|
2021-06-06 19:31:32 +02:00
|
|
|
).padStart(length * 2, '0')
|
|
|
|
|
2021-06-16 02:07:32 +02:00
|
|
|
/** Convert value into buffer of specified byte length */
|
2021-06-06 19:31:32 +02:00
|
|
|
const toBuffer = (value, length) =>
|
|
|
|
Buffer.from(
|
|
|
|
BigNumber.from(value)
|
|
|
|
.toHexString()
|
|
|
|
.slice(2)
|
|
|
|
.padStart(length * 2, '0'),
|
|
|
|
'hex',
|
|
|
|
)
|
|
|
|
|
2021-06-16 14:24:00 +02:00
|
|
|
function shuffle(array) {
|
|
|
|
let currentIndex = array.length
|
|
|
|
let randomIndex
|
|
|
|
|
|
|
|
// While there remain elements to shuffle...
|
|
|
|
while (0 !== currentIndex) {
|
|
|
|
// Pick a remaining element...
|
|
|
|
randomIndex = Math.floor(Math.random() * currentIndex)
|
|
|
|
currentIndex--
|
|
|
|
|
|
|
|
// And swap it with the current element.
|
|
|
|
;[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]
|
|
|
|
}
|
|
|
|
|
|
|
|
return array
|
|
|
|
}
|
2021-06-09 12:56:33 +02:00
|
|
|
async function takeSnapshot() {
|
|
|
|
return await ethers.provider.send('evm_snapshot', [])
|
|
|
|
}
|
|
|
|
|
|
|
|
async function revertSnapshot(id) {
|
|
|
|
await ethers.provider.send('evm_revert', [id])
|
|
|
|
}
|
|
|
|
|
2021-08-05 09:29:49 +02:00
|
|
|
async function getSignerFromAddress(address) {
|
|
|
|
await network.provider.request({
|
|
|
|
method: 'hardhat_impersonateAccount',
|
|
|
|
params: [address],
|
|
|
|
})
|
|
|
|
|
|
|
|
return await ethers.provider.getSigner(address)
|
|
|
|
}
|
|
|
|
|
2021-06-06 19:31:32 +02:00
|
|
|
module.exports = {
|
2021-06-07 12:12:15 +02:00
|
|
|
FIELD_SIZE,
|
2021-06-06 19:31:32 +02:00
|
|
|
randomBN,
|
|
|
|
toFixedHex,
|
|
|
|
toBuffer,
|
|
|
|
poseidonHash,
|
|
|
|
poseidonHash2,
|
2021-06-07 12:12:15 +02:00
|
|
|
getExtDataHash,
|
2021-06-09 12:56:33 +02:00
|
|
|
takeSnapshot,
|
|
|
|
revertSnapshot,
|
2021-06-16 14:24:00 +02:00
|
|
|
shuffle,
|
2021-08-05 09:29:49 +02:00
|
|
|
getSignerFromAddress,
|
2021-06-06 19:31:32 +02:00
|
|
|
}
|