Line data Source code
1 : // SPDX-License-Identifier: MIT 2 : 3 : pragma solidity ^0.6.12; 4 : pragma experimental ABIEncoderV2; 5 : 6 : // OZ Imports 7 : 8 : import { AdminUpgradeableProxy } from "../common/AdminUpgradeableProxy.sol"; 9 : import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 10 : 11 : // Tornado imports 12 : 13 : import { ITornadoInstance } from "tornado-anonymity-mining/contracts/interfaces/ITornadoInstance.sol"; 14 : 15 : // Local V2 imports 16 : 17 : import { RelayerRegistry } from "../v2/RelayerRegistry.sol"; 18 : 19 : import { FeeOracleManager } from "../v2/FeeOracleManager.sol"; 20 : 21 : import { InstanceRegistry } from "../v2/InstanceRegistry.sol"; 22 : 23 : import { UniswapFeeOracle, UniswapV3OracleHelper } from "../v2/UniswapFeeOracle.sol"; 24 : 25 : import { TornadoRouter } from "../v2/TornadoRouter.sol"; 26 : 27 : /** 28 : * @title InfrastructureUpgradeProposal 29 : * @author AlienTornadosaurusHex 30 : * @notice Proposal which will upgrade only the SURROUNDING infrastrucure in connection with the relayer 31 : * registry such that multiple oracles can be used and so the DAO can add more instances. 32 : */ 33 : contract InfrastructureUpgradeProposal { 34 : /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VARIABLES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 35 : 36 : /* @dev The address of the current FeeManager proxy, future FeeOracleManager */ 37 : address payable public constant feeManagerProxyAddress = 0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7; 38 : 39 : /* @dev The address of the current InstanceRegistry proxy, this will be upgraded */ 40 : address payable public constant instanceRegistryProxyAddress = 0xB20c66C4DE72433F3cE747b58B86830c459CA911; 41 : 42 : /* @dev The address of the current RelayerRegistry proxy, this will be upgraded */ 43 : address payable public constant relayerRegistryProxyAddress = 0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2; 44 : 45 : /* @dev The address of the current TornadoStakingRewards proxy, this will be upgraded */ 46 : address payable public constant stakingProxyAddress = 0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29; 47 : 48 : /* @dev The ENS resolver address */ 49 : address public constant ensAddress = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e; 50 : 51 : /* @dev This is the Uniswap Oracle which we will use for all of our traditional instances, but it will 52 : also help the CurveFeeOracle, the former must have been deployed witht the address of this */ 53 : address public immutable deployedUniswapFeeOracleAddress; 54 : 55 : /* @dev The implementation address of the RelayerRegistry upgrade contract */ 56 : address public immutable deployedRelayerRegistryImplementationAddress; 57 : 58 : /* @dev The implementation address of the TornadoStakingRewards upgrade contract */ 59 : address public immutable deployedStakingRewardsImplementationAddress; 60 : 61 : /* @dev The implementation address of the FeeManager upgrade contract */ 62 : address public immutable deployedFeeOracleManagerImplementationAddress; 63 : 64 : /* @dev The implementation address of the InstanceRegistry upgrade contract */ 65 : address public immutable deployedInstanceRegistryImplementationAddress; 66 : 67 : /* @dev The address of the new, cleaner, better TornadoRouter */ 68 : address public immutable deployedTornadoRouterAddress; 69 : 70 : /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LOGIC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 71 : 72 : constructor( 73 : address _deployedUniswapFeeOracleAddress, 74 : address _deployedRelayerRegistryImplementationAddress, 75 : address _deployedStakingRewardsImplementationAddress, 76 : address _deployedFeeOracleManagerImplementationAddress, 77 : address _deployedInstanceRegistryImplementationAddress, 78 : address _deployedTornadoRouterAddress 79 : ) public { 80 : deployedUniswapFeeOracleAddress = _deployedUniswapFeeOracleAddress; 81 : deployedRelayerRegistryImplementationAddress = _deployedRelayerRegistryImplementationAddress; 82 : deployedStakingRewardsImplementationAddress = _deployedStakingRewardsImplementationAddress; 83 : deployedFeeOracleManagerImplementationAddress = _deployedFeeOracleManagerImplementationAddress; 84 : deployedInstanceRegistryImplementationAddress = _deployedInstanceRegistryImplementationAddress; 85 : deployedTornadoRouterAddress = _deployedTornadoRouterAddress; 86 : } 87 : 88 : /** 89 : * @dev This function also executes further internal functions inlined below. 90 : */ 91 : function executeProposal() external { 92 : // We need to prepare the new TornadoRouter contract by setting the instance registry and relayer 93 : // registry addresses. 94 : 95 4 : TornadoRouter router = TornadoRouter(deployedTornadoRouterAddress); 96 : 97 4 : router.initialize(instanceRegistryProxyAddress, relayerRegistryProxyAddress, feeManagerProxyAddress); 98 : 99 : // We need to upgrade and re-initialize (storage layout has been accounted for, check repository) the 100 : // RelayerRegistry to support slashing relayers and such 101 : 102 : // Upgrade RelayerRegistry (V1) Proxy to RelayerRegistry (V2) 103 : 104 4 : AdminUpgradeableProxy(relayerRegistryProxyAddress).upgradeTo( 105 : deployedRelayerRegistryImplementationAddress 106 : ); 107 : 108 : // Initialize V2 109 : 110 4 : RelayerRegistry(relayerRegistryProxyAddress).initialize( 111 : ensAddress, 112 : deployedTornadoRouterAddress, 113 : feeManagerProxyAddress, 114 : stakingProxyAddress, 115 : bytes20(uint160(2000 ether)), 116 : 5000 117 : ); 118 : 119 : // Upgrade TornadoStakingRewards (V1) Proxy to TornadoStakingRewards (V2) 120 : // We need this for `rewardSlasher`, it's just a function so no state touched 121 : 122 4 : AdminUpgradeableProxy(stakingProxyAddress).upgradeTo(deployedStakingRewardsImplementationAddress); 123 : 124 : // Upgrade FeeManager (V1) Proxy to FeeOracleManager (V2) 125 : // The below is a total overhaul, layout has been accounted for 126 : 127 4 : AdminUpgradeableProxy(feeManagerProxyAddress).upgradeTo(deployedFeeOracleManagerImplementationAddress); 128 : 129 : // Now initialize the FeeOracleManager immediately, this initialization will record the old legacy 130 : // data in combination with the new oracle (which returns a fee value compatible with legacy) and in 131 : // accordance with the new data structures being used, which are more logical and segmented than what 132 : // the original implementation was using. The data which is used in the internal functions was read 133 : // out from the on-chain instance registry. 134 : 135 4 : FeeOracleManager(feeManagerProxyAddress).initialize( 136 : deployedUniswapFeeOracleAddress, 137 : instanceRegistryProxyAddress, 138 : _getAllInstances(), 139 : _getAllInstanceFeePercents() 140 : ); 141 : 142 : // We only allow the Tornado Router to touch the update function 143 : 144 4 : FeeOracleManager(feeManagerProxyAddress).setFeeUpdater(deployedTornadoRouterAddress); 145 : 146 : // Upgrade InstanceRegistry (V1) Proxy to InstanceRegistry (V2) 147 : // There is not many changes here, but we made it more logical and clear. Future developers should not 148 : // have a problem understanding what these contracts do. 149 : 150 4 : AdminUpgradeableProxy(instanceRegistryProxyAddress).upgradeTo( 151 : deployedInstanceRegistryImplementationAddress 152 : ); 153 : 154 : // Initialize this one too, we are abandoning all of the older data here because either the data 155 : // structures don't fit or we can't do a clean addition of all instances, it is better to add the 156 : // instances as fresh data because it's anyways a simple contract, it just stores some basic data on 157 : // instances which isn't mutable for them, instead only determined for each. The new Tornado Router is 158 : // also set. 159 : 160 4 : InstanceRegistry(instanceRegistryProxyAddress).initialize(_getAllInstances(), router); 161 : 162 : // It's been show recently that Uniswap V2 is providing better conditions for TORN liquidity than 163 : // Uniswap V3, probably due to the simplicity of managing positions and the fact that with a coming V4 164 : // upgrade, Uniswap is just moving to fragment their liquidity further. Until a Curve migration is not 165 : // fulfilled, we will use the Uniswap V2 pool for TORN, and if we also see that other token liquidity 166 : // is becoming an issue, we will move it all to V2 until we don't move stuff over to Curve fully. 167 : 168 4 : UniswapFeeOracle uniswapFeeOracle = UniswapFeeOracle(deployedUniswapFeeOracleAddress); 169 : 170 4 : uniswapFeeOracle.setMinObservationCardinality(1); // Set it to minimum so cDAI passes, see below 171 : 172 : // Each of the instances are going to require a Uniswap Pool Fee to be set such that we actually know 173 : // what pools to lookup when querying for Oracle data. This data has also been read out from the 174 : // instance registry and it basically has the 3000 (0.3%) and 500 (0.05%) non-stable and stable 175 : // respectively "default" pool fees. This is not to be confused with pool protocol fees, these have 176 : // been recorded in the (first) legacy initialization above 177 : 178 4 : _setAllInstancePoolFeesInOracle(uniswapFeeOracle); 179 : 180 4 : uniswapFeeOracle.setMinObservationCardinality(10); // Now set the cardinality to a reasonable value 181 : } 182 : 183 : function _setAllInstancePoolFeesInOracle(UniswapFeeOracle _uniswapFeeOracle) internal { 184 4 : ITornadoInstance[] memory instances = _getAllInstances(); 185 : 186 4 : IERC20 weth = IERC20(UniswapV3OracleHelper.WETH); 187 4 : IERC20 dai = IERC20(instances[4].token()); 188 4 : IERC20 cdai = IERC20(instances[8].token()); 189 4 : IERC20 usdt = IERC20(instances[12].token()); 190 4 : IERC20 wbtc = IERC20(instances[14].token()); 191 : 192 : /* ETH instances */ 193 4 : _uniswapFeeOracle.setPoolFeeForToken(weth, uint24(0x000)); 194 4 : _uniswapFeeOracle.setPoolFeeForToken(weth, uint24(0x000)); 195 4 : _uniswapFeeOracle.setPoolFeeForToken(weth, uint24(0x000)); 196 4 : _uniswapFeeOracle.setPoolFeeForToken(weth, uint24(0x000)); 197 : 198 : /* DAI instances */ 199 4 : _uniswapFeeOracle.setPoolFeeForToken(dai, uint24(0xbb8)); 200 4 : _uniswapFeeOracle.setPoolFeeForToken(dai, uint24(0xbb8)); 201 4 : _uniswapFeeOracle.setPoolFeeForToken(dai, uint24(0xbb8)); 202 4 : _uniswapFeeOracle.setPoolFeeForToken(dai, uint24(0xbb8)); 203 : 204 : /* cDAI instances */ 205 4 : _uniswapFeeOracle.setPoolFeeForToken(cdai, uint24(0xbb8)); 206 4 : _uniswapFeeOracle.setPoolFeeForToken(cdai, uint24(0xbb8)); 207 4 : _uniswapFeeOracle.setPoolFeeForToken(cdai, uint24(0xbb8)); 208 4 : _uniswapFeeOracle.setPoolFeeForToken(cdai, uint24(0xbb8)); 209 : 210 : /* USDT instances */ 211 4 : _uniswapFeeOracle.setPoolFeeForToken(usdt, uint24(0x1f4)); 212 4 : _uniswapFeeOracle.setPoolFeeForToken(usdt, uint24(0x1f4)); 213 : 214 : /* WBTC instances */ 215 4 : _uniswapFeeOracle.setPoolFeeForToken(wbtc, uint24(0xbb8)); 216 4 : _uniswapFeeOracle.setPoolFeeForToken(wbtc, uint24(0xbb8)); 217 4 : _uniswapFeeOracle.setPoolFeeForToken(wbtc, uint24(0xbb8)); 218 : } 219 : 220 : function _getAllInstances() internal pure returns (ITornadoInstance[] memory _addresses) { 221 12 : _addresses = new ITornadoInstance[](17); 222 : 223 : /* ETH instances */ 224 12 : _addresses[0] = ITornadoInstance(0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc); 225 12 : _addresses[1] = ITornadoInstance(0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936); 226 12 : _addresses[2] = ITornadoInstance(0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF); 227 12 : _addresses[3] = ITornadoInstance(0xA160cdAB225685dA1d56aa342Ad8841c3b53f291); 228 : 229 : /* DAI instances */ 230 12 : _addresses[4] = ITornadoInstance(0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3); 231 12 : _addresses[5] = ITornadoInstance(0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144); 232 12 : _addresses[6] = ITornadoInstance(0x07687e702b410Fa43f4cB4Af7FA097918ffD2730); 233 12 : _addresses[7] = ITornadoInstance(0x23773E65ed146A459791799d01336DB287f25334); 234 : 235 : /* cDAI instances */ 236 12 : _addresses[8] = ITornadoInstance(0x22aaA7720ddd5388A3c0A3333430953C68f1849b); 237 12 : _addresses[9] = ITornadoInstance(0x03893a7c7463AE47D46bc7f091665f1893656003); 238 12 : _addresses[10] = ITornadoInstance(0x2717c5e28cf931547B621a5dddb772Ab6A35B701); 239 12 : _addresses[11] = ITornadoInstance(0xD21be7248e0197Ee08E0c20D4a96DEBdaC3D20Af); 240 : 241 : /* USDT instances */ 242 12 : _addresses[12] = ITornadoInstance(0x169AD27A470D064DEDE56a2D3ff727986b15D52B); 243 12 : _addresses[13] = ITornadoInstance(0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f); 244 : 245 : /* WBTC instances */ 246 12 : _addresses[14] = ITornadoInstance(0x178169B423a011fff22B9e3F3abeA13414dDD0F1); 247 12 : _addresses[15] = ITornadoInstance(0x610B717796ad172B316836AC95a2ffad065CeaB4); 248 12 : _addresses[16] = ITornadoInstance(0xbB93e510BbCD0B7beb5A853875f9eC60275CF498); 249 : } 250 : 251 : function _getAllInstanceFeePercents() internal pure returns (uint256[] memory _percents) { 252 4 : _percents = new uint256[](17); 253 : 254 : /* ETH instances */ 255 4 : _percents[0] = uint256(0x0000000000000000000000000000000000000000000000000000000000000000); 256 4 : _percents[1] = uint256(0x000000000000000000000000000000000000000000000000000000000000001e); 257 4 : _percents[2] = uint256(0x000000000000000000000000000000000000000000000000000000000000001e); 258 4 : _percents[3] = uint256(0x000000000000000000000000000000000000000000000000000000000000001e); 259 : 260 : /* DAI instances */ 261 4 : _percents[4] = uint256(0x0000000000000000000000000000000000000000000000000000000000000000); 262 4 : _percents[5] = uint256(0x0000000000000000000000000000000000000000000000000000000000000000); 263 4 : _percents[6] = uint256(0x000000000000000000000000000000000000000000000000000000000000001e); 264 4 : _percents[7] = uint256(0x000000000000000000000000000000000000000000000000000000000000001e); 265 : 266 : /* cDAI instances */ 267 4 : _percents[8] = uint256(0x0000000000000000000000000000000000000000000000000000000000000000); 268 4 : _percents[9] = uint256(0x0000000000000000000000000000000000000000000000000000000000000000); 269 4 : _percents[10] = uint256(0x0000000000000000000000000000000000000000000000000000000000000000); 270 4 : _percents[11] = uint256(0x0000000000000000000000000000000000000000000000000000000000000000); 271 : 272 : /* USDT instances */ 273 4 : _percents[12] = uint256(0x0000000000000000000000000000000000000000000000000000000000000000); 274 4 : _percents[13] = uint256(0x0000000000000000000000000000000000000000000000000000000000000000); 275 : 276 : /* WBTC instances */ 277 4 : _percents[14] = uint256(0x000000000000000000000000000000000000000000000000000000000000001e); 278 4 : _percents[15] = uint256(0x000000000000000000000000000000000000000000000000000000000000001e); 279 4 : _percents[16] = uint256(0x000000000000000000000000000000000000000000000000000000000000001e); 280 : } 281 : }