mirror of
https://github.com/tornadocash/tornado-nova
synced 2024-02-02 14:53:56 +01:00
commit
38fb94b52f
@ -17,7 +17,7 @@
|
|||||||
"rules": {
|
"rules": {
|
||||||
"indent": ["error", 2],
|
"indent": ["error", 2],
|
||||||
"linebreak-style": ["error", "unix"],
|
"linebreak-style": ["error", "unix"],
|
||||||
"quotes": ["error", "single"],
|
"quotes": ["error", "single", { "avoidEscape": true }],
|
||||||
"semi": ["error", "never"],
|
"semi": ["error", "never"],
|
||||||
"object-curly-spacing": ["error", "always"],
|
"object-curly-spacing": ["error", "always"],
|
||||||
"comma-dangle": ["error", "always-multiline"],
|
"comma-dangle": ["error", "always-multiline"],
|
||||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -4,7 +4,6 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: ['*']
|
branches: ['*']
|
||||||
tags: ['v[0-9]+.[0-9]+.[0-9]+']
|
tags: ['v[0-9]+.[0-9]+.[0-9]+']
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@ -15,7 +14,8 @@ jobs:
|
|||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 14
|
node-version: 14
|
||||||
- run: yarn install
|
- run: yarn cache clean --all
|
||||||
|
- run: yarn install --network-concurrency 1
|
||||||
- run: yarn lint
|
- run: yarn lint
|
||||||
- run: yarn download
|
- run: yarn download
|
||||||
- run: yarn build
|
- run: yarn build
|
||||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -3,4 +3,6 @@ node_modules
|
|||||||
build
|
build
|
||||||
cache
|
cache
|
||||||
artifacts
|
artifacts
|
||||||
src/types
|
artifacts-ovm
|
||||||
|
cache-ovm
|
||||||
|
src/types
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
.vscode
|
.vscode
|
||||||
.idea
|
.idea
|
||||||
artifacts
|
artifacts
|
||||||
|
artifacts-ovm
|
||||||
cache
|
cache
|
||||||
|
cache-ovm
|
||||||
contracts/Verifier*.sol
|
contracts/Verifier*.sol
|
||||||
src/types
|
src/types
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
yarn
|
yarn
|
||||||
|
yarn download
|
||||||
yarn build
|
yarn build
|
||||||
yarn test
|
yarn test
|
||||||
```
|
```
|
||||||
@ -11,3 +12,11 @@ yarn test
|
|||||||
TODO
|
TODO
|
||||||
|
|
||||||
1. deposit from mainnet to the pool on optimism in one tx
|
1. deposit from mainnet to the pool on optimism in one tx
|
||||||
|
|
||||||
|
## Useful
|
||||||
|
|
||||||
|
How we do transaction inside pool of A amount.
|
||||||
|
|
||||||
|
1. sort inputs by amount
|
||||||
|
2. try to take 1 or 2 smallest inputs to satisfy A amount. Get 16 inputs if it's not possible using the same way
|
||||||
|
3. Also you can always use transaction to merge your inputs with change (especially in 16 inputs case)
|
||||||
|
9
TODO
9
TODO
@ -1,9 +0,0 @@
|
|||||||
* relayer
|
|
||||||
* design
|
|
||||||
* race condition ? (sequencer or something)
|
|
||||||
* the current trusted setup is not secure ?
|
|
||||||
|
|
||||||
How we do transaction inside pool of A amount.
|
|
||||||
1. sort inputs by amount
|
|
||||||
2. try to take 1 or 2 smallest inputs to satisfy A amount. Get 16 inputs if it's not possible using the same way
|
|
||||||
3. Also you can always use transaction to merge your inputs with change (especially in 16 inputs case)
|
|
@ -130,6 +130,5 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) {
|
|||||||
treeUpdater.pathElements[i] <== outPathElements[i];
|
treeUpdater.pathElements[i] <== outPathElements[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
signal extDataSquare;
|
signal extDataSquare <== extDataHash * extDataHash;
|
||||||
extDataSquare <== extDataHash * extDataHash;
|
|
||||||
}
|
}
|
||||||
|
40
contracts/CrossChainUpgradeableProxy.sol
Normal file
40
contracts/CrossChainUpgradeableProxy.sol
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import "@openzeppelin/contracts/contracts/proxy/TransparentUpgradeableProxy.sol";
|
||||||
|
|
||||||
|
// https://github.com/ethereum-optimism/optimism/blob/c7bc85deee999b8edfbe187b302d0ea262638ca9/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol
|
||||||
|
interface iOVM_CrossDomainMessenger {
|
||||||
|
function xDomainMessageSender() external view returns (address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev TransparentUpgradeableProxy where admin acts from a different chain.
|
||||||
|
*/
|
||||||
|
contract CrossChainUpgradeableProxy is TransparentUpgradeableProxy {
|
||||||
|
// https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/deployments/README.md
|
||||||
|
iOVM_CrossDomainMessenger public immutable messenger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Initializes an upgradeable proxy backed by the implementation at `_logic`.
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
address _logic,
|
||||||
|
address _admin,
|
||||||
|
bytes memory _data,
|
||||||
|
iOVM_CrossDomainMessenger _messenger
|
||||||
|
) TransparentUpgradeableProxy(_logic, _admin, _data) {
|
||||||
|
messenger = _messenger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Modifier used internally that will delegate the call to the implementation unless the sender is the cross chain admin.
|
||||||
|
*/
|
||||||
|
modifier ifAdmin() override {
|
||||||
|
if (msg.sender == address(messenger) && messenger.xDomainMessageSender() == _admin()) {
|
||||||
|
_;
|
||||||
|
} else {
|
||||||
|
_fallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
contracts/Mocks/MockOVM_CrossDomainMessenger.sol
Normal file
14
contracts/Mocks/MockOVM_CrossDomainMessenger.sol
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
contract MockOVM_CrossDomainMessenger {
|
||||||
|
address public xDomainMessageSender;
|
||||||
|
|
||||||
|
constructor(address _xDomainMessageSender) {
|
||||||
|
xDomainMessageSender = _xDomainMessageSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
function execute(address _who, bytes calldata _calldata) external returns (bool success, bytes memory result) {
|
||||||
|
(success, result) = _who.call(_calldata);
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
pragma solidity ^0.7.0;
|
pragma solidity ^0.7.0;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
|
||||||
|
|
||||||
interface IVerifier {
|
interface IVerifier {
|
||||||
function verifyProof(bytes memory _proof, uint256[9] memory _input) external view returns (bool);
|
function verifyProof(bytes memory _proof, uint256[9] memory _input) external view returns (bool);
|
||||||
@ -19,7 +20,11 @@ interface IVerifier {
|
|||||||
function verifyProof(bytes memory _proof, uint256[23] memory _input) external view returns (bool);
|
function verifyProof(bytes memory _proof, uint256[23] memory _input) external view returns (bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
contract TornadoPool {
|
interface ERC20 {
|
||||||
|
function transfer(address to, uint256 value) external returns (bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract TornadoPool is Initializable {
|
||||||
uint256 public constant FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
uint256 public constant FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||||
int256 public constant MAX_EXT_AMOUNT = 2**248;
|
int256 public constant MAX_EXT_AMOUNT = 2**248;
|
||||||
uint256 public constant MAX_FEE = 2**248;
|
uint256 public constant MAX_FEE = 2**248;
|
||||||
@ -65,13 +70,12 @@ contract TornadoPool {
|
|||||||
@param _verifier2 the address of SNARK verifier for 2 inputs
|
@param _verifier2 the address of SNARK verifier for 2 inputs
|
||||||
@param _verifier16 the address of SNARK verifier for 16 inputs
|
@param _verifier16 the address of SNARK verifier for 16 inputs
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(IVerifier _verifier2, IVerifier _verifier16) {
|
||||||
IVerifier _verifier2,
|
|
||||||
IVerifier _verifier16,
|
|
||||||
bytes32 _currentRoot
|
|
||||||
) {
|
|
||||||
verifier2 = _verifier2;
|
verifier2 = _verifier2;
|
||||||
verifier16 = _verifier16;
|
verifier16 = _verifier16;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initialize(bytes32 _currentRoot) external initializer {
|
||||||
currentRoot = _currentRoot;
|
currentRoot = _currentRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,13 +101,13 @@ contract TornadoPool {
|
|||||||
} else if (_extData.extAmount < 0) {
|
} else if (_extData.extAmount < 0) {
|
||||||
require(msg.value == 0, "Sent ETH amount should be 0 for withdrawal");
|
require(msg.value == 0, "Sent ETH amount should be 0 for withdrawal");
|
||||||
require(_extData.recipient != address(0), "Can't withdraw to zero address");
|
require(_extData.recipient != address(0), "Can't withdraw to zero address");
|
||||||
_extData.recipient.transfer(uint256(-_extData.extAmount));
|
_transfer(_extData.recipient, uint256(-_extData.extAmount));
|
||||||
} else {
|
} else {
|
||||||
require(msg.value == 0, "Sent ETH amount should be 0 for transaction");
|
require(msg.value == 0, "Sent ETH amount should be 0 for transaction");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_extData.fee > 0) {
|
if (_extData.fee > 0) {
|
||||||
_extData.relayer.transfer(_extData.fee);
|
_transfer(_extData.relayer, _extData.fee);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit NewCommitment(_args.outputCommitments[0], cachedCommitmentIndex, _extData.encryptedOutput1);
|
emit NewCommitment(_args.outputCommitments[0], cachedCommitmentIndex, _extData.encryptedOutput1);
|
||||||
@ -113,6 +117,18 @@ contract TornadoPool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _transfer(address payable _to, uint256 _amount) internal {
|
||||||
|
uint256 id;
|
||||||
|
assembly {
|
||||||
|
id := chainid()
|
||||||
|
}
|
||||||
|
if (id == 10) {
|
||||||
|
ERC20(0x4200000000000000000000000000000000000006).transfer(_to, _amount);
|
||||||
|
} else {
|
||||||
|
_to.transfer(_amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function calculatePublicAmount(int256 _extAmount, uint256 _fee) public pure returns (uint256) {
|
function calculatePublicAmount(int256 _extAmount, uint256 _fee) public pure returns (uint256) {
|
||||||
require(_fee < MAX_FEE, "Invalid fee");
|
require(_fee < MAX_FEE, "Invalid fee");
|
||||||
require(_extAmount > -MAX_EXT_AMOUNT && _extAmount < MAX_EXT_AMOUNT, "Invalid ext amount");
|
require(_extAmount > -MAX_EXT_AMOUNT && _extAmount < MAX_EXT_AMOUNT, "Invalid ext amount");
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
/* eslint-disable indent */
|
||||||
require('@typechain/hardhat')
|
require('@typechain/hardhat')
|
||||||
require('@nomiclabs/hardhat-ethers')
|
require('@nomiclabs/hardhat-ethers')
|
||||||
require('@nomiclabs/hardhat-waffle')
|
require('@nomiclabs/hardhat-waffle')
|
||||||
|
require('@eth-optimism/hardhat-ovm')
|
||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
@ -13,6 +15,9 @@ const config = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
ovm: {
|
||||||
|
solcVersion: '0.7.6+commit.3b061308',
|
||||||
|
},
|
||||||
networks: {
|
networks: {
|
||||||
// goerli: {
|
// goerli: {
|
||||||
// url: process.env.ETH_RPC,
|
// url: process.env.ETH_RPC,
|
||||||
@ -22,6 +27,19 @@ const config = {
|
|||||||
// mnemonic: 'test test test test test test test test test test test junk',
|
// mnemonic: 'test test test test test test test test test test test junk',
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
|
optimism: {
|
||||||
|
url: process.env.ETH_RPC || 'https://mainnet.optimism.io',
|
||||||
|
accounts: process.env.PRIVATE_KEY
|
||||||
|
? [process.env.PRIVATE_KEY]
|
||||||
|
: {
|
||||||
|
mnemonic: 'test test test test test test test test test test test junk',
|
||||||
|
},
|
||||||
|
// This sets the gas price to 0 for all transactions on L2. We do this
|
||||||
|
// because account balances are not automatically initiated with an ETH
|
||||||
|
// balance (yet, sorry!).
|
||||||
|
gasPrice: 15000000,
|
||||||
|
ovm: true, // This sets the network as using the ovm and ensure contract will be compiled against that.
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mocha: {
|
mocha: {
|
||||||
timeout: 600000000,
|
timeout: 600000000,
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"circuit": "./scripts/buildCircuit.sh 2 && ./scripts/buildCircuit.sh 16",
|
"circuit": "./scripts/buildCircuit.sh 2 && ./scripts/buildCircuit.sh 16",
|
||||||
"compile": "npx hardhat compile",
|
"compile": "npx hardhat compile",
|
||||||
"build": "npm run circuit && npm run compile",
|
"build": "npm run circuit && npm run compile",
|
||||||
|
"deploy": "npx hardhat run scripts/deploy.js --network optimism",
|
||||||
"download": "curl -L https://github.com/tornadocash/tornado-pool/releases/download/tmp/ptau15 --create-dirs -o artifacts/circuits/ptau15",
|
"download": "curl -L https://github.com/tornadocash/tornado-pool/releases/download/tmp/ptau15 --create-dirs -o artifacts/circuits/ptau15",
|
||||||
"test": "npx hardhat test",
|
"test": "npx hardhat test",
|
||||||
"eslint": "eslint --ext .js --ignore-path .gitignore .",
|
"eslint": "eslint --ext .js --ignore-path .gitignore .",
|
||||||
@ -23,7 +24,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||||
"@openzeppelin/contracts": "^3.4.0",
|
"@openzeppelin/contracts": "git+https://github.com/tornadocash/openzeppelin-contracts.git#6e46aa6946a7f215e7604169ddf46e1aebea850f",
|
||||||
|
"@openzeppelin/contracts-upgradeable": "3.4.1",
|
||||||
"@typechain/ethers-v5": "^7.0.1",
|
"@typechain/ethers-v5": "^7.0.1",
|
||||||
"@typechain/hardhat": "^2.3.0",
|
"@typechain/hardhat": "^2.3.0",
|
||||||
"bignumber.js": "^9.0.0",
|
"bignumber.js": "^9.0.0",
|
||||||
@ -45,6 +47,7 @@
|
|||||||
"typechain": "^5.1.2"
|
"typechain": "^5.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eth-optimism/hardhat-ovm": "^0.2.2",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"eslint": "^7.28.0",
|
"eslint": "^7.28.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const { ethers } = require('hardhat')
|
const { ethers } = require('hardhat')
|
||||||
|
|
||||||
const MERKLE_TREE_HEIGHT = 5
|
const MERKLE_TREE_HEIGHT = 32
|
||||||
const MerkleTree = require('fixed-merkle-tree')
|
const MerkleTree = require('fixed-merkle-tree')
|
||||||
const { poseidon } = require('circomlib')
|
const { poseidon } = require('circomlib')
|
||||||
const poseidonHash = (items) => ethers.BigNumber.from(poseidon(items).toString())
|
const poseidonHash = (items) => ethers.BigNumber.from(poseidon(items).toString())
|
||||||
|
11
src/utils.js
11
src/utils.js
@ -1,3 +1,4 @@
|
|||||||
|
/* global network */
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const { ethers } = require('hardhat')
|
const { ethers } = require('hardhat')
|
||||||
const BigNumber = ethers.BigNumber
|
const BigNumber = ethers.BigNumber
|
||||||
@ -76,6 +77,15 @@ function shuffle(array) {
|
|||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getSignerFromAddress(address) {
|
||||||
|
await network.provider.request({
|
||||||
|
method: 'hardhat_impersonateAccount',
|
||||||
|
params: [address],
|
||||||
|
})
|
||||||
|
|
||||||
|
return await ethers.provider.getSigner(address)
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
FIELD_SIZE,
|
FIELD_SIZE,
|
||||||
randomBN,
|
randomBN,
|
||||||
@ -85,4 +95,5 @@ module.exports = {
|
|||||||
poseidonHash2,
|
poseidonHash2,
|
||||||
getExtDataHash,
|
getExtDataHash,
|
||||||
shuffle,
|
shuffle,
|
||||||
|
getSignerFromAddress,
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ const { Keypair } = require('../src/keypair')
|
|||||||
|
|
||||||
describe('TornadoPool', function () {
|
describe('TornadoPool', function () {
|
||||||
this.timeout(20000)
|
this.timeout(20000)
|
||||||
|
let gov, messenger
|
||||||
|
|
||||||
async function deploy(contractName, ...args) {
|
async function deploy(contractName, ...args) {
|
||||||
const Factory = await ethers.getContractFactory(contractName)
|
const Factory = await ethers.getContractFactory(contractName)
|
||||||
@ -22,21 +23,57 @@ describe('TornadoPool', function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fixture() {
|
async function fixture() {
|
||||||
|
;[, gov] = await ethers.getSigners()
|
||||||
const verifier2 = await deploy('Verifier2')
|
const verifier2 = await deploy('Verifier2')
|
||||||
const verifier16 = await deploy('Verifier16')
|
const verifier16 = await deploy('Verifier16')
|
||||||
|
|
||||||
const tree = new MerkleTree(MERKLE_TREE_HEIGHT, [], { hashFunction: poseidonHash2 })
|
const tree = new MerkleTree(MERKLE_TREE_HEIGHT, [], { hashFunction: poseidonHash2 })
|
||||||
/** @type {TornadoPool} */
|
const root = await tree.root()
|
||||||
const tornadoPool = await deploy(
|
|
||||||
'TornadoPool',
|
|
||||||
verifier2.address,
|
|
||||||
verifier16.address,
|
|
||||||
toFixedHex(tree.root()),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
const Pool = await ethers.getContractFactory('TornadoPool')
|
||||||
|
const tornadoPoolImpl = await Pool.deploy(verifier2.address, verifier16.address)
|
||||||
|
|
||||||
|
const OVM_Messenger = await ethers.getContractFactory('MockOVM_CrossDomainMessenger')
|
||||||
|
messenger = await OVM_Messenger.deploy(gov.address)
|
||||||
|
await messenger.deployed()
|
||||||
|
|
||||||
|
const CrossChainUpgradeableProxy = await ethers.getContractFactory('CrossChainUpgradeableProxy')
|
||||||
|
const proxy = await CrossChainUpgradeableProxy.deploy(
|
||||||
|
tornadoPoolImpl.address,
|
||||||
|
gov.address,
|
||||||
|
[],
|
||||||
|
messenger.address,
|
||||||
|
)
|
||||||
|
await proxy.deployed()
|
||||||
|
|
||||||
|
/** @type {TornadoPool} */
|
||||||
|
const tornadoPool = Pool.attach(proxy.address)
|
||||||
|
|
||||||
|
await tornadoPool.initialize(toFixedHex(root))
|
||||||
return { tornadoPool }
|
return { tornadoPool }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
describe('Upgradeability tests', () => {
|
||||||
|
let tornadoPool, proxy
|
||||||
|
before(async () => {
|
||||||
|
;({ tornadoPool } = await loadFixture(fixture))
|
||||||
|
const CrossChainUpgradeableProxy = await ethers.getContractFactory('CrossChainUpgradeableProxy')
|
||||||
|
proxy = CrossChainUpgradeableProxy.attach(tornadoPool.address)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('admin should be gov', async () => {
|
||||||
|
const { data } = await proxy.populateTransaction.admin()
|
||||||
|
const { result } = await messenger.callStatic.execute(proxy.address, data)
|
||||||
|
expect('0x' + result.slice(26)).to.be.equal(gov.address.toLowerCase())
|
||||||
|
})
|
||||||
|
|
||||||
|
it('non admin cannot call', async () => {
|
||||||
|
await expect(proxy.admin()).to.be.revertedWith(
|
||||||
|
"Transaction reverted: function selector was not recognized and there's no fallback function",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('encrypt -> decrypt should work', () => {
|
it('encrypt -> decrypt should work', () => {
|
||||||
const data = Buffer.from([0xff, 0xaa, 0x00, 0x01])
|
const data = Buffer.from([0xff, 0xaa, 0x00, 0x01])
|
||||||
const keypair = new Keypair()
|
const keypair = new Keypair()
|
||||||
@ -57,7 +94,7 @@ describe('TornadoPool', function () {
|
|||||||
|
|
||||||
it('should register and deposit', async function () {
|
it('should register and deposit', async function () {
|
||||||
let { tornadoPool } = await loadFixture(fixture)
|
let { tornadoPool } = await loadFixture(fixture)
|
||||||
const sender = (await ethers.getSigners())[1]
|
const sender = (await ethers.getSigners())[0]
|
||||||
|
|
||||||
// Alice deposits into tornado pool
|
// Alice deposits into tornado pool
|
||||||
const aliceDepositAmount = 1e7
|
const aliceDepositAmount = 1e7
|
||||||
|
Loading…
Reference in New Issue
Block a user