851d4ef487
Signed-off-by: T-Hax <>
99 lines
6.0 KiB
Markdown
99 lines
6.0 KiB
Markdown
# You can now deploy proposals for instances & instances yourself! 🥳
|
|
|
|
Hi guys! 👋
|
|
|
|
Tornado Cash wouldn't be anything without the on-chain instances, but up until now there was the problem that it wasn't easy for anyone to deploy instances and propose them. For this reason, two new contracts have been deployed to Mainnet and verified. These are the (both links link to Etherscan!) [`MinimalInstanceFactory`](https://etherscan.io/address/0x9d00007c0f5037157b5be8bff174b194a99118d0) and [`InstanceProposalFactory`](https://etherscan.io/address/0x10715a092e160793C278a9830F0f8D4417B94D71) together with two implementation contracts, namely [`ETHTornadoCloneable`](https://etherscan.io/address/0xED2c9A637379DBF045982335db34Ea948F5FDB10) and [`ERC20TornadoCloneable`](https://etherscan.io/address/0xFDE7d58A869B7D4B11cA57A35a10D3D95B1683B2).
|
|
|
|
I'll call the "MinimalInstanceFactory" the "Clone factory 🏭" and the "InstanceProposalFactory" the "Proposal factory 🏭" going further!
|
|
|
|
Essentially, now you will be able to deploy proposals (and new instances) by yourself, starting via manual contract calls via Etherscan (or other methods, we will discuss this later) until UI's and other stuff implement methods for this to be done from other interfaces as well!
|
|
|
|
Addresses:
|
|
|
|
```
|
|
MinimalInstanceFactory = 0x9d00007c0f5037157b5be8bff174b194a99118d0
|
|
InstanceProposalFactory = 0x10715a092e160793C278a9830F0f8D4417B94D71
|
|
ERC20TornadoCloneable (implementation) = 0xED2c9A637379DBF045982335db34Ea948F5FDB10
|
|
ETHTornadoCloneable (implementation) = 0xFDE7d58A869B7D4B11cA57A35a10D3D95B1683B2
|
|
```
|
|
|
|
## Disclaimer
|
|
|
|
Obviously you should not just believe me but also check out the code of the contracts out by yourself. For example, you could take the older contracts and put them into a file, then compare them with the ones from the Github `tornado-core` and other repositories. Do note that the relative paths of the import statements might be different in some contract files, but comb through the code and you will see it is exactly the same logic, other than the stuff that was added on top to make things work (the most important part security wise, you can imagine, is that the cloneable instances are safe).
|
|
|
|
## How it works
|
|
|
|
The Instance factory 🏭 allows you to create an instance for any token of any denomination, you just have to call the `createInstanceClone(uint256 _denomination, address _token)` function with a wanted denomination and a token address, and voila - the instance will be created, no strings attached! Note - a new instance won't be deployed if there already is one for some token and denomination, it will just return the address.
|
|
|
|
This created instance is immediately ready for depositing, the source code on Etherscan will refer to the _implementation_ (because these are cloned contracts) source code. Let's continue on to the Proposal factory, which is where things get spicy.
|
|
|
|
The Proposal factory 🏭 deploys _proposals_ to add Instances to the TORN staking system. The proposed instances can be any token or denomination, but with a catch - since the staking system uses Uniswap V3 to get some TWAP (Time Weighted Average Price) data, we need a Uniswap V3 pool with a reliable history price history. This means, that the Proposal factory 🏭 will not consider every token to be eligible to be _added to the staking system._ It automatically checks this.
|
|
|
|
Otherwise, the Proposal factory 🏭 allows you to create a proposal for any amount of tokens and denominations as long as it fits within a single block! You just have to call one function (`createProposalContract`, more on it later), take the address, and propose that address as a new proposal, done - your instance are proposed!
|
|
|
|
## Details
|
|
|
|
Now for some necessary details when it comes to deploying the proposals, because this can get just a little bit complicated! 😬
|
|
|
|
In future, future-ish, soon (I don't know!) this should be handled automatically (and not via 🐸 REEEEtherscan), but for now start noting down! ✍️
|
|
|
|
The most complicated part is choosing the denominations wisely!
|
|
|
|
---
|
|
|
|
The denominations MUST be in the following format:
|
|
|
|
`p = power, d = denomination, d * 10^p where 1 <= d <= 1099511627775 && 0 <= p <= 65535`
|
|
|
|
`(2^16 - 1 === 65535 , 2^40 - 1 === 1099511627775)`
|
|
|
|
This is because we are storing the data efficiently to reduce gas costs! In MANY CASES:
|
|
|
|
`p = 18`
|
|
|
|
Because `2^40 - 1` will be enough to represent how large the denomination is, if not, bump `p`!
|
|
|
|
For each token, there will be ONE SET of denominations and ONE power.
|
|
|
|
---
|
|
|
|
The rest of the construction goes as follows:
|
|
|
|
1. Choose the tokens and for each one a set of denominations and one power.
|
|
2. For each token, choose a UNISWAP POOL SWAPPING FEE (the usual ones: `10000 == 1%, 3000 == 0.3%, 500 = 0.05%`).
|
|
3. For each DENOMINATION choose a PROTOCOL FEE (fee on withdraw, `100 == 1%, max 3%`).
|
|
4. Count the total number of denominations for all tokens.
|
|
|
|
YOU ARE ALMOST DONE.
|
|
|
|
Filling in the function goes as follows:
|
|
|
|
```
|
|
createProposalContract(
|
|
[token_address_1, token_address_2, ..., token_address_t],
|
|
[swapping_fee_1, swapping_fee_2, ..., swapping_fee_t],
|
|
[power_1, power_2, ..., power_t],
|
|
[[denomination_1_1, ..., denomination_1_d], ..., [..., denomination_t_d]],
|
|
[[fee_1_1, ..., fee_1_d], ..., [..., fee_t_d]],
|
|
d (the number of denominations we used to index above)
|
|
)
|
|
```
|
|
|
|
YOU ARE DONE!
|
|
|
|
---
|
|
|
|
A mini note on the Instance factory 🏭:
|
|
|
|
The above doesn't count for deploying instances, when using the `createInstanceClone` function, you just use the full denomination number (with decimals and all of that) and an address.
|
|
|
|
---
|
|
|
|
Obviously you can use Tor Browser to access Etherscan and connect with say... a Metamask hot wallet (because it doesn't recognize cold wallets because it blocks access to your devices, but you would obviously use a hot wallet), and then just call the function from there.
|
|
|
|
Furthermore if you're a dev for now grab the ABI off Etherscan or encode according to the function signature, this should be easy since there is no bytes data involved.
|
|
|
|
---
|
|
|
|
Why, THANK YOU ~ VERY MUCH ~ for reading this through! 👋
|