add new instance tests
This commit is contained in:
parent
238363d348
commit
160b2f4cb0
|
@ -3,11 +3,13 @@ module.exports = {
|
||||||
hasher: '0x83584f83f26aF4eDDA9CBe8C730bc87C364b28fe',
|
hasher: '0x83584f83f26aF4eDDA9CBe8C730bc87C364b28fe',
|
||||||
governance: '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
|
governance: '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
|
||||||
instanceRegistry: '0xB20c66C4DE72433F3cE747b58B86830c459CA911',
|
instanceRegistry: '0xB20c66C4DE72433F3cE747b58B86830c459CA911',
|
||||||
|
router: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
|
||||||
merkleTreeHeight: 20,
|
merkleTreeHeight: 20,
|
||||||
singletonFactory: '0xce0042B868300000d44A59004Da54A005ffdcf9f',
|
singletonFactory: '0xce0042B868300000d44A59004Da54A005ffdcf9f',
|
||||||
salt: '0x0000000000000000000000000000000000000000000000000000000047941987',
|
salt: '0x0000000000000000000000000000000000000000000000000000000047941987',
|
||||||
COMP: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
|
COMP: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
|
||||||
TORN: '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
|
TORN: '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
|
||||||
tornWhale: '0xF977814e90dA44bFA03b6295A0616a897441aceC',
|
tornWhale: '0xF977814e90dA44bFA03b6295A0616a897441aceC',
|
||||||
|
compWhale: '0xF977814e90dA44bFA03b6295A0616a897441aceC',
|
||||||
creationFee: '200000000000000000000', // 200 TORN
|
creationFee: '200000000000000000000', // 200 TORN
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,6 @@ const { ethers, waffle } = hre
|
||||||
const { loadFixture } = waffle
|
const { loadFixture } = waffle
|
||||||
const { expect } = require('chai')
|
const { expect } = require('chai')
|
||||||
const { BigNumber } = require('@ethersproject/bignumber')
|
const { BigNumber } = require('@ethersproject/bignumber')
|
||||||
const { rbigint, createDeposit, toHex, generateProof, initialize } = require('tornado-cli')
|
|
||||||
const MixerContractABI = require('tornado-cli/build/contracts/Mixer.abi.json')
|
|
||||||
const config = require('../config')
|
const config = require('../config')
|
||||||
const { getSignerFromAddress, minewait } = require('./utils')
|
const { getSignerFromAddress, minewait } = require('./utils')
|
||||||
const { PermitSigner } = require('../scripts/permit.js')
|
const { PermitSigner } = require('../scripts/permit.js')
|
||||||
|
@ -39,13 +37,13 @@ describe('Instance Factory Tests', () => {
|
||||||
config.COMP,
|
config.COMP,
|
||||||
)
|
)
|
||||||
|
|
||||||
instanceRegistry = await ethers.getContractAt(
|
const instanceRegistry = await ethers.getContractAt(
|
||||||
'tornado-relayer-registry/contracts/tornado-proxy/InstanceRegistry.sol:InstanceRegistry',
|
'tornado-relayer-registry/contracts/tornado-proxy/InstanceRegistry.sol:InstanceRegistry',
|
||||||
config.instanceRegistry,
|
config.instanceRegistry,
|
||||||
)
|
)
|
||||||
|
|
||||||
// deploy instance factory
|
// deploy instance factory
|
||||||
InstanceFactory = await ethers.getContractFactory('InstanceFactory')
|
const InstanceFactory = await ethers.getContractFactory('InstanceFactory')
|
||||||
const instanceFactory = await InstanceFactory.connect(deployer).deploy(
|
const instanceFactory = await InstanceFactory.connect(deployer).deploy(
|
||||||
config.verifier,
|
config.verifier,
|
||||||
config.hasher,
|
config.hasher,
|
||||||
|
@ -137,10 +135,10 @@ describe('Instance Factory Tests', () => {
|
||||||
[BigNumber.from(0).sub(config.creationFee), config.creationFee],
|
[BigNumber.from(0).sub(config.creationFee), config.creationFee],
|
||||||
)
|
)
|
||||||
|
|
||||||
let logs = await ethers.provider.getLogs(instanceFactory.filters.NewGovernanceProposalCreated())
|
let logs = await instanceFactory.queryFilter('NewGovernanceProposalCreated')
|
||||||
const proposal = await ethers.getContractAt(
|
const proposal = await ethers.getContractAt(
|
||||||
'AddInstanceProposal',
|
'AddInstanceProposal',
|
||||||
ethers.utils.getAddress('0x' + logs[0].topics[1].slice(26)),
|
ethers.utils.getAddress('0x' + logs[0].topics[1].slice(-40)),
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(await proposal.instanceFactory()).to.be.equal(instanceFactory.address)
|
expect(await proposal.instanceFactory()).to.be.equal(instanceFactory.address)
|
||||||
|
@ -183,12 +181,12 @@ describe('Instance Factory Tests', () => {
|
||||||
)
|
)
|
||||||
expect(await gov.state(id)).to.be.equal(ProposalState.AwaitingExecution)
|
expect(await gov.state(id)).to.be.equal(ProposalState.AwaitingExecution)
|
||||||
|
|
||||||
tx = await gov.execute(id)
|
let tx = await gov.execute(id)
|
||||||
|
|
||||||
expect(await gov.state(id)).to.be.equal(ProposalState.Executed)
|
expect(await gov.state(id)).to.be.equal(ProposalState.Executed)
|
||||||
|
|
||||||
// check instance initialization --------------------------------
|
// check instance initialization --------------------------------
|
||||||
receipt = await tx.wait()
|
let receipt = await tx.wait()
|
||||||
const instanceAddr = '0x' + receipt.events[0].topics[1].toString().slice(-40)
|
const instanceAddr = '0x' + receipt.events[0].topics[1].toString().slice(-40)
|
||||||
const instance = await ethers.getContractAt('ERC20TornadoCloneable', instanceAddr)
|
const instance = await ethers.getContractAt('ERC20TornadoCloneable', instanceAddr)
|
||||||
|
|
||||||
|
@ -261,10 +259,10 @@ describe('Instance Factory Tests', () => {
|
||||||
[BigNumber.from(0).sub(config.creationFee), config.creationFee],
|
[BigNumber.from(0).sub(config.creationFee), config.creationFee],
|
||||||
)
|
)
|
||||||
|
|
||||||
let logs = await ethers.provider.getLogs(instanceFactory.filters.NewGovernanceProposalCreated())
|
let logs = await instanceFactory.queryFilter('NewGovernanceProposalCreated')
|
||||||
const proposal = await ethers.getContractAt(
|
const proposal = await ethers.getContractAt(
|
||||||
'AddInstanceProposal',
|
'AddInstanceProposal',
|
||||||
ethers.utils.getAddress('0x' + logs[0].topics[1].slice(26)),
|
ethers.utils.getAddress('0x' + logs[0].topics[1].slice(-40)),
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(await proposal.instanceFactory()).to.be.equal(instanceFactory.address)
|
expect(await proposal.instanceFactory()).to.be.equal(instanceFactory.address)
|
||||||
|
@ -275,123 +273,4 @@ describe('Instance Factory Tests', () => {
|
||||||
expect(await proposal.protocolFeeByIndex(0)).to.be.equal(30)
|
expect(await proposal.protocolFeeByIndex(0)).to.be.equal(30)
|
||||||
expect(await proposal.denominationByIndex(0)).to.be.equal(ethers.utils.parseEther('100'))
|
expect(await proposal.denominationByIndex(0)).to.be.equal(ethers.utils.parseEther('100'))
|
||||||
})
|
})
|
||||||
|
|
||||||
// it('Should prepare data for instance deposit/withdraw tests', async () => {
|
|
||||||
// const RAITokenAddress = '0x03ab458634910AaD20eF5f1C8ee96F1D6ac54919'
|
|
||||||
// await sendr('hardhat_impersonateAccount', ['0x46a0B4Fa58141ABa23185e79f7047A7dFd0FF100'])
|
|
||||||
// RAIToken = await ethers.getContractAt(
|
|
||||||
// '@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20',
|
|
||||||
// RAITokenAddress,
|
|
||||||
// )
|
|
||||||
// whaleRAI = await ethers.getSigner('0x46a0B4Fa58141ABa23185e79f7047A7dFd0FF100')
|
|
||||||
|
|
||||||
// const tx = {
|
|
||||||
// to: whaleRAI.address,
|
|
||||||
// value: pE(50),
|
|
||||||
// }
|
|
||||||
// await accounts[0].sendTransaction(tx)
|
|
||||||
|
|
||||||
// whaleRAIBalance = await RAIToken.balanceOf(whaleRAI.address)
|
|
||||||
// RAIToken = await RAIToken.connect(whaleRAI)
|
|
||||||
// TornadoProxy = await TornadoProxy.connect(whaleRAI)
|
|
||||||
|
|
||||||
// for (let i = 0; i < 4; i++) {
|
|
||||||
// instanceAddresses[i] = await TornadoInstanceFactoryContract.getInstanceAddress(
|
|
||||||
// denominations[i],
|
|
||||||
// RAIToken.address,
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
|
|
||||||
// mixerContract = await ethers.getContractAt(MixerContractABI, instanceAddresses[0])
|
|
||||||
// mixerContract = await mixerContract.connect(whaleRAI)
|
|
||||||
|
|
||||||
// snapshotId = await sendr('evm_snapshot', [])
|
|
||||||
// })
|
|
||||||
|
|
||||||
// it('Should test depositing and withdrawing into the new instance over proxy', async () => {
|
|
||||||
// const depo = createDeposit({
|
|
||||||
// nullifier: rbigint(31),
|
|
||||||
// secret: rbigint(31),
|
|
||||||
// })
|
|
||||||
|
|
||||||
// // const note = toHex(depo.preimage, 62)
|
|
||||||
// // const noteString = `tornado-RAI-33-1-${note}`
|
|
||||||
// // clog('Note: ', note)
|
|
||||||
// // clog('Note string: ', noteString)
|
|
||||||
// // clog('Commitment: ', toHex(depo.commitment))
|
|
||||||
|
|
||||||
// await expect(RAIToken.approve(TornadoProxy.address, pE(5000000))).to.not.be.reverted
|
|
||||||
// TornadoInstance = await ethers.getContractAt(
|
|
||||||
// 'contracts/tornado_proxy/ITornadoInstance.sol:ITornadoInstance',
|
|
||||||
// instanceAddresses[0],
|
|
||||||
// )
|
|
||||||
|
|
||||||
// await expect(() =>
|
|
||||||
// TornadoProxy.deposit(instanceAddresses[0], toHex(depo.commitment), []),
|
|
||||||
// ).to.changeTokenBalance(RAIToken, whaleRAI, BigNumber.from(0).sub(await TornadoInstance.denomination()))
|
|
||||||
|
|
||||||
// let pevents = await mixerContract.queryFilter('Deposit')
|
|
||||||
// await initialize({ merkleTreeHeight: 20 })
|
|
||||||
|
|
||||||
// const { proof, args } = await generateProof({
|
|
||||||
// deposit: depo,
|
|
||||||
// recipient: whaleRAI.address,
|
|
||||||
// events: pevents,
|
|
||||||
// })
|
|
||||||
|
|
||||||
// await expect(() =>
|
|
||||||
// TornadoProxy.withdraw(TornadoInstance.address, proof, ...args),
|
|
||||||
// ).to.changeTokenBalance(RAIToken, whaleRAI, await TornadoInstance.denomination())
|
|
||||||
|
|
||||||
// await sendr('evm_revert', [snapshotId])
|
|
||||||
// snapshotId = await sendr('evm_snapshot', [])
|
|
||||||
// })
|
|
||||||
|
|
||||||
// it('Should prepare for multiple account deposits', async () => {
|
|
||||||
// let toSend = whaleRAIBalance.div(5)
|
|
||||||
|
|
||||||
// for (let i = 0; i < 3; i++) {
|
|
||||||
// await RAIToken.transfer(accounts[i].address, toSend)
|
|
||||||
// const rai = await RAIToken.connect(accounts[i])
|
|
||||||
// await rai.approve(TornadoProxy.address, pE(600000))
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// it('Should test depositing with multiple accounts over proxy', async () => {
|
|
||||||
// for (let i = 0; i < 3; i++) {
|
|
||||||
// const depo = createDeposit({
|
|
||||||
// nullifier: rbigint(31),
|
|
||||||
// secret: rbigint(31),
|
|
||||||
// })
|
|
||||||
// // const note = toHex(depo.preimage, 62)
|
|
||||||
// // const noteString = `tornado-RAI-33-1-${note}`
|
|
||||||
// // clog('Note: ', note)
|
|
||||||
// // clog('Note string: ', noteString)
|
|
||||||
// // clog('Commitment: ', toHex(depo.commitment))
|
|
||||||
// const proxy = await TornadoProxy.connect(accounts[i])
|
|
||||||
|
|
||||||
// await expect(() =>
|
|
||||||
// proxy.deposit(TornadoInstance.address, toHex(depo.commitment), []),
|
|
||||||
// ).to.changeTokenBalance(
|
|
||||||
// RAIToken,
|
|
||||||
// accounts[i],
|
|
||||||
// BigNumber.from(0).sub(await TornadoInstance.denomination()),
|
|
||||||
// )
|
|
||||||
|
|
||||||
// let pevents = await mixerContract.queryFilter('Deposit')
|
|
||||||
// await initialize({ merkleTreeHeight: 20 })
|
|
||||||
|
|
||||||
// const { proof, args } = await generateProof({
|
|
||||||
// deposit: depo,
|
|
||||||
// recipient: accounts[i].address,
|
|
||||||
// events: pevents,
|
|
||||||
// })
|
|
||||||
|
|
||||||
// await expect(() => proxy.withdraw(TornadoInstance.address, proof, ...args)).to.changeTokenBalance(
|
|
||||||
// RAIToken,
|
|
||||||
// accounts[i],
|
|
||||||
// await TornadoInstance.denomination(),
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
})
|
})
|
|
@ -0,0 +1,165 @@
|
||||||
|
const hre = require('hardhat')
|
||||||
|
const { ethers, waffle } = hre
|
||||||
|
const { loadFixture } = waffle
|
||||||
|
const { expect } = require('chai')
|
||||||
|
const { BigNumber } = require('@ethersproject/bignumber')
|
||||||
|
const { rbigint, createDeposit, toHex, generateProof, initialize } = require('tornado-cli')
|
||||||
|
const config = require('../config')
|
||||||
|
const { getSignerFromAddress, minewait } = require('./utils')
|
||||||
|
|
||||||
|
describe('Instance Factory Tests', () => {
|
||||||
|
const ProposalState = {
|
||||||
|
Pending: 0,
|
||||||
|
Active: 1,
|
||||||
|
Defeated: 2,
|
||||||
|
Timelocked: 3,
|
||||||
|
AwaitingExecution: 4,
|
||||||
|
Executed: 5,
|
||||||
|
Expired: 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fixture() {
|
||||||
|
const [sender, deployer, multisig] = await ethers.getSigners()
|
||||||
|
|
||||||
|
const tornWhale = await getSignerFromAddress(config.tornWhale)
|
||||||
|
const compWhale = await getSignerFromAddress(config.compWhale)
|
||||||
|
|
||||||
|
let gov = await ethers.getContractAt('Governance', config.governance)
|
||||||
|
|
||||||
|
const tornToken = await ethers.getContractAt(
|
||||||
|
'@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20',
|
||||||
|
config.TORN,
|
||||||
|
)
|
||||||
|
|
||||||
|
const compToken = await ethers.getContractAt(
|
||||||
|
'@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20',
|
||||||
|
config.COMP,
|
||||||
|
)
|
||||||
|
|
||||||
|
const instanceRegistry = await ethers.getContractAt(
|
||||||
|
'tornado-relayer-registry/contracts/tornado-proxy/InstanceRegistry.sol:InstanceRegistry',
|
||||||
|
config.instanceRegistry,
|
||||||
|
)
|
||||||
|
|
||||||
|
const router = await ethers.getContractAt(
|
||||||
|
'tornado-relayer-registry/contracts/tornado-proxy/TornadoRouter.sol:TornadoRouter',
|
||||||
|
config.router,
|
||||||
|
)
|
||||||
|
|
||||||
|
// deploy instance factory
|
||||||
|
const InstanceFactory = await ethers.getContractFactory('InstanceFactory')
|
||||||
|
const instanceFactory = await InstanceFactory.connect(deployer).deploy(
|
||||||
|
config.verifier,
|
||||||
|
config.hasher,
|
||||||
|
config.merkleTreeHeight,
|
||||||
|
config.governance,
|
||||||
|
config.instanceRegistry,
|
||||||
|
config.TORN,
|
||||||
|
config.creationFee,
|
||||||
|
)
|
||||||
|
await instanceFactory.deployed()
|
||||||
|
|
||||||
|
// deploy proposal
|
||||||
|
await tornToken.connect(tornWhale).transfer(sender.address, config.creationFee)
|
||||||
|
await tornToken.approve(instanceFactory.address, config.creationFee)
|
||||||
|
|
||||||
|
await instanceFactory
|
||||||
|
.connect(sender)
|
||||||
|
.createProposalApprove(config.COMP, 3000, [ethers.utils.parseEther('100')], [30])
|
||||||
|
|
||||||
|
let logs = await instanceFactory.queryFilter('NewGovernanceProposalCreated')
|
||||||
|
const proposal = await ethers.getContractAt(
|
||||||
|
'AddInstanceProposal',
|
||||||
|
ethers.utils.getAddress('0x' + logs[0].topics[1].slice(-40)),
|
||||||
|
)
|
||||||
|
|
||||||
|
// propose proposal
|
||||||
|
gov = await gov.connect(tornWhale)
|
||||||
|
await tornToken.connect(tornWhale).approve(gov.address, ethers.utils.parseEther('26000'))
|
||||||
|
await gov.lockWithApproval(ethers.utils.parseEther('26000'))
|
||||||
|
await gov.propose(proposal.address, 'COMP token instance proposal')
|
||||||
|
const id = await gov.latestProposalIds(tornWhale.address)
|
||||||
|
|
||||||
|
// execute proposal
|
||||||
|
await minewait((await gov.VOTING_DELAY()).add(1).toNumber())
|
||||||
|
await expect(gov.castVote(id, true)).to.not.be.reverted
|
||||||
|
expect(await gov.state(id)).to.be.equal(ProposalState.Active)
|
||||||
|
await minewait(
|
||||||
|
(
|
||||||
|
await gov.VOTING_PERIOD()
|
||||||
|
)
|
||||||
|
.add(await gov.EXECUTION_DELAY())
|
||||||
|
.add(96400)
|
||||||
|
.toNumber(),
|
||||||
|
)
|
||||||
|
expect(await gov.state(id)).to.be.equal(ProposalState.AwaitingExecution)
|
||||||
|
await gov.execute(id)
|
||||||
|
expect(await gov.state(id)).to.be.equal(ProposalState.Executed)
|
||||||
|
|
||||||
|
logs = await instanceFactory.queryFilter('NewInstanceCloneCreated')
|
||||||
|
const instance = await ethers.getContractAt(
|
||||||
|
'ERC20TornadoCloneable',
|
||||||
|
ethers.utils.getAddress('0x' + logs[0].topics[1].slice(-40)),
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
sender,
|
||||||
|
deployer,
|
||||||
|
multisig,
|
||||||
|
tornWhale,
|
||||||
|
compWhale,
|
||||||
|
gov,
|
||||||
|
tornToken,
|
||||||
|
compToken,
|
||||||
|
instanceRegistry,
|
||||||
|
router,
|
||||||
|
instanceFactory,
|
||||||
|
instance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it('Should set correct params for factory', async function () {
|
||||||
|
const { instance } = await loadFixture(fixture)
|
||||||
|
|
||||||
|
expect(await instance.token()).to.be.equal(config.COMP)
|
||||||
|
expect(await instance.verifier()).to.be.equal(config.verifier)
|
||||||
|
expect(await instance.hasher()).to.be.equal(config.hasher)
|
||||||
|
expect(await instance.levels()).to.be.equal(config.merkleTreeHeight)
|
||||||
|
expect(await instance.denomination()).to.equal(ethers.utils.parseEther('100'))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should deposit and withdraw into the new instance', async function () {
|
||||||
|
const { sender, instance, compToken, compWhale, router } = await loadFixture(fixture)
|
||||||
|
|
||||||
|
const depo = createDeposit({
|
||||||
|
nullifier: rbigint(31),
|
||||||
|
secret: rbigint(31),
|
||||||
|
})
|
||||||
|
|
||||||
|
const value = ethers.utils.parseEther('100')
|
||||||
|
|
||||||
|
await compToken.connect(compWhale).transfer(sender.address, value)
|
||||||
|
await compToken.connect(sender).approve(router.address, value)
|
||||||
|
|
||||||
|
await expect(() => router.deposit(instance.address, toHex(depo.commitment), [])).to.changeTokenBalances(
|
||||||
|
compToken,
|
||||||
|
[sender, instance],
|
||||||
|
[BigNumber.from(0).sub(value), value],
|
||||||
|
)
|
||||||
|
|
||||||
|
let pevents = await instance.queryFilter('Deposit')
|
||||||
|
await initialize({ merkleTreeHeight: 20 })
|
||||||
|
|
||||||
|
const { proof, args } = await generateProof({
|
||||||
|
deposit: depo,
|
||||||
|
recipient: sender.address,
|
||||||
|
events: pevents,
|
||||||
|
})
|
||||||
|
|
||||||
|
await expect(() => router.withdraw(instance.address, proof, ...args)).to.changeTokenBalances(
|
||||||
|
compToken,
|
||||||
|
[instance, sender],
|
||||||
|
[BigNumber.from(0).sub(value), value],
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue