diff --git a/contracts/DEXProxy.sol b/contracts/DEXProxy.sol deleted file mode 100644 index 40057ae..0000000 --- a/contracts/DEXProxy.sol +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.1; - -contract DEXProxy { - bytes32 constant IMPLEMENTATION_POSITION = keccak256("MysDEXProxy.implementation"); - bytes32 constant OWNER_POSITION = keccak256("MystDEXProxy.owner"); - - event Upgraded(address indexed newImplementation); - - modifier _onlyProxyOwner() { - require(msg.sender == ___proxyOwner(), "Only owner can run this function"); - _; - } - - constructor (address _implementation, address _owner) { - require(_implementation != address(0x0)); - - bytes32 _ownerPosition = OWNER_POSITION; - bytes32 _implementationPosition = IMPLEMENTATION_POSITION; - - assembly { - sstore(_ownerPosition, _owner) // sets owner - sstore(_implementationPosition, _implementation) // sets proxy target - } - } - - // Proxying all calls into MystDEX implementation - receive() external payable { - ___default(); - } - - fallback() external { - ___default(); - } - - function ___default() internal { - address _implementation = ___Implementation(); - assembly { - let ptr := mload(0x40) - calldatacopy(ptr, 0, calldatasize()) - let success := delegatecall(sub(gas(), 10000), _implementation, ptr, calldatasize(), 0, 0) - let retSz := returndatasize() - returndatacopy(ptr, 0, retSz) - - switch success - case 0 { revert(ptr, retSz) } - default { return(ptr, retSz) } - } - } - - function ___proxyOwner() public view returns (address owner) { - bytes32 _position = OWNER_POSITION; - assembly { - owner := sload(_position) - } - } - - function ___setProxyOwner(address _newOwner) external _onlyProxyOwner { - bytes32 position = OWNER_POSITION; - assembly { - sstore(position, _newOwner) - } - } - - function ___Implementation() public view returns (address _implementation) { - bytes32 _position = IMPLEMENTATION_POSITION; - assembly { - _implementation := sload(_position) - } - } - - function ___upgradeTo(address _newImplementation) public _onlyProxyOwner { - bytes32 position = IMPLEMENTATION_POSITION; - assembly { - sstore(position, _newImplementation) - } - emit Upgraded(_newImplementation); - } - - function __upgradeToAndCall(address _newImplementation, bytes memory _data) public payable _onlyProxyOwner { - ___upgradeTo(_newImplementation); - (bool success, ) = address(this).call{value: msg.value}(_data); - require(success, "Calling new target failed"); - } -} diff --git a/contracts/MystDEX.sol b/contracts/MystDEX.sol deleted file mode 100644 index 0f4fe86..0000000 --- a/contracts/MystDEX.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.1; - -import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; -import { IERC20Token } from "./interfaces/IERC20Token.sol"; -import { FundsRecovery } from "./FundsRecovery.sol"; -import { Ownable } from "./Ownable.sol"; - -contract MystDEX is Ownable, FundsRecovery { - using SafeMath for uint256; - - bool public initialised; - uint256 rate; // Wei per token - - // Default function - converts ethers to MYST - receive() external payable { - require(initialised, "Contract is not initialised"); - - uint256 tokensAmount = msg.value.div(rate).mul(1e18); - - require(token.balanceOf(address(this)) >= tokensAmount); - token.transfer(msg.sender, tokensAmount); - } - - // Because of proxy pattern this function is used insted of constructor. - // Have to be called right after proxy deployment. - function initialise(address _dexOwner, address _token, uint256 _rate) public { - require(!initialised, "Contract is already initialised"); - transferOwnership(_dexOwner); - token = IERC20Token(_token); - rate = _rate; - initialised = true; - } - - function setRate (uint256 _newRate) public onlyOwner { - rate = _newRate; - } - - // Transfers selected tokens into tokens destination address. - function transferEthers(address payable _to, uint256 _amount) external onlyOwner { - require(address(this).balance >= _amount, "not enough ether balance"); - _to.transfer(_amount); - } - - function transferMyst(address _to, uint256 _amount) external onlyOwner { - require(token.balanceOf(address(this)) >= _amount,"not enough myst balance"); - token.transfer(_to, _amount); - } -} diff --git a/contracts/flattened/DEXImplementation.sol.flattened b/contracts/flattened/DEXImplementation.sol.flattened deleted file mode 100644 index 8a7798a..0000000 --- a/contracts/flattened/DEXImplementation.sol.flattened +++ /dev/null @@ -1,383 +0,0 @@ - -// File: @openzeppelin/contracts/math/SafeMath.sol - -// SPDX-License-Identifier: MIT - -pragma solidity ^0.6.0; - -/** - * @dev Wrappers over Solidity's arithmetic operations with added overflow - * checks. - * - * Arithmetic operations in Solidity wrap on overflow. This can easily result - * in bugs, because programmers usually assume that an overflow raises an - * error, which is the standard behavior in high level programming languages. - * `SafeMath` restores this intuition by reverting the transaction when an - * operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - */ -library SafeMath { - /** - * @dev Returns the addition of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - require(c >= a, "SafeMath: addition overflow"); - - return c; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - return sub(a, b, "SafeMath: subtraction overflow"); - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting with custom message on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b <= a, errorMessage); - uint256 c = a - b; - - return c; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) { - return 0; - } - - uint256 c = a * b; - require(c / a == b, "SafeMath: multiplication overflow"); - - return c; - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - return div(a, b, "SafeMath: division by zero"); - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts with custom message on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b > 0, errorMessage); - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - - return c; - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - return mod(a, b, "SafeMath: modulo by zero"); - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts with custom message when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b != 0, errorMessage); - return a % b; - } -} - -// File: @openzeppelin/contracts/token/ERC20/IERC20.sol - -// SPDX-License-Identifier: MIT - -pragma solidity ^0.6.0; - -/** - * @dev Interface of the ERC20 standard as defined in the EIP. - */ -interface IERC20 { - /** - * @dev Returns the amount of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the amount of tokens owned by `account`. - */ - function balanceOf(address account) external view returns (uint256); - - /** - * @dev Moves `amount` tokens from the caller's account to `recipient`. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transfer(address recipient, uint256 amount) external returns (bool); - - /** - * @dev Returns the remaining number of tokens that `spender` will be - * allowed to spend on behalf of `owner` through {transferFrom}. This is - * zero by default. - * - * This value changes when {approve} or {transferFrom} are called. - */ - function allowance(address owner, address spender) external view returns (uint256); - - /** - * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * IMPORTANT: Beware that changing an allowance with this method brings the risk - * that someone may use both the old and the new allowance by unfortunate - * transaction ordering. One possible solution to mitigate this race - * condition is to first reduce the spender's allowance to 0 and set the - * desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * - * Emits an {Approval} event. - */ - function approve(address spender, uint256 amount) external returns (bool); - - /** - * @dev Moves `amount` tokens from `sender` to `recipient` using the - * allowance mechanism. `amount` is then deducted from the caller's - * allowance. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); - - /** - * @dev Emitted when `value` tokens are moved from one account (`from`) to - * another (`to`). - * - * Note that `value` may be zero. - */ - event Transfer(address indexed from, address indexed to, uint256 value); - - /** - * @dev Emitted when the allowance of a `spender` for an `owner` is set by - * a call to {approve}. `value` is the new allowance. - */ - event Approval(address indexed owner, address indexed spender, uint256 value); -} - -// File: contracts/interfaces/IERC20Token.sol - -// SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.6.12; - - -abstract contract IERC20Token is IERC20 { - function upgrade(uint256 value) public virtual; -} - -// File: contracts/Ownable.sol - -// SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.6.0 <0.7.0; - -contract Ownable { - address private _owner; - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - function owner() public view returns (address) { - return _owner; - } - - modifier onlyOwner() { - require(_owner == msg.sender || _owner == address(0x0), "Ownable: caller is not the owner"); - _; - } - - function renounceOwnership() public virtual onlyOwner { - emit OwnershipTransferred(_owner, address(0)); - _owner = address(0); - } - - function transferOwnership(address newOwner) public virtual onlyOwner { - require(newOwner != address(0), "Ownable: new owner is the zero address"); - emit OwnershipTransferred(_owner, newOwner); - _owner = newOwner; - } -} - -// File: contracts/FundsRecovery.sol - -// SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.5.12 <0.7.0; - - - -contract FundsRecovery is Ownable { - address payable internal fundsDestination; - IERC20Token public token; - - event DestinationChanged(address indexed previousDestination, address indexed newDestination); - - /** - * Setting new destination of funds recovery. - */ - function setFundsDestination(address payable _newDestination) public virtual onlyOwner { - require(_newDestination != address(0)); - emit DestinationChanged(fundsDestination, _newDestination); - fundsDestination = _newDestination; - } - - /** - * Getting funds destination address. - */ - function getFundsDestination() public view returns (address) { - return fundsDestination; - } - - /** - * Possibility to recover funds in case they were sent to this address before smart contract deployment - */ - function claimEthers() public { - require(fundsDestination != address(0)); - fundsDestination.transfer(address(this).balance); - } - - /** - Transfers selected tokens into owner address. - */ - // TODO add reentrancy protection - function claimTokens(address _token) public { - require(fundsDestination != address(0)); - require(_token != address(token), "native token funds can't be recovered"); - uint256 _amount = IERC20Token(_token).balanceOf(address(this)); - IERC20Token(_token).transfer(fundsDestination, _amount); - } -} - -// File: contracts/MystDEX.sol - -// SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.6.0 <0.7.0; - - - - - -contract MystDEX is Ownable, FundsRecovery { - using SafeMath for uint256; - - bool public initialised; - uint256 rate; // Wei per token - - // Default function - converts ethers to MYST - receive() external payable { - require(initialised, "Contract is not initialised"); - - uint256 tokensAmount = msg.value.div(rate).mul(1e18); - - require(token.balanceOf(address(this)) >= tokensAmount); - token.transfer(msg.sender, tokensAmount); - } - - // Because of proxy pattern this function is used insted of constructor. - // Have to be called right after proxy deployment. - function initialise(address _dexOwner, address _token, uint256 _rate) public { - require(!initialised, "Contract is already initialised"); - transferOwnership(_dexOwner); - token = IERC20Token(_token); - rate = _rate; - initialised = true; - } - - function setRate (uint256 _newRate) public onlyOwner { - rate = _newRate; - } - - // Transfers selected tokens into tokens destination address. - function transferEthers(address payable _to, uint256 _amount) external onlyOwner { - require(address(this).balance >= _amount, "not enough ether balance"); - _to.transfer(_amount); - } - - function transferMyst(address _to, uint256 _amount) external onlyOwner { - require(token.balanceOf(address(this)) >= _amount,"not enough myst balance"); - token.transfer(_to, _amount); - } -} diff --git a/flattener.sh b/flattener.sh index 35ad14a..c401ce9 100644 --- a/flattener.sh +++ b/flattener.sh @@ -3,7 +3,6 @@ truffle-flattener ./contracts/MystToken.sol --output ./contracts/flattened/MystToken.sol.flattened truffle-flattener ./contracts/HermesImplementation.sol --output ./contracts/flattened/HermesImplementation.sol.flattened truffle-flattener ./contracts/ChannelImplementation.sol --output ./contracts/flattened/ChannelImplementation.sol.flattened -truffle-flattener ./contracts/MystDEX.sol --output ./contracts/flattened/DEXImplementation.sol.flattened truffle-flattener ./contracts/Registry.sol --output ./contracts/flattened/Registry.sol.flattened echo "DONE" diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index c04246a..c3d3d3c 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -1,7 +1,6 @@ const Registry = artifacts.require("Registry") const ChannelImplementation = artifacts.require("ChannelImplementation") const HermesImplementation = artifacts.require("HermesImplementation") -const DEXImplementation = artifacts.require("MystDEX") const MystToken = artifacts.require("MystToken") const OldMystToken = artifacts.require("OldMystToken") @@ -9,20 +8,18 @@ const SafeMathLib = artifacts.require("SafeMathLib") const uniswap = require("../scripts/deployUniswap") const WETH = require("../scripts/deployWETH") +const deployRouter02 = require('../scripts/UniswapV2Router02.json') const zeroAddress = '0x0000000000000000000000000000000000000000' -const multicallBytecode = require('../scripts/installation_data.json').bytecode.multicall - module.exports = async function (deployer, network, accounts) { // We do have MYSTTv1 deployed on Görli already if (network === 'goerli') { const originalToken = '0x8EA3F639e98da04708520C63b34AfBAa1594bC82' await deployer.deploy(MystToken, originalToken) - await deployer.deploy(DEXImplementation) await deployer.deploy(ChannelImplementation) await deployer.deploy(HermesImplementation) - await deployer.deploy(Registry, MystToken.address, DEXImplementation.address, 0, ChannelImplementation.address, HermesImplementation.address, zeroAddress) + await deployer.deploy(Registry, MystToken.address, deployRouter02.contractAddr, 0, ChannelImplementation.address, HermesImplementation.address, zeroAddress) } else { await deployer.deploy(SafeMathLib) await deployer.link(SafeMathLib, [OldMystToken]) @@ -32,12 +29,5 @@ module.exports = async function (deployer, network, accounts) { // Deploy Uniswap smart contracts: Factory, Router, Migrator await uniswap.deploy(web3, accounts[0]) - - // Deploy Uniswap V2 Multicall contract - await web3.eth.sendTransaction({ - from: accounts[0], - data: multicallBytecode, - gas: 5700000 - }) } } diff --git a/test/dex.js b/test/dex.js deleted file mode 100644 index 818a346..0000000 --- a/test/dex.js +++ /dev/null @@ -1,112 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") - -const OneEther = web3.utils.toWei(new BN(1), 'ether') - -contract('Mysterium simplified DEX', ([_, owner, ...otherAccounts]) => { - let token, dex - before(async () => { - token = await MystToken.new() - dex = await MystDex.new() - - // Mint 10 000 tokens into dex account - const tokensToMint = web3.utils.toWei(new BN(10000), 'ether') - await token.mint(dex.address, tokensToMint) - - const balance = await token.balanceOf(dex.address) - balance.should.be.bignumber.equal(tokensToMint) - }) - - it('should always work', () => { }) - - it('tx should fail when DEX is not initialised', async () => { - await dex.sendTransaction({ - from: otherAccounts[0], - value: 1, - gas: 200000 - }).should.be.rejected - }) - - it('should initialise not initialised DEX', async () => { - await dex.initialise(owner, token.address, OneEther).should.be.fulfilled - expect(await dex.initialised()).to.be.true - }) - - it('second initialisation should fail', async () => { - await dex.initialise(owner, token.address, 1).should.be.rejected - }) - - it('should exchange ethers into tokens with 1:1 rate', async () => { - const userAccount = otherAccounts[0] - const ethersAmount = 7 * OneEther - const tokenAmount = Number(await token.balanceOf(dex.address)) - - // Send some ethers into DEX - await dex.sendTransaction({ - from: userAccount, - value: ethersAmount, - gas: 200000 - }) - - expect(Number(await token.balanceOf(userAccount))).to.be.equal(ethersAmount) - expect(Number(await web3.eth.getBalance(dex.address))).to.be.equal(ethersAmount) - expect(Number(await token.balanceOf(dex.address))).to.be.equal(tokenAmount - ethersAmount) - }) - - it('should fail setting new rate for not owner', async () => { - const newRate = web3.utils.toWei(new BN(2), 'finney') - await dex.setRate(newRate).should.be.rejected - }) - - it('owner should be able to set new rate', async () => { - const newRate = web3.utils.toWei(new BN(2), 'finney') - - // Owner should be able to set new rate - await dex.setRate(Number(newRate), { from: owner }).should.be.fulfilled - - // Ethers should be exchanged into tokens using new rate - const userAccount = otherAccounts[1] - const ethersAmount = OneEther - const initialTokenBalance = await token.balanceOf(dex.address) - const dexEthers = new BN(await web3.eth.getBalance(dex.address)) - - await dex.sendTransaction({ - from: userAccount, - value: ethersAmount, - gas: 200000 - }) - - const userTokenBalance = await token.balanceOf(userAccount) - const tokensToGet = ethersAmount.div(newRate) * 1e18 - const dexTokenBalance = await token.balanceOf(dex.address) - - expect(await web3.eth.getBalance(dex.address)).to.be.equal(ethersAmount.add(dexEthers).toString()) - expect(userTokenBalance.toString()).to.be.equal(tokensToGet.toString()) - dexTokenBalance.should.be.bignumber.equal(initialTokenBalance.sub(new BN(tokensToGet.toString()))) - }) - - it('should reject tx if there are not enought tokens', async () => { - const rate = web3.utils.toWei(new BN(2), 'finney') - const userAccount = otherAccounts[2] - const ethersAmount = OneEther.mul(new BN(30)) // 30 ethers - const dexEthers = await web3.eth.getBalance(dex.address) - - // There should be more tokens to get that amount DEX is owning - const dexTokens = await token.balanceOf(dex.address) - const tokensToGet = ethersAmount.div(rate).mul(OneEther) - tokensToGet.should.be.bignumber.greaterThan(dexTokens) - - // Transaction should fail - await dex.sendTransaction({ - from: userAccount, - value: ethersAmount, - gas: 200000 - }).should.be.rejected - - // Amount of tokens and ethers should state same as before transaction - expect(await web3.eth.getBalance(dex.address)).to.be.equal(dexEthers) - dexTokens.should.be.bignumber.equal(await token.balanceOf(dex.address)) - }) -}) diff --git a/test/dexOverProxy.js b/test/dexOverProxy.js deleted file mode 100644 index af0fcbb..0000000 --- a/test/dexOverProxy.js +++ /dev/null @@ -1,115 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") -const DEXProxy = artifacts.require("DEXProxy") - -const OneEther = web3.utils.toWei(new BN(1), 'ether') - -contract('DEX over Proxy', ([_, owner, ...otherAccounts]) => { - let token, dex, proxy - before(async () => { - token = await MystToken.new() - dex = await MystDex.new() - proxy = await DEXProxy.new(dex.address, owner) - proxiedDEX = await MystDex.at(proxy.address) - - // Mint 10 000 tokens into dex account - const tokensToMint = web3.utils.toWei(new BN(10000), 'ether') - await token.mint(proxiedDEX.address, tokensToMint) - - const balance = await token.balanceOf(proxiedDEX.address) - balance.should.be.bignumber.equal(tokensToMint) - }) - - it('should always work', () => { }) - - it('tx should fail when DEX is not initialised', async () => { - await proxiedDEX.sendTransaction({ - from: otherAccounts[0], - value: 1, - gas: 200000 - }).should.be.rejected - }) - - it('should initialise not initialised DEX', async () => { - await proxiedDEX.initialise(owner, token.address, OneEther).should.be.fulfilled - expect(await proxiedDEX.initialised()).to.be.true - }) - - it('second initialisation should fail', async () => { - await proxiedDEX.initialise(owner, token.address, OneEther).should.be.rejected - }) - - it('should exchange ethers into tokens with 1:1 rate', async () => { - const userAccount = otherAccounts[0] - const ethersAmount = 7 * OneEther - const tokenAmount = Number(await token.balanceOf(proxiedDEX.address)) - - // Send some ethers into DEX - await proxiedDEX.sendTransaction({ - from: userAccount, - value: ethersAmount, - gas: 200000 - }) - - expect(Number(await token.balanceOf(userAccount))).to.be.equal(ethersAmount) - expect(Number(await web3.eth.getBalance(proxiedDEX.address))).to.be.equal(ethersAmount) - expect(Number(await token.balanceOf(proxiedDEX.address))).to.be.equal(tokenAmount - ethersAmount) - }) - - it('should fail setting new rate for not owner', async () => { - const newRate = web3.utils.toWei(new BN(2), 'finney') - await proxiedDEX.setRate(newRate).should.be.rejected - }) - - it('owner should be able to set new rate', async () => { - const newRate = web3.utils.toWei(new BN(2), 'finney') - - // Owner should be able to set new rate - await proxiedDEX.setRate(Number(newRate), { from: owner }).should.be.fulfilled - - // Ethers should be exchanged into tokens using new rate - const userAccount = otherAccounts[1] - const ethersAmount = OneEther - const initialTokenBalance = await token.balanceOf(proxiedDEX.address) - const dexEthers = new BN(await web3.eth.getBalance(proxiedDEX.address)) - - await proxiedDEX.sendTransaction({ - from: userAccount, - value: ethersAmount, - gas: 200000 - }) - - const userTokenBalance = await token.balanceOf(userAccount) - const tokensToGet = ethersAmount.div(newRate) * 1e18 - const dexTokenBalance = await token.balanceOf(proxiedDEX.address) - - expect(await web3.eth.getBalance(proxiedDEX.address)).to.be.equal(ethersAmount.add(dexEthers).toString()) - expect(userTokenBalance.toString()).to.be.equal(tokensToGet.toString()) - dexTokenBalance.should.be.bignumber.equal(initialTokenBalance.sub(new BN(tokensToGet.toString()))) - }) - - it('should reject tx if there are not enought tokens', async () => { - const rate = web3.utils.toWei(new BN(2), 'finney') - const userAccount = otherAccounts[2] - const ethersAmount = OneEther.mul(new BN(30)) // 30 ethers - const dexEthers = await web3.eth.getBalance(proxiedDEX.address) - - // There should be more tokens to get that amount DEX is owning - const dexTokens = await token.balanceOf(proxiedDEX.address) - const tokensToGet = ethersAmount.div(rate).mul(OneEther) - tokensToGet.should.be.bignumber.greaterThan(dexTokens) - - // Transaction should fail - await proxiedDEX.sendTransaction({ - from: userAccount, - value: ethersAmount, - gas: 200000 - }).should.be.rejected - - // Amount of tokens and ethers should state same as before transaction - expect(await web3.eth.getBalance(proxiedDEX.address)).to.be.equal(dexEthers) - dexTokens.should.be.bignumber.equal(await token.balanceOf(proxiedDEX.address)) - }) -}) diff --git a/test/dexProxy.js b/test/dexProxy.js deleted file mode 100644 index bf15474..0000000 --- a/test/dexProxy.js +++ /dev/null @@ -1,79 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const DEXProxy = artifacts.require("DEXProxy") -const ProxyTarget = artifacts.require("ProxyTarget") -const SecondProxyTarget = artifacts.require("SecondProxyTarget") - -contract('DEX Proxy', ([_, owner, ...otherAccounts]) => { - let proxy, implementation, proxiedImplementation - before(async () => { - implementation = await ProxyTarget.new() - proxy = await DEXProxy.new(implementation.address, owner) - proxiedImplementation = await ProxyTarget.at(proxy.address) - }) - - it('should always work', () => { }) - - it('should have proper proxy owner', async () => { - const proxyOwner = await proxy.___proxyOwner() - expect(proxyOwner).to.be.equal(owner) - }) - - it('should correctly transfer ownership', async () => { - await proxy.___setProxyOwner(otherAccounts[0], { from: owner }) - const newOwner = await proxy.___proxyOwner() - expect(newOwner).to.be.equal(otherAccounts[0]) - }) - - it('should fail when not owner is setting new owner', async () => { - await proxy.___setProxyOwner(otherAccounts[1]).should.be.rejected - }) - - it('should have proper implementation', async () => { - const expectedName = await proxiedImplementation.name() - expect(expectedName).to.be.equal('FirstTarget') - - const expectedTargetAddress = await proxy.___Implementation() - expect(expectedTargetAddress).to.be.equal(implementation.address) - }) - - it('should set new implementation', async () => { - const newImplementation = await SecondProxyTarget.new() - await proxy.___upgradeTo(newImplementation.address, { from: otherAccounts[0] }) - - const expectedName = await proxiedImplementation.name() - expect(expectedName).to.be.equal('SecondTarget') - }) - - it('should fail when not owner is setting new implementation', async () => { - await proxy.___upgradeTo(implementation.address).should.be.rejected - - const expectedName = await proxiedImplementation.name() - expect(expectedName).to.be.equal('SecondTarget') - }) - - it('should change target back to original', async () => { - await proxy.___upgradeTo(implementation.address, { from: otherAccounts[0] }) - - const expectedName = await proxiedImplementation.name() - expect(expectedName).to.be.equal('FirstTarget') - }) - - it('should have own storage with different than `implementation` state', async () => { - // Implementation contract is already initialised - expect(await implementation.initialised()).to.be.true - - // Proxy is pointing to same implementation should be not initialised - const expectedTargetAddress = await proxy.___Implementation() - expect(expectedTargetAddress).to.be.equal(implementation.address) - expect(proxiedImplementation.address).to.be.equal(proxy.address) - expect(await proxiedImplementation.initialised()).to.be.false - - // Calling `initialise` function on Implementation address should fail - await implementation.initialise().should.be.rejected - - // Calling `initialise` function on proxied implementation should change it's state - await proxiedImplementation.initialise() - expect(await proxiedImplementation.initialised()).to.be.true - }) -}) diff --git a/test/fundsRecovery.js b/test/fundsRecovery.js index 5c0d2d8..a5fedbd 100644 --- a/test/fundsRecovery.js +++ b/test/fundsRecovery.js @@ -11,8 +11,6 @@ const ChannelImplementation = artifacts.require("TestChannelImplementation") const HermesImplementation = artifacts.require("HermesImplementation") const TestHermesImplementation = artifacts.require("TestHermesImplementation") const Token = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") -const DEXProxy = artifacts.require("DEXProxy") const FundsRecovery = artifacts.require("TestFundsRecovery") const OneEther = web3.utils.toWei(new BN(1), 'ether') @@ -77,103 +75,13 @@ contract('General tests for funds recovery', ([txMaker, owner, fundsDestination, }) }) -contract('Dex funds recovery', ([_, txMaker, fundsDestination, ...otherAccounts]) => { - let token, dex, proxy, proxiedDEX, topupAmount, tokensToMint - before(async () => { - token = await Token.new() - }) - - it('should topup some ethers and tokens into dex address', async () => { - const nonce = await web3.eth.getTransactionCount(txMaker) - const dexAddress = deriveContractAddress(txMaker, nonce) - - // Toup some tokens and ethers into expected address - topupAmount = tokensToMint = 0.7 * OneEther - await topUpEthers(otherAccounts[3], dexAddress, topupAmount) - await topUpTokens(token, dexAddress, topupAmount) - - // Deploy dex smart contract - dex = await MystDex.new({ from: txMaker }) - expect(dex.address.toLowerCase()).to.be.equal(dexAddress.toLowerCase()) - - // Set funds destination - await dex.setFundsDestination(fundsDestination, { from: txMaker }) - }) - - it('should recover ethers sent to dex before deployment', async () => { - const initialBalance = await web3.eth.getBalance(fundsDestination) - - await dex.claimEthers().should.be.fulfilled - - const expectedBalance = Number(initialBalance) + topupAmount - expect(await web3.eth.getBalance(fundsDestination)).to.be.equal(expectedBalance.toString()) - }) - - it('should recover tokens send to dex before deployment', async () => { - await dex.claimTokens(token.address).should.be.fulfilled - expect((await token.balanceOf(fundsDestination)).toString()).to.be.equal(tokensToMint.toString()) - }) - - it('should topup some ethers and tokens into proxy address', async () => { - const nonce = await web3.eth.getTransactionCount(txMaker) - const proxyAddress = deriveContractAddress(txMaker, nonce) - - // Topup some ethers into expected proxyAddress - topupAmount = 0.8 * OneEther - await web3.eth.sendTransaction({ - from: otherAccounts[3], - to: proxyAddress, - value: topupAmount - }) - expect(await web3.eth.getBalance(proxyAddress)).to.be.equal(topupAmount.toString()) - - // Mint some tokens into expected proxyAddress - tokensToMint = web3.utils.toWei(new BN(8), 'ether') - await token.mint(proxyAddress, tokensToMint) - - const balance = await token.balanceOf(proxyAddress) - balance.should.be.bignumber.equal(tokensToMint) - - // Deploy proxy smart contract - proxy = await DEXProxy.new(dex.address, txMaker, { from: txMaker }) - proxiedDEX = await MystDex.at(proxy.address) - expect(proxiedDEX.address.toLowerCase()).to.be.equal(proxyAddress.toLowerCase()) - - // Initialise proxiedDex - const nativeToken = await Token.new() - await proxiedDEX.initialise(txMaker, nativeToken.address, 1) - - // Set funds destination - await proxiedDEX.setFundsDestination(fundsDestination, { from: txMaker }) - }) - - it('should recover ethers sent to proxy before deployment', async () => { - const initialBalance = await web3.eth.getBalance(fundsDestination) - - await proxiedDEX.claimEthers().should.be.fulfilled - - const expectedBalance = Number(initialBalance) + topupAmount - expect(await web3.eth.getBalance(fundsDestination)).to.be.equal(expectedBalance.toString()) - }) - - it('should recover tokens send to proxy', async () => { - const initialBalance = await token.balanceOf(fundsDestination) - - await proxiedDEX.claimTokens(token.address).should.be.fulfilled - - const expectedBalance = initialBalance.add(tokensToMint) - expect((await token.balanceOf(fundsDestination)).toString()).to.be.equal(expectedBalance.toString()) - }) - -}) - contract('Registry funds recovery', ([_, txMaker, identity, account, fundsDestination, ...otherAccounts]) => { let token, channelImplementation, hermesImplementation, dex, registry, topupAmount, tokensAmount before(async () => { token = await Token.new() - dex = await MystDex.new() + dex = await setupDEX(token, _) hermesImplementation = await HermesImplementation.new() - channelImplementation = await ChannelImplementation.new(token.address, identity, hermesImplementation.address, Zero) + channelImplementation = await ChannelImplementation.new(token.address, dex.address, identity, hermesImplementation.address, Zero) }) it('should topup some ethers and tokens into future registry address', async () => { @@ -192,6 +100,7 @@ contract('Registry funds recovery', ([_, txMaker, identity, account, fundsDestin // Deploy registry smart contract const nativeToken = await Token.new() // Native token is used as main unit of value in channels. We're recovering any other tokens but not this. + dex = await setupDEX(nativeToken, _) registry = await Registry.new(nativeToken.address, dex.address, 0, channelImplementation.address, hermesImplementation.address, ZeroAddress, { from: txMaker }) expect(registry.address.toLowerCase()).to.be.equal(registryAddress.toLowerCase()) @@ -241,7 +150,8 @@ contract('Channel implementation funds recovery', ([_, txMaker, identity, identi // Deploy IdentityImplementation smart contract const hermesImplementation = await HermesImplementation.new() - channelImplementation = await ChannelImplementation.new(nativeToken.address, txMaker, hermesImplementation.address, Zero, { from: txMaker }) + const dex = await setupDEX(nativeToken, _) + channelImplementation = await ChannelImplementation.new(nativeToken.address, dex.address, txMaker, hermesImplementation.address, Zero, { from: txMaker }) expect(channelImplementation.address.toLowerCase()).to.be.equal(implementationAddress.toLowerCase()) // Set funds destination diff --git a/test/fundsRecoveryByCheque.js b/test/fundsRecoveryByCheque.js index 9a6db1e..4f5bfac 100644 --- a/test/fundsRecoveryByCheque.js +++ b/test/fundsRecoveryByCheque.js @@ -2,11 +2,11 @@ const { BN } = require('@openzeppelin/test-helpers') const { genCreate2Address, signMessage, + setupDEX, verifySignature, topUpEthers, topUpTokens, - toBytes32Buffer, - setupConfig + toBytes32Buffer } = require('./utils/index.js') const wallet = require('./utils/wallet.js') const signIdentityRegistration = require('./utils/client.js').signIdentityRegistration @@ -15,7 +15,6 @@ const Registry = artifacts.require("Registry") const ChannelImplementation = artifacts.require("ChannelImplementation") const HermesImplementation = artifacts.require("HermesImplementation") const Token = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const OneEther = web3.utils.toWei('1', 'ether') const Zero = new BN(0) @@ -46,7 +45,7 @@ contract('Full path (in channel using cheque) test for funds recovery', ([txMake before(async () => { token = await Token.new() nativeToken = await Token.new() - const dex = await MystDex.new() + const dex = await setupDEX(nativeToken, txMaker) const channelImplementation = await ChannelImplementation.new() const hermesImplementation = await HermesImplementation.new() registry = await Registry.new(nativeToken.address, dex.address, 0, channelImplementation.address, hermesImplementation.address, ZeroAddress) diff --git a/test/greenpaths.js b/test/greenpaths.js index f5b4552..1e4cdfb 100644 --- a/test/greenpaths.js +++ b/test/greenpaths.js @@ -7,6 +7,7 @@ const { BN } = require('@openzeppelin/test-helpers') const { topUpTokens, topUpEthers, + setupDEX, generateChannelId } = require('./utils/index.js') const { @@ -19,7 +20,6 @@ const wallet = require('./utils/wallet.js') const { expect } = require('chai') const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const Registry = artifacts.require("Registry") const HermesImplementation = artifacts.require("TestHermesImplementation") const ChannelImplementation = artifacts.require("ChannelImplementation") @@ -53,7 +53,7 @@ async function pay(consumer, provider, hermesService, amount, repetitions = 1) { contract('Green path tests', ([txMaker, ...beneficiaries]) => { before(async () => { token = await MystToken.new() - const dex = await MystDex.new() + const dex = await setupDEX(token, txMaker) const hermesImplementation = await HermesImplementation.new() const channelImplementation = await ChannelImplementation.new() registry = await Registry.new(token.address, dex.address, 1, channelImplementation.address, hermesImplementation.address, ZeroAddress) diff --git a/test/hermesChannelSettlement.js b/test/hermesChannelSettlement.js index 27e85b0..c62046e 100644 --- a/test/hermesChannelSettlement.js +++ b/test/hermesChannelSettlement.js @@ -7,7 +7,8 @@ const { BN } = require('@openzeppelin/test-helpers') const { generateChannelId, topUpTokens, - topUpEthers + topUpEthers, + setupDEX } = require('./utils/index.js') const wallet = require('./utils/wallet.js') const { @@ -17,7 +18,6 @@ const { } = require('./utils/client.js') const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const HermesImplementation = artifacts.require("TestHermesImplementation") const ChannelImplementation = artifacts.require("ChannelImplementation") @@ -39,7 +39,7 @@ contract("Channel openinig via settlement tests", ([txMaker, beneficiaryA, benef let token, hermes, registry, promise before(async () => { token = await MystToken.new() - const dex = await MystDex.new() + const dex = await setupDEX(token, txMaker) const hermesImplementation = await HermesImplementation.new(token.address, operator.address, 0, OneToken) const channelImplementation = await ChannelImplementation.new() registry = await Registry.new(token.address, dex.address, 100, channelImplementation.address, hermesImplementation.address, ZeroAddress) diff --git a/test/hermesClosing.js b/test/hermesClosing.js index d0e981f..13b3357 100644 --- a/test/hermesClosing.js +++ b/test/hermesClosing.js @@ -3,7 +3,7 @@ require('chai') .should() const { BN } = require('@openzeppelin/test-helpers') -const { topUpTokens } = require('./utils/index.js') +const { topUpTokens, setupDEX } = require('./utils/index.js') const { signIdentityRegistration, signChannelBalanceUpdate, @@ -13,7 +13,6 @@ const { const wallet = require('./utils/wallet.js') const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const Registry = artifacts.require("Registry") const HermesImplementation = artifacts.require("TestHermesImplementation") const ChannelImplementation = artifacts.require("ChannelImplementation") @@ -32,7 +31,7 @@ contract('Hermes closing', ([txMaker, operatorAddress, ...beneficiaries]) => { stake = OneToken token = await MystToken.new() - const dex = await MystDex.new() + const dex = await setupDEX(token, txMaker) const hermesImplementation = await HermesImplementation.new(token.address, hermesOperator.address, 0, OneToken) const channelImplementation = await ChannelImplementation.new() registry = await Registry.new(token.address, dex.address, stake, channelImplementation.address, hermesImplementation.address, ZeroAddress) diff --git a/test/hermesFee.js b/test/hermesFee.js index 660700b..075012b 100644 --- a/test/hermesFee.js +++ b/test/hermesFee.js @@ -3,7 +3,7 @@ require('chai') .should() const { BN } = require('@openzeppelin/test-helpers') const { randomBytes } = require('crypto') -const { topUpTokens, generateChannelId, keccak, setupConfig } = require('./utils/index.js') +const { topUpTokens, generateChannelId, keccak, setupDEX } = require('./utils/index.js') const { signIdentityRegistration, createPromise @@ -11,7 +11,6 @@ const { const wallet = require('./utils/wallet.js') const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const Registry = artifacts.require("Registry") const HermesImplementation = artifacts.require("TestHermesImplementation") const ChannelImplementation = artifacts.require("ChannelImplementation") @@ -29,7 +28,7 @@ contract('Hermes fee', ([txMaker, operatorAddress, ...beneficiaries]) => { let token, channelImplementation, hermes, dex, registry before(async () => { token = await MystToken.new() - dex = await MystDex.new() + dex = await setupDEX(token, txMaker) const hermesImplementation = await HermesImplementation.new(token.address, hermesOperator.address, 0, OneToken) channelImplementation = await ChannelImplementation.new() registry = await Registry.new(token.address, dex.address, 0, channelImplementation.address, hermesImplementation.address, ZeroAddress) diff --git a/test/hermesPunishment.js b/test/hermesPunishment.js index b5f45d5..2447044 100644 --- a/test/hermesPunishment.js +++ b/test/hermesPunishment.js @@ -4,7 +4,7 @@ require('chai') const { BN } = require('@openzeppelin/test-helpers') const { randomBytes } = require('crypto') -const { topUpTokens, generateChannelId, keccak } = require('./utils/index.js') +const { topUpTokens, setupDEX, generateChannelId, keccak } = require('./utils/index.js') const { signIdentityRegistration, signChannelLoanReturnRequest, @@ -14,7 +14,6 @@ const wallet = require('./utils/wallet.js') const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const Registry = artifacts.require("Registry") const HermesImplementation = artifacts.require("TestHermesImplementation") const ChannelImplementation = artifacts.require("ChannelImplementation") @@ -34,7 +33,7 @@ contract('Hermes punishment', ([txMaker, operatorAddress, ...beneficiaries]) => stake = OneToken token = await MystToken.new() - const dex = await MystDex.new() + const dex = await setupDEX(token, txMaker) const hermesImplementation = await HermesImplementation.new(token.address, hermesOperator.address, 0, OneToken) const channelImplementation = await ChannelImplementation.new() registry = await Registry.new(token.address, dex.address, stake, channelImplementation.address, hermesImplementation.address, ZeroAddress) diff --git a/test/hermesStake.js b/test/hermesStake.js index afbb931..9662aa7 100644 --- a/test/hermesStake.js +++ b/test/hermesStake.js @@ -4,7 +4,7 @@ require('chai') const { BN } = require('@openzeppelin/test-helpers') const { randomBytes } = require('crypto') -const { topUpTokens, generateChannelId, keccak } = require('./utils/index.js') +const { topUpTokens, setupDEX, generateChannelId, keccak } = require('./utils/index.js') const { signIdentityRegistration, createPromise @@ -13,7 +13,6 @@ const wallet = require('./utils/wallet.js') const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const Registry = artifacts.require("Registry") const HermesImplementation = artifacts.require("TestHermesImplementation") const ChannelImplementation = artifacts.require("ChannelImplementation") @@ -32,7 +31,7 @@ contract('Hermes stake management', ([txMaker, operatorAddress, ...beneficiaries stake = OneToken token = await MystToken.new() - const dex = await MystDex.new() + const dex = await setupDEX(token, txMaker) const hermesImplementation = await HermesImplementation.new(token.address, hermesOperator.address, 0, OneToken) const channelImplementation = await ChannelImplementation.new() registry = await Registry.new(token.address, dex.address, stake, channelImplementation.address, hermesImplementation.address, ZeroAddress) diff --git a/test/multiHermes.js b/test/multiHermes.js index 3e04e83..a4bb950 100644 --- a/test/multiHermes.js +++ b/test/multiHermes.js @@ -2,12 +2,11 @@ require('chai') .use(require('chai-as-promised')) .should() const { BN } = require('@openzeppelin/test-helpers') -const { topUpTokens } = require('./utils/index.js') +const { topUpTokens, setupDEX } = require('./utils/index.js') const { signIdentityRegistration } = require('./utils/client.js') const wallet = require('./utils/wallet.js') const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const Registry = artifacts.require("Registry") const HermesImplementation = artifacts.require("HermesImplementation") const ChannelImplementation = artifacts.require("ChannelImplementation") @@ -30,7 +29,7 @@ contract('Multi hermeses', ([txMaker, ...beneficiaries]) => { let token, channelImplementation, hermeses, dex, registry before(async () => { token = await MystToken.new() - dex = await MystDex.new() + dex = await setupDEX(token, txMaker) const hermesImplementation = await HermesImplementation.new() channelImplementation = await ChannelImplementation.new() registry = await Registry.new(token.address, dex.address, 0, channelImplementation.address, hermesImplementation.address, ZeroAddress) diff --git a/test/parentRegistry.js b/test/parentRegistry.js index 0bb2e21..167dcd8 100644 --- a/test/parentRegistry.js +++ b/test/parentRegistry.js @@ -5,10 +5,10 @@ const { BN } = require('@openzeppelin/test-helpers') const generateAccount = require('./utils/wallet.js').generateAccount const topUpTokens = require('./utils/index.js').topUpTokens +const setupDEX = require('./utils/index.js').setupDEX const signIdentityRegistration = require('./utils/client.js').signIdentityRegistration const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const ChannelImplementation = artifacts.require("ChannelImplementation") const HermesImplementation = artifacts.require("HermesImplementation") const Registry = artifacts.require("Registry") @@ -27,7 +27,7 @@ contract('Parent registry', ([txMaker, minter, hermesOperator, hermesOperator2, let token, channelImplementation, hermesImplementation, accId, hermesId, registry, parentRegistry before(async () => { token = await MystToken.new() - dex = await MystDex.new() + dex = await setupDEX(token, txMaker) hermesImplementation = await HermesImplementation.new() channelImplementation = await ChannelImplementation.new() parentRegistry = await ParentRegistry.new(token.address) diff --git a/test/registry.js b/test/registry.js index 66d18e5..c5552bc 100644 --- a/test/registry.js +++ b/test/registry.js @@ -5,6 +5,7 @@ const { BN } = require('@openzeppelin/test-helpers') const genCreate2Address = require('./utils/index.js').genCreate2Address const topUpTokens = require('./utils/index.js').topUpTokens +const setupDEX = require('./utils/index.js').setupDEX const { signIdentityRegistration, signUrlUpdate } = require('./utils/client.js') const generateAccount = require('./utils/wallet.js').generateAccount @@ -12,7 +13,6 @@ const Registry = artifacts.require("Registry") const ChannelImplementation = artifacts.require("ChannelImplementation") const HermesImplementation = artifacts.require("HermesImplementation") const MystToken = artifacts.require("TestMystToken") -const MystDex = artifacts.require("MystDEX") const OneEther = web3.utils.toWei('1', 'ether') const OneToken = web3.utils.toWei(new BN('100000000'), 'wei') @@ -31,7 +31,7 @@ contract('Registry', ([txMaker, minter, fundsDestination, ...otherAccounts]) => let token, channelImplementation, hermesImplementation, hermesId, dex, registry before(async () => { token = await MystToken.new() - dex = await MystDex.new() + dex = await setupDEX(token, txMaker) hermesImplementation = await HermesImplementation.new() channelImplementation = await ChannelImplementation.new() registry = await Registry.new(token.address, dex.address, 0, channelImplementation.address, hermesImplementation.address, ZeroAddress)