Configure for presentation
Signed-off-by: AlienTornadosaurusHex <>
This commit is contained in:
parent
6b480c62cf
commit
2f53f4959c
@ -1,183 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
// OZ Imports
|
||||
|
||||
import { AdminUpgradeableProxy } from "../common/AdminUpgradeableProxy.sol";
|
||||
|
||||
// Tornado imports
|
||||
|
||||
import { ITornadoInstance } from "tornado-anonymity-mining/contracts/interfaces/ITornadoInstance.sol";
|
||||
|
||||
// Local V2 imports
|
||||
|
||||
import { FeeOracleManager } from "../v2/FeeOracleManager.sol";
|
||||
|
||||
import { InstanceRegistry } from "../v2/InstanceRegistry.sol";
|
||||
|
||||
import { CurveFeeOracle, ICurvePriceOracle, CurveChainedOracles } from "../v2/CurveFeeOracle.sol";
|
||||
|
||||
import { UniswapFeeOracle } from "../v2/UniswapFeeOracle.sol";
|
||||
|
||||
import { TornadoRouter } from "../v2/TornadoRouter.sol";
|
||||
|
||||
/**
|
||||
* @title CRVUSDInstancesProposal
|
||||
* @author AlienTornadosaurusHex
|
||||
* @notice Proposal to add crvUSD instances in 100, 1000, 10000, 100000, 1000000 denominations.
|
||||
*/
|
||||
contract CRVUSDInstancesProposal {
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VARIABLES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/* @dev The first Curve pool which is capable of being used as a safe oracle due to analytical EMA price */
|
||||
address public constant crvUSDUSDCStableswap2Pool = 0x4DEcE678ceceb27446b35C672dC7d61F30bAD69E;
|
||||
|
||||
/* @dev The second Curve pool which is capable of being used as a safe oracle due to analytical EMA price */
|
||||
address public constant tricryptoUSDCPool = 0x7F86Bf177Dd4F3494b841a37e810A34dD56c829B;
|
||||
|
||||
/* @dev The InstanceRegistry contract, for registering instances, proxy must be upgraded */
|
||||
InstanceRegistry public constant instanceRegistry =
|
||||
InstanceRegistry(0xB20c66C4DE72433F3cE747b58B86830c459CA911);
|
||||
|
||||
/* @dev The FeeOracleManager contract, proxy must be upgraded */
|
||||
FeeOracleManager public constant feeOracleManager =
|
||||
FeeOracleManager(0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7);
|
||||
|
||||
/* @dev This is the Uniswap V3 Oracle which we will use for all of our traditional instances, but it will
|
||||
also help the Curve instances, the former must have been deployed with the address of this */
|
||||
UniswapFeeOracle public immutable uniswapFeeOracle;
|
||||
|
||||
/* @dev This is the CurveFeeOracle contract which will be deployed beforehand and which will be able to
|
||||
use multiple Curve pools as oracles, at once. */
|
||||
CurveFeeOracle public immutable curveFeeOracle;
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LOGIC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
constructor(address _deployedCurveFeeOracleAddress, address _deployedUniswapFeeOracleAddress) public {
|
||||
curveFeeOracle = CurveFeeOracle(_deployedCurveFeeOracleAddress);
|
||||
uniswapFeeOracle = UniswapFeeOracle(_deployedUniswapFeeOracleAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev This function also executes further internal functions inlined below.
|
||||
*/
|
||||
function executeProposal() external {
|
||||
// Load the deployed crvUSD instances
|
||||
|
||||
ITornadoInstance cu100 = ITornadoInstance(0x913a73486Dc4AA3832A56d461542836C1eeB93be);
|
||||
ITornadoInstance cu1_000 = ITornadoInstance(0x5A6b3C829dB3e938C885000c6E93CF35E74876a4);
|
||||
ITornadoInstance cu10_000 = ITornadoInstance(0x49f173CDAB99a2C3800F1255393DF9B7a17B82Bb);
|
||||
ITornadoInstance cu100_000 = ITornadoInstance(0x4640Dffc9fD0B113B983e3A350b070a119CA143C);
|
||||
ITornadoInstance cu1_000_000 = ITornadoInstance(0xc4eA8Bd3Fd76f3c255395793B47F7c55aD59d991);
|
||||
|
||||
// Ok, first add the Uniswap V3 Oracle to the contract
|
||||
|
||||
curveFeeOracle.setUniswapFeeOracle(uniswapFeeOracle);
|
||||
|
||||
// Then, add necessary oracles for the CRVUSD price, to the CurveFeeOracle
|
||||
|
||||
_setCurveFeeChainedOracleForInstance(curveFeeOracle, cu100);
|
||||
_setCurveFeeChainedOracleForInstance(curveFeeOracle, cu1_000);
|
||||
_setCurveFeeChainedOracleForInstance(curveFeeOracle, cu10_000);
|
||||
_setCurveFeeChainedOracleForInstance(curveFeeOracle, cu100_000);
|
||||
_setCurveFeeChainedOracleForInstance(curveFeeOracle, cu1_000_000);
|
||||
|
||||
// Then, add the instances to the InstanceRegistry
|
||||
|
||||
instanceRegistry.addInstance(cu100);
|
||||
instanceRegistry.addInstance(cu1_000);
|
||||
instanceRegistry.addInstance(cu10_000);
|
||||
instanceRegistry.addInstance(cu100_000);
|
||||
instanceRegistry.addInstance(cu1_000_000);
|
||||
|
||||
// The fee will be 0.3 % for those pools for which it makes sense
|
||||
|
||||
feeOracleManager.setFeePercentForInstance(cu100, 0);
|
||||
feeOracleManager.setFeePercentForInstance(cu1_000, 0);
|
||||
feeOracleManager.setFeePercentForInstance(cu10_000, 30);
|
||||
feeOracleManager.setFeePercentForInstance(cu100_000, 30);
|
||||
feeOracleManager.setFeePercentForInstance(cu1_000_000, 30);
|
||||
|
||||
// Make the update interval 6 hours
|
||||
|
||||
feeOracleManager.setFeeUpdateIntervalForInstance(cu100, 6 hours);
|
||||
feeOracleManager.setFeeUpdateIntervalForInstance(cu1_000, 6 hours);
|
||||
feeOracleManager.setFeeUpdateIntervalForInstance(cu10_000, 6 hours);
|
||||
feeOracleManager.setFeeUpdateIntervalForInstance(cu100_000, 6 hours);
|
||||
feeOracleManager.setFeeUpdateIntervalForInstance(cu1_000_000, 6 hours);
|
||||
|
||||
// Finally, set all necessary data in the FeeOracleManager
|
||||
|
||||
feeOracleManager.setFeeOracle(address(cu100), address(curveFeeOracle));
|
||||
feeOracleManager.setFeeOracle(address(cu1_000), address(curveFeeOracle));
|
||||
feeOracleManager.setFeeOracle(address(cu10_000), address(curveFeeOracle));
|
||||
feeOracleManager.setFeeOracle(address(cu100_000), address(curveFeeOracle));
|
||||
feeOracleManager.setFeeOracle(address(cu1_000_000), address(curveFeeOracle));
|
||||
|
||||
// Update them all at the start
|
||||
|
||||
address router = feeOracleManager.feeUpdaterAddress();
|
||||
|
||||
feeOracleManager.setFeeUpdater(address(this));
|
||||
|
||||
feeOracleManager.updateFee(cu100, false);
|
||||
feeOracleManager.updateFee(cu1_000, false);
|
||||
feeOracleManager.updateFee(cu10_000, false);
|
||||
feeOracleManager.updateFee(cu100_000, false);
|
||||
feeOracleManager.updateFee(cu1_000_000, false);
|
||||
|
||||
feeOracleManager.setFeeUpdater(router);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev This function adds pools as fee oracles to the main curve fee oracle contract. The oracles are
|
||||
* chained, this means that multiple pools can be used as one oracle using the library which can be found
|
||||
* in the contract file. This means:
|
||||
*
|
||||
* (...pool contracts as oracles) ===(`price_oracle`)===> CurveFeeOracle ===(`getFee()`)===>
|
||||
* FeeOracleManager ===(`instanceFeeWithUpdate`)===> RelayerRegistry
|
||||
*/
|
||||
function _setCurveFeeChainedOracleForInstance(CurveFeeOracle _feeOracle, ITornadoInstance _instance)
|
||||
internal
|
||||
{
|
||||
// Add the oracles which are the USDC/CRVUSD stableswap and tricryptoUSDC pools
|
||||
|
||||
ICurvePriceOracle[] memory _oracles = new ICurvePriceOracle[](2);
|
||||
|
||||
_oracles[0] = ICurvePriceOracle(crvUSDUSDCStableswap2Pool);
|
||||
_oracles[1] = ICurvePriceOracle(tricryptoUSDCPool);
|
||||
|
||||
// Add the selectors, so which functions to call because tricrypto pools supports getting prices for
|
||||
// multiple tokens, denominated in the first token, which is usually a stable
|
||||
|
||||
bytes4[] memory _selectors = new bytes4[](2);
|
||||
|
||||
_selectors[0] = CurveChainedOracles.PRICE_ORACLE_SELECTOR;
|
||||
_selectors[1] = CurveChainedOracles.PRICE_ORACLE_UINT256_SELECTOR;
|
||||
|
||||
// Specify for the second that the ether price must be retrieved
|
||||
|
||||
uint8[] memory _coins = new uint8[](2);
|
||||
|
||||
_coins[1] = 1; // ETHER
|
||||
|
||||
// In order to receive the CRVUSD price, its price in USDC must be read out (the USDC price in crvUSD
|
||||
// is worthless because we do not have a common denominator in the oracle then) and then the second
|
||||
// price must be inverted to receive the accurate ETH/CRVUSD price, meaning ETH per CRVUSD, which will
|
||||
// then be divided by ETH per TORN, and then (ETH/CRVUSD)/(ETH/TORN) = (ETH/CRVUSD)*(TORN/ETH) =
|
||||
// (TORN/CRVUSD) which is the price that the oracle should be supplying
|
||||
|
||||
bool[] memory _invert = new bool[](2);
|
||||
|
||||
_invert[0] = false; // DO NOT INVERT, PRICE IS CRVUSD IN USDC
|
||||
_invert[1] = true; // INVERT, PRICE IS ETH IN USDC, BUT WE NEED USDC IN ETH
|
||||
|
||||
// (USDC/CRVUSD)*(ETH/USDC) = (ETH/CRVUSD)
|
||||
|
||||
_feeOracle.modifyChainedOracleForInstance(
|
||||
_instance, _oracles, _selectors, _coins, _invert, "ETH/CRVUSD"
|
||||
);
|
||||
}
|
||||
}
|
@ -35,8 +35,6 @@ 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";
|
||||
@ -77,14 +75,6 @@ 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 {
|
||||
@ -165,188 +155,6 @@ 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();
|
||||
@ -629,24 +437,6 @@ 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(
|
||||
|
Loading…
Reference in New Issue
Block a user