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