Last active
March 14, 2022 05:54
-
-
Save hakymulla/199936f73a577da50e5ba3b693cc84bc to your computer and use it in GitHub Desktop.
Add a script named custom.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const hre = require('hardhat') | |
const { ethers, waffle } = hre | |
const { loadFixture } = waffle | |
const { expect } = require('chai') | |
const { poseidonHash2, toFixedHex } = require('../src/utils') | |
const MERKLE_TREE_HEIGHT = 5 | |
const MerkleTree = require('fixed-merkle-tree') | |
const { utils } = ethers | |
const Utxo = require('../src/utxo') | |
const { transaction, registerAndTransact, prepareTransaction, buildMerkleTree } = require('../src/index') | |
const { Keypair } = require('../src/keypair') | |
const { encodeDataForBridge } = require('./utils') | |
const l1ChainId = 1 | |
const MINIMUM_WITHDRAWAL_AMOUNT = utils.parseEther(process.env.MINIMUM_WITHDRAWAL_AMOUNT || '0.05') | |
const MAXIMUM_DEPOSIT_AMOUNT = utils.parseEther(process.env.MAXIMUM_DEPOSIT_AMOUNT || '1') | |
describe('Question 2 Test', function () { | |
this.timeout(20000) | |
async function deploy(contractName, ...args) { | |
const Factory = await ethers.getContractFactory(contractName) | |
const instance = await Factory.deploy(...args) | |
return instance.deployed() | |
} | |
async function fixture() { | |
require('../scripts/compileHasher') | |
const [sender, gov, l1Unwrapper, multisig] = await ethers.getSigners() | |
const verifier2 = await deploy('Verifier2') | |
const verifier16 = await deploy('Verifier16') | |
const hasher = await deploy('Hasher') | |
const merkleTreeWithHistory = await deploy( | |
'MerkleTreeWithHistoryMock', | |
MERKLE_TREE_HEIGHT, | |
hasher.address, | |
) | |
await merkleTreeWithHistory.initialize() | |
const token = await deploy('PermittableToken', 'Wrapped ETH', 'WETH', 18, l1ChainId) | |
await token.mint(sender.address, utils.parseEther('10000')) | |
const amb = await deploy('MockAMB', gov.address, l1ChainId) | |
const omniBridge = await deploy('MockOmniBridge', amb.address) | |
/** @type {TornadoPool} */ | |
const tornadoPoolImpl = await deploy( | |
'TornadoPool', | |
verifier2.address, | |
verifier16.address, | |
MERKLE_TREE_HEIGHT, | |
hasher.address, | |
token.address, | |
omniBridge.address, | |
l1Unwrapper.address, | |
gov.address, | |
l1ChainId, | |
multisig.address, | |
) | |
const { data } = await tornadoPoolImpl.populateTransaction.initialize( | |
MINIMUM_WITHDRAWAL_AMOUNT, | |
MAXIMUM_DEPOSIT_AMOUNT, | |
) | |
const proxy = await deploy( | |
'CrossChainUpgradeableProxy', | |
tornadoPoolImpl.address, | |
gov.address, | |
data, | |
amb.address, | |
l1ChainId, | |
) | |
const tornadoPool = tornadoPoolImpl.attach(proxy.address) | |
await token.approve(tornadoPool.address, utils.parseEther('10000')) | |
return { tornadoPool, token, proxy, omniBridge, amb, gov, multisig,hasher, merkleTreeWithHistory } | |
} | |
it('should deposit from L1 and withdraw to L2 Question 2', async function () { | |
const { merkleTreeWithHistory, tornadoPool, token, omniBridge } = await loadFixture(fixture) | |
const gas = await merkleTreeWithHistory.estimateGas.insert(toFixedHex(123), toFixedHex(456)) | |
console.log('gas needed to insert a pair of leaves', gas - 21000) | |
const aliceKeypair = new Keypair() // contains private and public keys | |
// Alice deposits into tornado pool | |
const aliceDepositAmount = utils.parseEther('0.08') | |
const aliceDepositUtxo = new Utxo({ amount: aliceDepositAmount, keypair: aliceKeypair }) | |
const { args, extData } = await prepareTransaction({ | |
tornadoPool, | |
outputs: [aliceDepositUtxo], | |
}) | |
const onTokenBridgedData = encodeDataForBridge({ | |
proof: args, | |
extData, | |
}) | |
const onTokenBridgedTx = await tornadoPool.populateTransaction.onTokenBridged( | |
token.address, | |
aliceDepositUtxo.amount, | |
onTokenBridgedData, | |
) | |
// emulating bridge. first it sends tokens to omnibridge mock then it sends to the pool | |
await token.transfer(omniBridge.address, aliceDepositAmount) | |
const transferTx = await token.populateTransaction.transfer(tornadoPool.address, aliceDepositAmount) | |
await omniBridge.execute([ | |
{ who: token.address, callData: transferTx.data }, // send tokens to pool | |
{ who: tornadoPool.address, callData: onTokenBridgedTx.data }, // call onTokenBridgedTx | |
]) | |
// Alice withdraws a part of his funds from the shielded pool | |
const aliceWithdrawAmount = utils.parseEther('0.05') | |
const AliceEthAddress = '0xDeaD00000000000000000000000000000000BEEf' | |
const aliceChangeUtxo = new Utxo({ | |
amount: aliceDepositAmount.sub(aliceWithdrawAmount), | |
keypair: aliceKeypair, | |
}) | |
await transaction({ | |
tornadoPool, | |
inputs: [aliceDepositUtxo], | |
outputs: [aliceChangeUtxo], | |
recipient: AliceEthAddress, | |
isL1Withdrawal: false | |
}) | |
const AliceEthAddressBalance = await token.balanceOf(AliceEthAddress) | |
console.log("AliceEthAddressBalance ", ethers.utils.formatEther(AliceEthAddressBalance)) | |
expect(AliceEthAddressBalance).to.be.equal(aliceWithdrawAmount) | |
const omniBridgeBalance = await token.balanceOf(omniBridge.address) | |
console.log("omniBridgeBalance ", ethers.utils.formatEther(omniBridgeBalance)) | |
expect(omniBridgeBalance).to.be.equal(0) | |
const tornadoPoolBalance = await token.balanceOf(tornadoPool.address) | |
console.log("tornadoPoolBalance ", ethers.utils.formatEther(tornadoPoolBalance)) | |
expect(tornadoPoolBalance).to.be.equal(aliceDepositAmount.sub(aliceWithdrawAmount)) | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment