tornado-pool-factory/contracts/InstanceFactory.sol

110 lines
3.3 KiB
Solidity
Raw Normal View History

2021-10-24 21:54:07 +02:00
// SPDX-License-Identifier: MIT
2022-02-16 14:50:46 +01:00
pragma solidity 0.7.6;
2021-10-24 21:54:07 +02:00
pragma abicoder v2;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/proxy/Clones.sol";
2021-10-24 21:54:07 +02:00
import "./ERC20TornadoCloneable.sol";
2022-02-16 14:50:46 +01:00
import "./AddInstanceProposal.sol";
import "./interfaces/IGovernance.sol";
2021-10-24 21:54:07 +02:00
2022-02-16 14:50:46 +01:00
contract InstanceFactory is Ownable {
2021-10-24 21:54:07 +02:00
using Clones for address;
using Address for address;
2021-10-24 21:54:07 +02:00
2022-02-16 14:50:46 +01:00
address immutable governance;
2021-10-24 21:54:07 +02:00
address public implementation;
address public verifier;
address public hasher;
uint32 public merkleTreeHeight;
event NewVerifierSet(address indexed newVerifier);
event NewHasherSet(address indexed newHasher);
event NewTreeHeightSet(uint32 indexed newTreeHeight);
event NewImplementationSet(address indexed newImplemenentation);
event NewInstanceCloneCreated(address indexed clone);
2021-10-24 21:54:07 +02:00
constructor(
address _verifier,
address _hasher,
2022-02-16 14:50:46 +01:00
uint32 _merkleTreeHeight,
address _governance
2021-10-24 21:54:07 +02:00
) {
verifier = _verifier;
hasher = _hasher;
merkleTreeHeight = _merkleTreeHeight;
ERC20TornadoCloneable implContract = new ERC20TornadoCloneable(_verifier, _hasher);
2021-10-24 21:54:07 +02:00
implementation = address(implContract);
2022-02-16 14:50:46 +01:00
governance = _governance;
transferOwnership(_governance);
}
function createInstanceClone(uint256 _denomination, address _token) external onlyOwner returns (address) {
bytes32 salt = keccak256(abi.encodePacked(_denomination, _token));
require(!implementation.predictDeterministicAddress(salt).isContract(), "Instance already exists");
address newClone = implementation.cloneDeterministic(salt);
emit NewInstanceCloneCreated(newClone);
ERC20TornadoCloneable(newClone).init(_denomination, merkleTreeHeight, _token);
return newClone;
}
function getInstanceAddress(uint256 _denomination, address _token) public view returns (address) {
bytes32 salt = keccak256(abi.encodePacked(_denomination, _token));
return implementation.predictDeterministicAddress(salt);
}
function createNewProposal(
string calldata _description,
address _instanceRegistry,
address _token,
uint24 _uniswapPoolSwappingFee,
uint256[] memory _denominations,
uint32[] memory _protocolFees
) external returns (address) {
// TODO test params
require(_denominations.length == _protocolFees.length);
address proposal = address(new AddInstanceProposal(
address(this),
_instanceRegistry,
_token,
_uniswapPoolSwappingFee,
_denominations,
_protocolFees
));
IGovernance(governance).propose(proposal, _description);
return proposal;
2021-10-24 21:54:07 +02:00
}
function setVerifier(address _verifier) external onlyOwner {
verifier = _verifier;
emit NewVerifierSet(verifier);
2021-10-24 21:54:07 +02:00
}
function setHasher(address _hasher) external onlyOwner {
hasher = _hasher;
emit NewHasherSet(hasher);
2021-10-24 21:54:07 +02:00
}
function setMerkleTreeHeight(uint32 _merkleTreeHeight) external onlyOwner {
merkleTreeHeight = _merkleTreeHeight;
emit NewTreeHeightSet(merkleTreeHeight);
2021-10-24 21:54:07 +02:00
}
function setImplementation(address _newImplementation) external onlyOwner {
implementation = _newImplementation;
emit NewImplementationSet(implementation);
}
function generateNewImplementation() external onlyOwner {
implementation = address(new ERC20TornadoCloneable(verifier, hasher));
2021-10-24 21:54:07 +02:00
}
}