2023-06-10 03:14:20 +03:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
pragma solidity ^0.6.12;
|
|
|
|
pragma experimental ABIEncoderV2;
|
|
|
|
|
|
|
|
// OZ Imports
|
|
|
|
|
|
|
|
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
|
|
2023-06-10 20:39:07 +03:00
|
|
|
// STD Imports
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-10 20:39:07 +03:00
|
|
|
import { console2 } from "forge-std/console2.sol";
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
// Tornado imports
|
|
|
|
|
|
|
|
import { ITornadoInstance } from "tornado-anonymity-mining/contracts/interfaces/ITornadoInstance.sol";
|
|
|
|
|
2023-06-10 20:39:07 +03:00
|
|
|
// Local imports
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
import { UniswapFeeOracle } from "src/v2/UniswapFeeOracle.sol";
|
2023-06-10 03:14:20 +03:00
|
|
|
|
|
|
|
import { CurveFeeOracle, ICurvePriceOracle, CurveChainedOracles } from "src/v2/CurveFeeOracle.sol";
|
|
|
|
|
2023-06-16 19:12:22 +03:00
|
|
|
import { InstanceRegistry, InstanceState } from "src/v2/InstanceRegistry.sol";
|
2023-06-10 03:14:20 +03:00
|
|
|
|
|
|
|
import { FeeOracleManager } from "src/v2/FeeOracleManager.sol";
|
|
|
|
|
|
|
|
import { TornadoRouter } from "src/v2/TornadoRouter.sol";
|
|
|
|
|
2023-06-10 20:39:07 +03:00
|
|
|
import { InfrastructureUpgradeProposal } from "src/proposals/InfrastructureUpgradeProposal.sol";
|
|
|
|
|
|
|
|
import { CRVUSDInstancesProposal } from "src/proposals/CRVUSDInstancesProposal.sol";
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
import { IUniswapV2Pair } from "src/v2/interfaces/IUniswapV2Pair.sol";
|
|
|
|
|
|
|
|
import { FeeOracleManager, FeeDataForOracle, InstanceWithFee } from "src/v2/FeeOracleManager.sol";
|
|
|
|
|
2023-06-10 03:14:20 +03:00
|
|
|
// Test imports
|
|
|
|
|
2023-06-10 20:39:07 +03:00
|
|
|
import { TornadoProposalTest, ProposalState } from "./TornadoProposalTest.sol";
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
interface IWethDepositable {
|
|
|
|
function deposit() external payable;
|
|
|
|
}
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
contract Instances {
|
|
|
|
/* ETH instances */
|
|
|
|
ITornadoInstance public constant eth01 = ITornadoInstance(0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc);
|
|
|
|
ITornadoInstance public constant eth1 = ITornadoInstance(0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936);
|
|
|
|
ITornadoInstance public constant eth10 = ITornadoInstance(0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF);
|
|
|
|
ITornadoInstance public constant eth100 = ITornadoInstance(0xA160cdAB225685dA1d56aa342Ad8841c3b53f291);
|
|
|
|
|
|
|
|
/* DAI instances */
|
|
|
|
ITornadoInstance public constant dai100 = ITornadoInstance(0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3);
|
|
|
|
ITornadoInstance public constant dai1000 = ITornadoInstance(0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144);
|
|
|
|
ITornadoInstance public constant dai10000 = ITornadoInstance(0x07687e702b410Fa43f4cB4Af7FA097918ffD2730);
|
|
|
|
ITornadoInstance public constant dai100000 = ITornadoInstance(0x23773E65ed146A459791799d01336DB287f25334);
|
|
|
|
|
|
|
|
/* cDAI instances */
|
|
|
|
ITornadoInstance public constant cdai100 = ITornadoInstance(0x22aaA7720ddd5388A3c0A3333430953C68f1849b);
|
|
|
|
ITornadoInstance public constant cdai1000 = ITornadoInstance(0x03893a7c7463AE47D46bc7f091665f1893656003);
|
|
|
|
ITornadoInstance public constant cdai10000 = ITornadoInstance(0x2717c5e28cf931547B621a5dddb772Ab6A35B701);
|
|
|
|
ITornadoInstance public constant cdai100000 = ITornadoInstance(0xD21be7248e0197Ee08E0c20D4a96DEBdaC3D20Af);
|
|
|
|
|
|
|
|
/* USDT instances */
|
|
|
|
ITornadoInstance public constant usdt100 = ITornadoInstance(0x169AD27A470D064DEDE56a2D3ff727986b15D52B);
|
|
|
|
ITornadoInstance public constant usdt1000 = ITornadoInstance(0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f);
|
|
|
|
|
|
|
|
/* WBTC 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 {
|
2023-06-10 03:14:20 +03:00
|
|
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VARIABLES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
// Tokens
|
|
|
|
|
2023-06-10 03:14:20 +03:00
|
|
|
IERC20 public constant TORN = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C);
|
2023-06-16 04:12:39 +03:00
|
|
|
IERC20 public constant DAI = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);
|
2023-06-17 01:38:42 +03:00
|
|
|
IERC20 internal constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
|
|
|
|
|
|
|
|
// Infra contracts constant
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
FeeOracleManager public constant feeOracleManager =
|
|
|
|
FeeOracleManager(0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7);
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
InstanceRegistry public constant instanceRegistry =
|
|
|
|
InstanceRegistry(0xB20c66C4DE72433F3cE747b58B86830c459CA911);
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
IUniswapV2Pair public constant uniTornPool = IUniswapV2Pair(0x0C722a487876989Af8a05FFfB6e32e45cc23FB3A);
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
// Implementations
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-10 20:39:07 +03:00
|
|
|
InstanceRegistry implInstanceRegisty;
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
FeeOracleManager implFeeOracleManager;
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
// Infra contracts mutable
|
2023-06-16 04:12:39 +03:00
|
|
|
|
|
|
|
CurveFeeOracle curveFeeOracle;
|
|
|
|
|
|
|
|
UniswapFeeOracle uniswapFeeOracle;
|
2023-06-10 03:14:20 +03:00
|
|
|
|
|
|
|
TornadoRouter router;
|
|
|
|
|
|
|
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TESTING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
function setUp() public override {
|
2023-06-16 04:12:39 +03:00
|
|
|
TornadoProposalTest.setUp();
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
vm.rollFork(17_486_841);
|
2023-06-10 20:39:07 +03:00
|
|
|
|
|
|
|
curveFeeOracle = new CurveFeeOracle(address(governance));
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
uniswapFeeOracle = new UniswapFeeOracle(address(governance), address(feeOracleManager));
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-10 20:39:07 +03:00
|
|
|
vm.prank(address(governance));
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
curveFeeOracle.setUniswapFeeOracle(uniswapFeeOracle);
|
2023-06-10 20:39:07 +03:00
|
|
|
|
|
|
|
implInstanceRegisty = new InstanceRegistry(address(governance));
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
implFeeOracleManager = new FeeOracleManager(address(TORN), address(governance));
|
|
|
|
|
|
|
|
router = TornadoRouter(vm.envAddress("TORNADO_ROUTER_ADDRESS"));
|
2023-06-17 01:38:42 +03:00
|
|
|
|
|
|
|
_advanceTORNETHMarket();
|
2023-06-16 04:12:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function test_crvusdInstancesBasic() public {
|
|
|
|
// Do the proposal first
|
|
|
|
test_crvusdInstancesProposalBasic();
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
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~~~~~~~~~~~~~~~~~~ UPDATED FEES ~~~~~~~~~~~~~~~~~~\n");
|
|
|
|
console2.log("cu100: ", uint256(feeOracleManager.instanceFeeWithUpdate(cu100)));
|
|
|
|
console2.log("cu1_000: ", uint256(feeOracleManager.instanceFeeWithUpdate(cu1_000)));
|
|
|
|
console2.log("cu10_000: ", uint256(feeOracleManager.instanceFeeWithUpdate(cu10_000)));
|
|
|
|
console2.log("cu100_000: ", uint256(feeOracleManager.instanceFeeWithUpdate(cu100_000)));
|
|
|
|
console2.log("cu1_000_000: ", uint256(feeOracleManager.instanceFeeWithUpdate(cu1_000_000)));
|
|
|
|
console2.log("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
|
|
|
|
|
|
|
delimit();
|
|
|
|
|
|
|
|
console2.log("\n~~~~~~~~~~~~~~~~~~ DATA ~~~~~~~~~~~~~~~~~~\n");
|
2023-06-16 19:12:22 +03:00
|
|
|
InstanceState memory data = instanceRegistry.getInstanceState(cu100);
|
2023-06-16 04:12:39 +03:00
|
|
|
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();
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(cu1_000);
|
2023-06-16 04:12:39 +03:00
|
|
|
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();
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(cu10_000);
|
2023-06-16 04:12:39 +03:00
|
|
|
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();
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(cu100_000);
|
2023-06-16 04:12:39 +03:00
|
|
|
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();
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(cu1_000_000);
|
2023-06-16 04:12:39 +03:00
|
|
|
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");
|
|
|
|
|
2023-06-17 01:47:51 +03:00
|
|
|
curveFeeOracle.update(TORN, feeOracleManager.populateInstanceWithFeeData(cu10_000));
|
|
|
|
curveFeeOracle.getFee(TORN, feeOracleManager.populateInstanceWithFeeData(cu10_000));
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
// 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"
|
|
|
|
);
|
|
|
|
|
|
|
|
// Should be able to update all fees
|
|
|
|
feeOracleManager.updateAllFees(true);
|
|
|
|
feeOracleManager.updateAllFees(false);
|
|
|
|
|
|
|
|
// Just for some gas values for this call
|
|
|
|
instanceRegistry.instanceData(cu100);
|
|
|
|
instanceRegistry.instanceData(cu1_000);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_infrastructureBasic() public {
|
|
|
|
// Do the proposal first
|
|
|
|
test_infrastructureUpgradeProposalBasic();
|
|
|
|
|
|
|
|
// Try to update eth10
|
|
|
|
feeOracleManager.updateFee(eth10, false);
|
|
|
|
|
|
|
|
// Try to update multiple
|
|
|
|
ITornadoInstance[] memory _toUpdate = new ITornadoInstance[](3);
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
console2.log(uint256(feeOracleManager.getLastFeeForInstance(eth100)));
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
_toUpdate[0] = eth100;
|
|
|
|
_toUpdate[1] = dai10000;
|
|
|
|
_toUpdate[2] = usdt100;
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
console2.log(uint256(feeOracleManager.getLastFeeForInstance(eth100)));
|
2023-06-16 04:12:39 +03:00
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
feeOracleManager.updateFees(_toUpdate, false);
|
|
|
|
console2.log("BOBO", uint256(feeOracleManager.getLastFeeForInstance(eth100)));
|
2023-06-16 04:12:39 +03:00
|
|
|
require(feeOracleManager.getLastUpdatedTimeForInstance(eth100) == now, "timeup");
|
|
|
|
|
|
|
|
// Must not be able to re-initialize the InstanceRegistry
|
|
|
|
|
|
|
|
vm.expectRevert();
|
|
|
|
vm.prank(address(governance));
|
|
|
|
instanceRegistry.initialize(_toUpdate, router);
|
|
|
|
|
|
|
|
vm.expectRevert();
|
|
|
|
instanceRegistry.initialize(_toUpdate, router);
|
|
|
|
|
|
|
|
// Must not be able to re-initialize the FeeOracleManager
|
|
|
|
|
|
|
|
vm.expectRevert();
|
|
|
|
vm.prank(address(governance));
|
|
|
|
feeOracleManager.initialize(
|
|
|
|
address(uniswapFeeOracle), address(instanceRegistry), _toUpdate, feeArrayForTesting_1()
|
|
|
|
);
|
|
|
|
|
|
|
|
vm.expectRevert();
|
|
|
|
feeOracleManager.initialize(
|
|
|
|
address(uniswapFeeOracle), address(instanceRegistry), _toUpdate, feeArrayForTesting_1()
|
|
|
|
);
|
|
|
|
|
|
|
|
// Must not be able to re-initialize the router... the contract addresses are unimportant
|
|
|
|
|
|
|
|
vm.expectRevert();
|
|
|
|
vm.prank(address(governance));
|
|
|
|
router.initialize(address(instanceRegistry), address(instanceRegistry));
|
|
|
|
|
|
|
|
vm.expectRevert();
|
|
|
|
router.initialize(address(instanceRegistry), address(instanceRegistry));
|
|
|
|
|
|
|
|
// Check fee logic and print to console.
|
|
|
|
|
|
|
|
console2.log("\n~~~~~~~~~~~~~~~~~~ LAST FEES ~~~~~~~~~~~~~~~~~~\n");
|
|
|
|
console2.log("eth10: ", uint256(feeOracleManager.getLastFeeForInstance(eth10)));
|
|
|
|
console2.log("eth100: ", uint256(feeOracleManager.getLastFeeForInstance(eth100)));
|
|
|
|
console2.log("dai10000: ", uint256(feeOracleManager.getLastFeeForInstance(dai10000)));
|
|
|
|
console2.log("usdt100: ", uint256(feeOracleManager.getLastFeeForInstance(usdt100)));
|
|
|
|
console2.log("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
|
|
|
|
|
|
|
delimit();
|
2023-06-17 01:38:42 +03:00
|
|
|
console2.log("BOBO", uint256(feeOracleManager.getLastFeeForInstance(eth100)));
|
2023-06-16 04:12:39 +03:00
|
|
|
console2.log("\n~~~~~~~~~~~~~~~~~~ UPDATED FEES ~~~~~~~~~~~~~~~~~~\n");
|
|
|
|
console2.log("eth10: ", uint256(feeOracleManager.instanceFeeWithUpdate(eth10)));
|
|
|
|
console2.log("eth100: ", uint256(feeOracleManager.instanceFeeWithUpdate(eth100)));
|
|
|
|
console2.log("dai10000: ", uint256(feeOracleManager.instanceFeeWithUpdate(dai10000)));
|
|
|
|
console2.log("usdt100: ", uint256(feeOracleManager.instanceFeeWithUpdate(usdt100)));
|
|
|
|
console2.log("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
2023-06-17 01:38:42 +03:00
|
|
|
console2.log("BOBO", uint256(feeOracleManager.getLastFeeForInstance(eth100)));
|
2023-06-16 04:12:39 +03:00
|
|
|
delimit();
|
|
|
|
|
|
|
|
console2.log("\n~~~~~~~~~~~~~~~~~~ DATA ~~~~~~~~~~~~~~~~~~\n");
|
2023-06-16 19:12:22 +03:00
|
|
|
InstanceState memory data = instanceRegistry.getInstanceState(eth10);
|
2023-06-16 04:12:39 +03:00
|
|
|
delimit();
|
|
|
|
console2.log("eth10:");
|
|
|
|
console2.log("token: ", address(data.token));
|
|
|
|
console2.log("index: ", uint256(data.index));
|
|
|
|
console2.log("iserc20: ", data.isERC20);
|
|
|
|
console2.log("isenabled: ", data.isEnabled);
|
|
|
|
delimit();
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(eth100);
|
2023-06-16 04:12:39 +03:00
|
|
|
console2.log("eth100:");
|
|
|
|
console2.log("token: ", address(data.token));
|
|
|
|
console2.log("index: ", uint256(data.index));
|
|
|
|
console2.log("iserc20: ", data.isERC20);
|
|
|
|
console2.log("isenabled: ", data.isEnabled);
|
|
|
|
delimit();
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(dai10000);
|
2023-06-16 04:12:39 +03:00
|
|
|
console2.log("dai10000:");
|
|
|
|
console2.log("token: ", address(data.token));
|
|
|
|
console2.log("index: ", uint256(data.index));
|
|
|
|
console2.log("iserc20: ", data.isERC20);
|
|
|
|
console2.log("isenabled: ", data.isEnabled);
|
|
|
|
delimit();
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(usdt100);
|
2023-06-16 04:12:39 +03:00
|
|
|
console2.log("usdt100:");
|
|
|
|
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");
|
|
|
|
|
|
|
|
// Now should be able to rmemove an instance
|
|
|
|
vm.prank(address(governance));
|
|
|
|
instanceRegistry.removeInstanceByAddress(address(dai10000)); // DAI10k
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
|
|
|
instanceRegistry.removeInstanceByIndex(2); // ETH10
|
|
|
|
|
|
|
|
// Now log again
|
|
|
|
console2.log("\n~~~~~~~~~~~~~~~~~~ SHOULD HAVE CHANGED ~~~~~~~~~~~~~~~~~~\n");
|
|
|
|
delimit();
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(2);
|
2023-06-16 04:12:39 +03:00
|
|
|
console2.log("NOT eth10:");
|
|
|
|
console2.log("token: ", address(data.token));
|
|
|
|
console2.log("index: ", uint256(data.index));
|
|
|
|
console2.log("iserc20: ", data.isERC20);
|
|
|
|
console2.log("isenabled: ", data.isEnabled);
|
|
|
|
delimit();
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(6);
|
2023-06-16 04:12:39 +03:00
|
|
|
console2.log("NOT dai10000:");
|
|
|
|
console2.log("token: ", address(data.token));
|
|
|
|
console2.log("index: ", uint256(data.index));
|
|
|
|
console2.log("iserc20: ", data.isERC20);
|
|
|
|
console2.log("isenabled: ", data.isEnabled);
|
|
|
|
console2.log("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
|
|
|
|
|
|
|
// Now add them back and only do assertions
|
|
|
|
vm.prank(address(governance));
|
|
|
|
instanceRegistry.addInstance(dai10000);
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
|
|
|
instanceRegistry.addInstance(eth10);
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(dai10000);
|
2023-06-16 04:12:39 +03:00
|
|
|
require(data.token == DAI, "not dai");
|
|
|
|
require(data.index == 15, "not 15");
|
|
|
|
require(data.isERC20, "not token");
|
|
|
|
require(data.isEnabled, "not enabled");
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
2023-06-16 19:12:22 +03:00
|
|
|
data = instanceRegistry.getInstanceState(eth10);
|
2023-06-16 04:12:39 +03:00
|
|
|
require(data.token == IERC20(0), "not eth");
|
|
|
|
require(data.index == 16, "not last");
|
|
|
|
require(!data.isERC20, "not not token");
|
|
|
|
require(data.isEnabled, "not enabled");
|
|
|
|
|
|
|
|
// Some assertions to test getters
|
|
|
|
require(instanceRegistry.getInstanceIndex(eth100) == 3, "Wrong index");
|
|
|
|
require(instanceRegistry.getInstanceToken(eth100) == IERC20(address(0)), "Wrong token");
|
|
|
|
require(instanceRegistry.getInstanceToken(dai10000) == DAI, "Wrong token");
|
|
|
|
require(instanceRegistry.isEnabledInstance(dai10000) == true, "Wrong token");
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
// Just to get some gas values for these fns
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
instanceRegistry.instanceData(eth10);
|
|
|
|
instanceRegistry.instanceData(eth100);
|
|
|
|
instanceRegistry.instanceData(dai10000);
|
2023-06-17 01:38:42 +03:00
|
|
|
uniswapFeeOracle.getTWAPData();
|
|
|
|
uniswapFeeOracle.getLastUpdatedTime();
|
|
|
|
|
|
|
|
vm.expectRevert();
|
|
|
|
uniswapFeeOracle.update(
|
|
|
|
TORN,
|
|
|
|
InstanceWithFee({
|
|
|
|
logic: eth100,
|
|
|
|
state: InstanceState(WETH, 0, false, false),
|
|
|
|
fee: FeeDataForOracle(0, 0, 0, 2 days, 0)
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
vm.expectRevert();
|
|
|
|
uniswapFeeOracle.setFeeOracleManagerAddress(address(0));
|
|
|
|
vm.expectRevert();
|
|
|
|
uniswapFeeOracle.setMinObservationCardinality(0);
|
|
|
|
vm.expectRevert();
|
|
|
|
uniswapFeeOracle.setPoolFeeForToken(WETH, 0);
|
2023-06-16 04:12:39 +03:00
|
|
|
|
|
|
|
// Expect no update if in inside the time limit interval
|
|
|
|
|
|
|
|
uint256 startTimestamp = block.timestamp;
|
|
|
|
uint256 interval = feeOracleManager.getFeeUpdateIntervalForInstance(eth100);
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
vm.warp(startTimestamp + interval + 5 days);
|
|
|
|
|
|
|
|
feeOracleManager.updateFee(eth100, true);
|
|
|
|
uint256 eth100Fee = feeOracleManager.getLastFeeForInstance(eth100);
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
vm.prank(address(governance));
|
|
|
|
feeOracleManager.setFeePercentForInstance(eth100, 50);
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
// both shouldnt update
|
2023-06-16 04:12:39 +03:00
|
|
|
feeOracleManager.updateFee(eth100, true);
|
2023-06-17 01:38:42 +03:00
|
|
|
uint32 lastUpdatedTimeHere = feeOracleManager.getLastUpdatedTimeForInstance(eth100);
|
|
|
|
vm.prank(address(feeOracleManager));
|
|
|
|
uniswapFeeOracle.update(
|
|
|
|
TORN,
|
|
|
|
InstanceWithFee({
|
|
|
|
logic: eth100,
|
|
|
|
state: InstanceState(WETH, 0, false, false),
|
|
|
|
fee: FeeDataForOracle(0, 0, 0, 2 days, lastUpdatedTimeHere)
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
require(eth100Fee == feeOracleManager.getLastFeeForInstance(eth100), "wrong fee 1");
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
vm.warp(startTimestamp + 2 * interval + 10 days);
|
2023-06-16 04:12:39 +03:00
|
|
|
|
|
|
|
feeOracleManager.updateFee(eth100, true);
|
|
|
|
uint256 eth100Fee2 = feeOracleManager.getLastFeeForInstance(eth100);
|
|
|
|
require(eth100Fee != eth100Fee2, "wrong fee 2");
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
|
|
|
feeOracleManager.setFeePercentForInstance(eth100, 30);
|
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
vm.warp(startTimestamp + 3 * interval + 15 days);
|
2023-06-16 04:12:39 +03:00
|
|
|
|
|
|
|
feeOracleManager.updateFee(eth100, true);
|
|
|
|
require(eth100Fee == feeOracleManager.getLastFeeForInstance(eth100), "wrong fee 3");
|
|
|
|
|
|
|
|
vm.warp(startTimestamp);
|
|
|
|
|
|
|
|
// Should be able to update all fees
|
2023-06-17 01:38:42 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
feeOracleManager.updateAllFees(true);
|
|
|
|
feeOracleManager.updateAllFees(false);
|
|
|
|
|
|
|
|
// Deviations don't revert
|
|
|
|
|
|
|
|
feeOracleManager.getAllFeeDeviations();
|
2023-06-10 03:14:20 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
// There is a deviation
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
|
|
|
feeOracleManager.setFeePercentForInstance(eth100, 10);
|
|
|
|
|
|
|
|
_toUpdate = new ITornadoInstance[](1);
|
|
|
|
|
|
|
|
_toUpdate[0] = eth100;
|
|
|
|
|
|
|
|
int256[] memory eth100Deviations = feeOracleManager.getFeeDeviationsForInstances(_toUpdate);
|
|
|
|
|
|
|
|
require(eth100Deviations[0] != 0, "deviations");
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
|
|
|
feeOracleManager.setFeePercentForInstance(eth100, 30);
|
|
|
|
|
|
|
|
feeOracleManager.updateFee(eth100, false);
|
|
|
|
|
|
|
|
// Should be able to deposit via router
|
|
|
|
|
|
|
|
address depositor = address(bytes20(bytes32(keccak256("depositor"))));
|
|
|
|
|
|
|
|
vm.deal(depositor, 1 ether); // for gas
|
|
|
|
|
|
|
|
vm.prank(address(DAI));
|
|
|
|
DAI.transfer(depositor, 100_000e18);
|
|
|
|
|
|
|
|
require(DAI.balanceOf(depositor) == 100_000e18, "not enough depo bal");
|
|
|
|
|
|
|
|
vm.prank(address(depositor));
|
|
|
|
DAI.approve(address(router), 100_000e18);
|
|
|
|
|
|
|
|
bytes32 commitment = 0x00eb84375e4bfd042468fe624e6d322dba4f601b37dd0a44f741d3cb04127df0;
|
|
|
|
|
|
|
|
bytes memory empty;
|
|
|
|
|
|
|
|
vm.prank(address(depositor));
|
|
|
|
|
|
|
|
router.deposit(dai100000, commitment, empty);
|
|
|
|
|
|
|
|
// Let's toss in some functions for coverage
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
|
|
|
feeOracleManager.setFeeUpdateIntervalForInstance(eth100, 60_000);
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
|
|
|
feeOracleManager.setFeeUpdateIntervalForInstance(eth100, uint24(interval));
|
|
|
|
|
|
|
|
require(feeOracleManager.getFeePercentForInstance(eth100) == 30, "fee percent eth100");
|
|
|
|
require(feeOracleManager.getLastUpdatedTimeForInstance(eth100) == now, "updated time eth100");
|
|
|
|
|
|
|
|
// Reverts
|
|
|
|
|
|
|
|
vm.expectRevert();
|
|
|
|
feeOracleManager.setInstanceRegistry(address(0));
|
|
|
|
vm.expectRevert();
|
|
|
|
feeOracleManager.setFeeOracle(address(eth100), address(0));
|
|
|
|
vm.expectRevert();
|
|
|
|
feeOracleManager.setFeePercentForInstance(eth100, 40);
|
|
|
|
vm.expectRevert();
|
|
|
|
feeOracleManager.setFeeUpdateIntervalForInstance(eth100, uint24(interval - 3));
|
|
|
|
|
|
|
|
// Should be able to delete and set an oracle
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
|
|
|
feeOracleManager.setFeeOracle(address(eth100), address(0));
|
|
|
|
|
|
|
|
require(address(feeOracleManager.instanceFeeOracles(eth100)) == address(0), "fee oracle deletion");
|
|
|
|
|
|
|
|
vm.prank(address(governance));
|
|
|
|
feeOracleManager.setFeeOracle(address(eth100), address(uniswapFeeOracle));
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2023-06-10 03:14:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function test_infrastructureUpgradeProposalBasic() public {
|
|
|
|
// Create proposal
|
|
|
|
address proposal = address(
|
|
|
|
new InfrastructureUpgradeProposal(
|
2023-06-16 04:12:39 +03:00
|
|
|
address(uniswapFeeOracle),
|
|
|
|
address(implFeeOracleManager),
|
2023-06-10 03:14:20 +03:00
|
|
|
address(implInstanceRegisty),
|
|
|
|
address(router)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
// Propose
|
|
|
|
uint256 id = easyPropose(proposal);
|
|
|
|
|
|
|
|
// Wait
|
|
|
|
waitUntilExecutable(id);
|
|
|
|
|
|
|
|
// Exec
|
|
|
|
governance.execute(id);
|
2023-06-10 20:39:07 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
// Test whethe resolving names works... with the Governance contract
|
2023-06-10 20:39:07 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
require(
|
|
|
|
address(instanceRegistry.getInstanceByENSName("governance.contract.tornadocash.eth"))
|
|
|
|
== address(governance),
|
|
|
|
"ENSResolving doesn't work"
|
|
|
|
);
|
|
|
|
}
|
2023-06-10 20:39:07 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HELPERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2023-06-10 20:39:07 +03:00
|
|
|
|
2023-06-17 01:38:42 +03:00
|
|
|
function _advanceTORNETHMarket() internal {
|
|
|
|
console2.log("\n ♻️ Trader is now going to move the price. ♻️ \n");
|
|
|
|
|
|
|
|
uint256 lastPriceAvg0 = uniTornPool.price0CumulativeLast();
|
|
|
|
uint256 lastPriceAvg1 = uniTornPool.price0CumulativeLast();
|
|
|
|
|
|
|
|
uint256 rn = now;
|
|
|
|
address trader = address(bytes20(keccak256("trader")));
|
|
|
|
|
|
|
|
vm.deal(trader, 20 ether);
|
|
|
|
vm.prank(trader);
|
|
|
|
IWethDepositable(address(WETH)).deposit{ value: 19 ether }();
|
|
|
|
|
|
|
|
require(WETH.balanceOf(trader) == 19 ether, "deposit for weth");
|
|
|
|
|
|
|
|
vm.warp(rn + 2 days + 1 hours);
|
|
|
|
|
|
|
|
vm.prank(trader);
|
|
|
|
WETH.transfer(address(uniTornPool), 19 ether);
|
|
|
|
|
|
|
|
uniTornPool.swap(5_600_000_000_000_000_000_000, 0, trader, new bytes(0));
|
|
|
|
|
|
|
|
require(lastPriceAvg0 != uniTornPool.price0CumulativeLast(), "twap moving 0 fail");
|
|
|
|
require(lastPriceAvg1 != uniTornPool.price1CumulativeLast(), "twap moving 1 fail");
|
|
|
|
}
|
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
function delimit() internal view {
|
|
|
|
console2.log();
|
|
|
|
}
|
2023-06-10 20:39:07 +03:00
|
|
|
|
2023-06-16 04:12:39 +03:00
|
|
|
function strcomp(string memory left, string memory right) internal pure returns (bool) {
|
|
|
|
return keccak256(abi.encode(left)) == keccak256(abi.encode(right));
|
|
|
|
}
|
|
|
|
|
|
|
|
function feeArrayForTesting_1() internal pure returns (uint256[] memory fees) {
|
|
|
|
fees = new uint256[](3);
|
|
|
|
fees[0] = 30;
|
|
|
|
fees[1] = 30;
|
|
|
|
fees[2] = 30;
|
2023-06-10 20:39:07 +03:00
|
|
|
}
|
2023-06-10 03:14:20 +03:00
|
|
|
}
|