From c34a70585a1a1645df59f8056bc719858b635217 Mon Sep 17 00:00:00 2001 From: AlienTornadosaurusHex <> Date: Thu, 22 Jun 2023 20:12:12 +0000 Subject: [PATCH] deploy script and code quality on infra proposal Signed-off-by: AlienTornadosaurusHex <> --- .env.example | 10 +- script/Deploys.sol | 107 +++++++++ script/TornadoRouter.s.sol | 28 --- .../InfrastructureUpgradeProposal.sol | 30 +-- test/ProposalTests.sol | 218 +++++++++++++++++- 5 files changed, 345 insertions(+), 48 deletions(-) create mode 100644 script/Deploys.sol delete mode 100755 script/TornadoRouter.s.sol diff --git a/.env.example b/.env.example index 907f434..ed23191 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,12 @@ # Network & other MAINNET_RPC_URL= ETHERSCAN_KEY= -PRIVATE_KEY= \ No newline at end of file +PRIVATE_KEY= + +# Deployed contracts, which are needed for other deployments. +DEPLOYED_ROUTER_ADDRESS= +DEPLOYED_STAKING_ADDRESS= +DEPLOYED_RELAYERSR_ADDRESS= +DEPLOYED_INSTANCESR_ADDRESS= +DEPLOYED_FOM_ADDRESS= +DEPLOYED_UNIFEO_ADDRESS= \ No newline at end of file diff --git a/script/Deploys.sol b/script/Deploys.sol new file mode 100644 index 0000000..c8966c1 --- /dev/null +++ b/script/Deploys.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.6.12; +pragma experimental ABIEncoderV2; + +// STD imports + +import { Script } from "forge-std/Script.sol"; + +import { console2 } from "forge-std/console2.sol"; + +// Local imports + +import { TornadoAddresses } from "../src/common/TornadoAddresses.sol"; + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BASE CONTRACTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +abstract contract SimpleDeployer is TornadoAddresses, Script { + function _createContract() internal virtual; + + function run() external { + uint256 key = vm.envUint("PRIVATE_KEY"); + + vm.startBroadcast(key); + + _createContract(); + + vm.stopBroadcast(); + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEPLOY ROUTER ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +import { TornadoRouter } from "../src/v2/TornadoRouter.sol"; + +contract RouterDeployer is SimpleDeployer { + function _createContract() internal virtual override { + new TornadoRouter(getGovernanceProxyAddress()); + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEPLOY STAKING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +import { TornadoStakingRewards } from "../src/v2/TornadoStakingRewards.sol"; + +contract StakingDeployer is SimpleDeployer { + function _createContract() internal virtual override { + new TornadoStakingRewards(getGovernanceProxyAddress(), getTornTokenAddress(), vm.envAddress("DEPLOYED_ROUTER_ADDRESS")); + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEPLOY RELAYER REGISTRY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +import { RelayerRegistry } from "../src/v2/RelayerRegistry.sol"; + +contract RelayerRegistryDeployer is SimpleDeployer { + function _createContract() internal virtual override { + new RelayerRegistry(getGovernanceProxyAddress(), getTornTokenAddress()); + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEPLOY INSTANCE REGISTRY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +import { InstanceRegistry } from "../src/v2/InstanceRegistry.sol"; + +contract InstanceRegistryDeployer is SimpleDeployer { + function _createContract() internal virtual override { + new InstanceRegistry(getGovernanceProxyAddress()); + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEPLOY FEE ORACLE MANAGER ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +import { FeeOracleManager } from "../src/v2/FeeOracleManager.sol"; + +contract FeeOracleManagerDeployer is SimpleDeployer { + function _createContract() internal virtual override { + new FeeOracleManager(getTornTokenAddress(), getGovernanceProxyAddress()); + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEPLOY UNISWAP FEE ORACLE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +import { UniswapFeeOracle } from "../src/v2/UniswapFeeOracle.sol"; + +contract UniswapFeeOracleDeployer is SimpleDeployer { + function _createContract() internal virtual override { + new UniswapFeeOracle(getGovernanceProxyAddress(), vm.envAddress("DEPLOYED_FOM_ADDRESS")); + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEPLOY INFRASTRUCTURE UPGRADE PROPOSAL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +import { InfrastructureUpgradeProposal } from "../src/proposals/InfrastructureUpgradeProposal.sol"; + +contract InfrastructureUpgradeProposalDeployer is SimpleDeployer { + function _createContract() internal virtual override { + new InfrastructureUpgradeProposal( + vm.envAddress("DEPLOYED_ROUTER_ADDRESS"), + vm.envAddress("DEPLOYED_STAKING_ADDRESS"), + vm.envAddress("DEPLOYED_RELAYERSR_ADDRESS"), + vm.envAddress("DEPLOYED_INSTANCESR_ADDRESS"), + vm.envAddress("DEPLOYED_FOM_ADDRESS"), + vm.envAddress("DEPLOYED_UNIFEO_ADDRESS") + ); + } +} diff --git a/script/TornadoRouter.s.sol b/script/TornadoRouter.s.sol deleted file mode 100755 index 250bd71..0000000 --- a/script/TornadoRouter.s.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.6.12; -pragma experimental ABIEncoderV2; - -// STD imports - -import { Script } from "forge-std/Script.sol"; - -import { console2 } from "forge-std/console2.sol"; - -// Local imports - -import { TornadoAddresses } from "../src/common/TornadoAddresses.sol"; - -import { TornadoRouter } from "../src/v2/TornadoRouter.sol"; - -contract DeployScript is TornadoAddresses, Script { - function run() external { - uint256 key = vm.envUint("PRIVATE_KEY"); - - vm.startBroadcast(key); - - new TornadoRouter(getGovernanceProxyAddress()); - - vm.stopBroadcast(); - } -} diff --git a/src/proposals/InfrastructureUpgradeProposal.sol b/src/proposals/InfrastructureUpgradeProposal.sol index 8822612..08c3b83 100644 --- a/src/proposals/InfrastructureUpgradeProposal.sol +++ b/src/proposals/InfrastructureUpgradeProposal.sol @@ -54,9 +54,9 @@ contract InfrastructureUpgradeProposal { address payable public constant stakingProxyAddress = 0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29; /** - * @notice The implementation address of the RelayerRegistry upgrade contract + * @notice The address of the new, cleaner, better TornadoRouter */ - address public immutable deployedRelayerRegistryImplementationAddress; + address public immutable deployedTornadoRouterAddress; /** * @notice The implementation address of the TornadoStakingRewards upgrade contract @@ -64,9 +64,9 @@ contract InfrastructureUpgradeProposal { address public immutable deployedStakingRewardsImplementationAddress; /** - * @notice The implementation address of the FeeOracleManager upgrade contract + * @notice The implementation address of the RelayerRegistry upgrade contract */ - address public immutable deployedFeeOracleManagerImplementationAddress; + address public immutable deployedRelayerRegistryImplementationAddress; /** * @notice The implementation address of the InstanceRegistry upgrade contract @@ -74,9 +74,9 @@ contract InfrastructureUpgradeProposal { address public immutable deployedInstanceRegistryImplementationAddress; /** - * @notice The address of the new, cleaner, better TornadoRouter + * @notice The implementation address of the FeeOracleManager upgrade contract */ - address public immutable deployedTornadoRouterAddress; + address public immutable deployedFeeOracleManagerImplementationAddress; /** * @notice This is the Uniswap Oracle which we will use for all of our traditional instances, but it will @@ -87,19 +87,19 @@ contract InfrastructureUpgradeProposal { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LOGIC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ constructor( - address _deployedUniswapFeeOracleAddress, - address _deployedRelayerRegistryImplementationAddress, + address _deployedTornadoRouterAddress, address _deployedStakingRewardsImplementationAddress, - address _deployedFeeOracleManagerImplementationAddress, + address _deployedRelayerRegistryImplementationAddress, address _deployedInstanceRegistryImplementationAddress, - address _deployedTornadoRouterAddress + address _deployedFeeOracleManagerImplementationAddress, + address _deployedUniswapFeeOracleAddress ) public { - deployedUniswapFeeOracleAddress = _deployedUniswapFeeOracleAddress; - deployedRelayerRegistryImplementationAddress = _deployedRelayerRegistryImplementationAddress; - deployedStakingRewardsImplementationAddress = _deployedStakingRewardsImplementationAddress; - deployedFeeOracleManagerImplementationAddress = _deployedFeeOracleManagerImplementationAddress; - deployedInstanceRegistryImplementationAddress = _deployedInstanceRegistryImplementationAddress; deployedTornadoRouterAddress = _deployedTornadoRouterAddress; + deployedStakingRewardsImplementationAddress = _deployedStakingRewardsImplementationAddress; + deployedRelayerRegistryImplementationAddress = _deployedRelayerRegistryImplementationAddress; + deployedInstanceRegistryImplementationAddress = _deployedInstanceRegistryImplementationAddress; + deployedFeeOracleManagerImplementationAddress = _deployedFeeOracleManagerImplementationAddress; + deployedUniswapFeeOracleAddress = _deployedUniswapFeeOracleAddress; } /** diff --git a/test/ProposalTests.sol b/test/ProposalTests.sol index fbff54d..e32e0ab 100644 --- a/test/ProposalTests.sol +++ b/test/ProposalTests.sol @@ -35,6 +35,8 @@ import { CurveFeeOracle, ICurvePriceOracle, CurveChainedOracles } from "src/v2/C import { InfrastructureUpgradeProposal } from "src/proposals/InfrastructureUpgradeProposal.sol"; +import { CRVUSDInstancesProposal } from "src/proposals/CRVUSDInstancesProposal.sol"; + // Test imports import { TornadoProposalTest, ProposalState } from "./TornadoProposalTest.sol"; @@ -75,6 +77,14 @@ contract Instances { ITornadoInstance public constant wbtc01 = ITornadoInstance(0x178169B423a011fff22B9e3F3abeA13414dDD0F1); ITornadoInstance public constant wbtc1 = ITornadoInstance(0x610B717796ad172B316836AC95a2ffad065CeaB4); ITornadoInstance public constant wbtc10 = ITornadoInstance(0xbB93e510BbCD0B7beb5A853875f9eC60275CF498); + + /* CRVUSD instances */ + ITornadoInstance public constant cu100 = ITornadoInstance(0x913a73486Dc4AA3832A56d461542836C1eeB93be); + ITornadoInstance public constant cu1_000 = ITornadoInstance(0x5A6b3C829dB3e938C885000c6E93CF35E74876a4); + ITornadoInstance public constant cu10_000 = ITornadoInstance(0x49f173CDAB99a2C3800F1255393DF9B7a17B82Bb); + ITornadoInstance public constant cu100_000 = ITornadoInstance(0x4640Dffc9fD0B113B983e3A350b070a119CA143C); + ITornadoInstance public constant cu1_000_000 = + ITornadoInstance(0xc4eA8Bd3Fd76f3c255395793B47F7c55aD59d991); } contract ProposalTests is Instances, TornadoProposalTest { @@ -155,6 +165,188 @@ contract ProposalTests is Instances, TornadoProposalTest { _advanceTORNETHMarket(); } + function test_crvusdInstancesBasic() public { + // Do the proposal first + test_crvusdInstancesProposalBasic(); + + // We have to set to address this again + _feeManagerShouldRevertAndSetFeeUpdater(); + + // Advance + _advanceTORNETHMarket(); + + // Try to update crvusd 10000 + feeOracleManager.updateFee(cu10_000, false); + + // Try to update all + ITornadoInstance[] memory _toUpdate = new ITornadoInstance[](5); + + _toUpdate[0] = cu100; + _toUpdate[1] = cu1_000; + _toUpdate[2] = cu10_000; + _toUpdate[3] = cu100_000; + _toUpdate[4] = cu1_000_000; + + // We will need to prank an update on the uniswapFeeOracle + // this should otherwise happen automatically though other tokens being withdrawn + vm.startPrank(address(feeOracleManager)); + for (uint256 i = 0; i < _toUpdate.length; i++) { + uniswapFeeOracle.update(TORN, feeOracleManager.populateInstanceWithFeeData(_toUpdate[i])); + } + vm.stopPrank(); + + // Now update all fees + + uint160[] memory fees = feeOracleManager.updateFees(_toUpdate, false); + + // Print fees to console. + + console2.log("\n~~~~~~~~~~~~~~~~~~ LAST FEES ~~~~~~~~~~~~~~~~~~\n"); + console2.log("cu100: ", uint256(feeOracleManager.getLastFeeForInstance(cu100))); + console2.log("cu1_000: ", uint256(feeOracleManager.getLastFeeForInstance(cu1_000))); + console2.log("cu10_000: ", uint256(feeOracleManager.getLastFeeForInstance(cu10_000))); + console2.log("cu100_000: ", uint256(feeOracleManager.getLastFeeForInstance(cu100_000))); + console2.log("cu1_000_000: ", uint256(feeOracleManager.getLastFeeForInstance(cu1_000_000))); + console2.log("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); + + delimit(); + + console2.log("\n~~~~~~~~~~~~~~~~~~ DATA ~~~~~~~~~~~~~~~~~~\n"); + InstanceState memory data = instanceRegistry.getInstanceState(cu100); + delimit(); + console2.log("cu100:"); + console2.log("token: ", address(data.token)); + console2.log("index: ", uint256(data.index)); + console2.log("iserc20: ", data.isERC20); + console2.log("isenabled: ", data.isEnabled); + delimit(); + data = instanceRegistry.getInstanceState(cu1_000); + console2.log("cu1_000:"); + console2.log("token: ", address(data.token)); + console2.log("index: ", uint256(data.index)); + console2.log("iserc20: ", data.isERC20); + console2.log("isenabled: ", data.isEnabled); + delimit(); + data = instanceRegistry.getInstanceState(cu10_000); + console2.log("cu10_000:"); + console2.log("token: ", address(data.token)); + console2.log("index: ", uint256(data.index)); + console2.log("iserc20: ", data.isERC20); + console2.log("isenabled: ", data.isEnabled); + delimit(); + data = instanceRegistry.getInstanceState(cu100_000); + console2.log("cu100_000:"); + console2.log("token: ", address(data.token)); + console2.log("index: ", uint256(data.index)); + console2.log("iserc20: ", data.isERC20); + console2.log("isenabled: ", data.isEnabled); + delimit(); + data = instanceRegistry.getInstanceState(cu1_000_000); + console2.log("cu1_000_000:"); + console2.log("token: ", address(data.token)); + console2.log("index: ", uint256(data.index)); + console2.log("iserc20: ", data.isERC20); + console2.log("isenabled: ", data.isEnabled); + delimit(); + console2.log("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); + + // No access + curveFeeOracle.update(TORN, feeOracleManager.populateInstanceWithFeeData(cu10_000)); + // No access view + curveFeeOracle.getFee(TORN, feeOracleManager.populateInstanceWithFeeData(cu10_000)); + + // Some assertions + require( + strcomp(curveFeeOracle.getChainedOracleNameForInstance(cu100), "ETH/CRVUSD"), + "oracle name doesnt match" + ); + require( + strcomp( + curveFeeOracle.getChainedOracleNameForOracleHash( + curveFeeOracle.getChainedOracleHashForInstance(cu1_000) + ), + "ETH/CRVUSD" + ), + "oracle name doesnt match" + ); + + // Now since we will test updating all fees... the oracle will get updated + // but first, warp forward + vm.warp(now + 2 days); + + // Should be able to update all fees + fees = feeOracleManager.updateAllFees(true); + feeOracleManager.version(); + + delimit(); + console2.log("\n~~~~~~~~~~~~~~~~~~ LAST FEES ~~~~~~~~~~~~~~~~~~\n"); + console2.log("cu100: ", uint256(feeOracleManager.getLastFeeForInstance(cu100))); + console2.log("cu1_000: ", uint256(feeOracleManager.getLastFeeForInstance(cu1_000))); + console2.log("cu10_000: ", uint256(feeOracleManager.getLastFeeForInstance(cu10_000))); + console2.log("cu100_000: ", uint256(feeOracleManager.getLastFeeForInstance(cu100_000))); + console2.log("cu1_000_000: ", uint256(feeOracleManager.getLastFeeForInstance(cu1_000_000))); + console2.log("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); + delimit(); + + console2.log( + "\n 💱 I would like to note that I have verified via calculation that post-price move, the fees work.\n Basically: (1000000*30/10000) == fee * 9 / 10^18, should be constant because block is fix. \n" + ); + + // Just for some gas values for this call + instanceRegistry.instanceData(cu100); + instanceRegistry.instanceData(cu1_000); + instanceRegistry.version(); + + router.version(); + + // Let's just check all instances one by one + InstanceState[] memory states = instanceRegistry.getAllInstanceStates(); + + for (uint256 i = 0; i < states.length; i++) { + if (i <= 3) { + require(!states[i].isERC20); + require(states[i].isEnabled); + } else if (i <= 7) { + require(states[i].token == DAI); + require(states[i].isERC20); + require(states[i].isEnabled); + } else if (i <= 11) { + require(states[i].token == CDAI); + require(states[i].isERC20); + require(states[i].isEnabled); + } else if (i <= 13) { + require(states[i].token == USDT); + require(states[i].isERC20); + require(states[i].isEnabled); + } else if (i <= 16) { + require(states[i].token == WBTC); + require(states[i].isERC20); + require(states[i].isEnabled); + } else if (i <= 21) { + require(states[i].token == CRVUSD); + require(states[i].isERC20); + require(states[i].isEnabled); + } + } + + // Now do a specific interval + + states = instanceRegistry.getInstanceState(8, 11); + + for (uint256 i = 0; i < 4; i++) { + require(states[i].token == CDAI); + require(states[i].isERC20); + require(states[i].isEnabled); + } + + // Other for coverage + require(instanceRegistry.isRegisteredInstance(cu10_000)); + + vm.prank(address(governance)); + instanceRegistry.setTornadoRouter(address(0)); + require(address(instanceRegistry.router()) == address(0)); + } + function test_infrastructureBasic() public { // Do the proposal first test_infrastructureUpgradeProposalBasic(); @@ -437,16 +629,34 @@ contract ProposalTests is Instances, TornadoProposalTest { feeOracleManager.setInstanceRegistry(address(instanceRegistry)); } + function test_crvusdInstancesProposalBasic() public { + // First pass the former proposal + test_infrastructureUpgradeProposalBasic(); + + // Then create the crvUSD proposal + address proposal = + address(new CRVUSDInstancesProposal(address(curveFeeOracle), address(uniswapFeeOracle))); + + // Propose + uint256 id = easyPropose(proposal); + + // Wait + waitUntilExecutable(id); + + // Exec + governance.execute(id); + } + function test_infrastructureUpgradeProposalBasic() public { // Create proposal address proposal = address( new InfrastructureUpgradeProposal( - address(uniswapFeeOracle), - address(implRegistry), + address(router), address(implStaking), - address(implFeeOracleManager), + address(implRegistry), address(implInstanceRegistry), - address(router) + address(implFeeOracleManager), + address(uniswapFeeOracle) ) );