mirror of
https://github.com/tornadocash/tornado-pool-factory
synced 2024-02-02 15:04:08 +01:00
add uniswap pool check
This commit is contained in:
parent
65a01c3ce8
commit
9bfbc01d8e
@ -29,6 +29,7 @@ Anyone can create governance proposal for the addition of a new ERC20 instance b
|
||||
|
||||
1. `max number of new instances in one proposal` - the current version supports the addition of a maximum of 4 instances at once.
|
||||
2. `proposal creation fee` - this fee is charged from creator of proposal during `createProposalApprove/createProposalPermit` factory method execution. It can be changed by governance. Default value is stored in `config.js`.
|
||||
3. `TWAPSlotsMin` - minimum number of TWAP slots for Uniswap pool that is chosen during `createProposalApprove/createProposalPermit` factory method call. It can be changed by governance. Default value is stored in `config.js`.
|
||||
|
||||
## Warnings
|
||||
|
||||
@ -60,8 +61,8 @@ Check config.js for actual values.
|
||||
|
||||
With `salt` = `0x0000000000000000000000000000000000000000000000000000000047941987` address must be:
|
||||
|
||||
1. `InstanceFactory` - `0x9A04e3F1091A69CB53D163abE7ad9bbc86C23823`
|
||||
1. `InstanceFactoryWithRegistry` - `0xee994E045B9Ec5a37f3f85d34f9fD087A0c69236`
|
||||
1. `InstanceFactory` - `0x09110e04d5AEF747bcf7A3585D8FFC892Ab9D1Cf`
|
||||
2. `InstanceFactoryWithRegistry` - `0xC01D57d83E9Fe35E0Fb900F9D384EFcA679DF4bD`
|
||||
|
||||
Check addresses with current config:
|
||||
|
||||
|
@ -15,4 +15,7 @@ module.exports = {
|
||||
creationFee: '200000000000000000000', // 200 TORN
|
||||
deployGasLimit: 7000000,
|
||||
owner: '0xBAE5aBfa98466Dbe68836763B087f2d189f4D28f',
|
||||
WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
||||
UniswapV3Factory: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
|
||||
TWAPSlotsMin: 50,
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ contract AddInstanceProposal {
|
||||
token = _token;
|
||||
uniswapPoolSwappingFee = _uniswapPoolSwappingFee;
|
||||
|
||||
require(_denominations.length == _protocolFees.length, "denominations length != protocolFees length");
|
||||
require(_denominations.length == _protocolFees.length, "Incorrect denominations/fees length");
|
||||
uint256 _numInstances = _denominations.length;
|
||||
require(_numInstances > 0 && _numInstances <= 4, "incorrect instances number");
|
||||
numInstances = _numInstances;
|
||||
|
@ -8,6 +8,8 @@ import "./AddInstanceProposal.sol";
|
||||
import "./InstanceFactory.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import { IERC20Permit } from "@openzeppelin/contracts/drafts/IERC20Permit.sol";
|
||||
import { IUniswapV3Factory } from "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol";
|
||||
import { IUniswapV3PoolState } from "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol";
|
||||
|
||||
contract InstanceFactoryWithRegistry is InstanceFactory {
|
||||
using Address for address;
|
||||
@ -15,9 +17,13 @@ contract InstanceFactoryWithRegistry is InstanceFactory {
|
||||
address public immutable governance;
|
||||
address public immutable torn;
|
||||
address public immutable instanceRegistry;
|
||||
IUniswapV3Factory public immutable UniswapV3Factory;
|
||||
address public immutable WETH;
|
||||
uint16 public TWAPSlotsMin;
|
||||
uint256 public creationFee;
|
||||
|
||||
event NewCreationFeeSet(uint256 indexed newCreationFee);
|
||||
event NewCreationFeeSet(uint256 newCreationFee);
|
||||
event NewTWAPSlotsMinSet(uint256 newTWAPSlotsMin);
|
||||
event NewGovernanceProposalCreated(address indexed proposal);
|
||||
|
||||
/**
|
||||
@ -35,11 +41,17 @@ contract InstanceFactoryWithRegistry is InstanceFactory {
|
||||
address _governance,
|
||||
address _instanceRegistry,
|
||||
address _torn,
|
||||
address _UniswapV3Factory,
|
||||
address _WETH,
|
||||
uint16 _TWAPSlotsMin,
|
||||
uint256 _creationFee
|
||||
) InstanceFactory(_verifier, _hasher, _merkleTreeHeight, _governance) {
|
||||
governance = _governance;
|
||||
instanceRegistry = _instanceRegistry;
|
||||
torn = _torn;
|
||||
UniswapV3Factory = IUniswapV3Factory(_UniswapV3Factory);
|
||||
WETH = _WETH;
|
||||
TWAPSlotsMin = _TWAPSlotsMin;
|
||||
creationFee = _creationFee;
|
||||
}
|
||||
|
||||
@ -103,10 +115,22 @@ contract InstanceFactoryWithRegistry is InstanceFactory {
|
||||
uint32[] memory _protocolFees
|
||||
) internal returns (address) {
|
||||
require(_token.isContract(), "Token is not contract");
|
||||
require(_uniswapPoolSwappingFee > 0, "uniswapPoolSwappingFee is zero");
|
||||
require(_denominations.length > 0, "Empty denominations");
|
||||
require(_denominations.length == _protocolFees.length, "Incorrect denominations/fees length");
|
||||
|
||||
// check Uniswap Pool
|
||||
for (uint8 i = 0; i < _protocolFees.length; i++) {
|
||||
if (_protocolFees[i] > 0) {
|
||||
// pool exists
|
||||
address poolAddr = UniswapV3Factory.getPool(_token, WETH, _uniswapPoolSwappingFee);
|
||||
require(poolAddr != address(0), "Uniswap pool is not exist");
|
||||
// TWAP slots
|
||||
(, , , , uint16 observationCardinalityNext, , ) = IUniswapV3PoolState(poolAddr).slot0();
|
||||
require(observationCardinalityNext >= TWAPSlotsMin, "Uniswap pool TWAP slots number is low");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
address proposal = address(
|
||||
new AddInstanceProposal(address(this), instanceRegistry, _token, _uniswapPoolSwappingFee, _denominations, _protocolFees)
|
||||
);
|
||||
@ -119,4 +143,9 @@ contract InstanceFactoryWithRegistry is InstanceFactory {
|
||||
creationFee = _creationFee;
|
||||
emit NewCreationFeeSet(_creationFee);
|
||||
}
|
||||
|
||||
function setTWAPSlotsMin(uint16 _TWAPSlotsMin) external onlyGovernance {
|
||||
TWAPSlotsMin = _TWAPSlotsMin;
|
||||
emit NewTWAPSlotsMinSet(_TWAPSlotsMin);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,9 @@ async function generate(config = defaultConfig) {
|
||||
config.governance,
|
||||
config.instanceRegistry,
|
||||
config.TORN,
|
||||
config.UniswapV3Factory,
|
||||
config.WETH,
|
||||
config.TWAPSlotsMin,
|
||||
config.creationFee,
|
||||
])
|
||||
.slice(2)
|
||||
|
@ -101,6 +101,9 @@ describe('Instance Factory With Registry Tests', () => {
|
||||
expect(await instanceFactory.implementation()).to.exist
|
||||
expect(await instanceFactory.creationFee()).to.be.equal(config.creationFee)
|
||||
expect(await instanceFactory.torn()).to.be.equal(config.TORN)
|
||||
expect(await instanceFactory.TWAPSlotsMin()).to.be.equal(config.TWAPSlotsMin)
|
||||
expect(await instanceFactory.WETH()).to.be.equal(config.WETH)
|
||||
expect(await instanceFactory.UniswapV3Factory()).to.be.equal(config.UniswapV3Factory)
|
||||
})
|
||||
|
||||
it('Governance should be able to set factory params', async function () {
|
||||
@ -114,20 +117,24 @@ describe('Instance Factory With Registry Tests', () => {
|
||||
await instanceFactory.generateNewImplementation(addressZero, addressZero)
|
||||
await instanceFactory.setMerkleTreeHeight(1)
|
||||
await instanceFactory.setCreationFee(0)
|
||||
await instanceFactory.setTWAPSlotsMin(0)
|
||||
|
||||
expect(await instanceFactory.verifier()).to.be.equal(addressZero)
|
||||
expect(await instanceFactory.hasher()).to.be.equal(addressZero)
|
||||
expect(await instanceFactory.merkleTreeHeight()).to.be.equal(1)
|
||||
expect(await instanceFactory.creationFee()).to.be.equal(0)
|
||||
expect(await instanceFactory.TWAPSlotsMin()).to.be.equal(0)
|
||||
|
||||
await instanceFactory.generateNewImplementation(config.verifier, config.hasher)
|
||||
await instanceFactory.setMerkleTreeHeight(config.merkleTreeHeight)
|
||||
await instanceFactory.setCreationFee(config.creationFee)
|
||||
await instanceFactory.setTWAPSlotsMin(config.TWAPSlotsMin)
|
||||
|
||||
expect(await instanceFactory.verifier()).to.be.equal(config.verifier)
|
||||
expect(await instanceFactory.hasher()).to.be.equal(config.hasher)
|
||||
expect(await instanceFactory.merkleTreeHeight()).to.be.equal(config.merkleTreeHeight)
|
||||
expect(await instanceFactory.creationFee()).to.be.equal(config.creationFee)
|
||||
expect(await instanceFactory.TWAPSlotsMin()).to.be.equal(config.TWAPSlotsMin)
|
||||
})
|
||||
|
||||
it('Should successfully deploy/propose/execute proposal - add instance', async function () {
|
||||
@ -466,4 +473,24 @@ describe('Instance Factory With Registry Tests', () => {
|
||||
[BigNumber.from(0).sub(value), value],
|
||||
)
|
||||
})
|
||||
|
||||
it('Should not deploy proposal with incorrect Uniswap pool', async function () {
|
||||
let { sender, instanceFactory, tornWhale, tornToken } = await loadFixture(fixture)
|
||||
|
||||
// deploy proposal ----------------------------------------------
|
||||
await tornToken.connect(tornWhale).transfer(sender.address, config.creationFee)
|
||||
await tornToken.approve(instanceFactory.address, config.creationFee)
|
||||
|
||||
await expect(
|
||||
instanceFactory
|
||||
.connect(sender)
|
||||
.createProposalApprove(config.COMP, 4000, [ethers.utils.parseEther('100')], [30]),
|
||||
).to.be.revertedWith('Uniswap pool is not exist')
|
||||
|
||||
await expect(
|
||||
instanceFactory
|
||||
.connect(sender)
|
||||
.createProposalApprove(config.COMP, 10000, [ethers.utils.parseEther('100')], [30]),
|
||||
).to.be.revertedWith('Uniswap pool TWAP slots number is low')
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user