From 307cc33d8c0a0ed9b87346f81c1c1a7fd24354b1 Mon Sep 17 00:00:00 2001 From: AlienTornadosaurusHex <> Date: Tue, 20 Jun 2023 13:14:26 +0000 Subject: [PATCH] router will call staking reward addition Signed-off-by: AlienTornadosaurusHex <> --- coverage/index.html | 2 +- gas/all.md | 127 ++++++++++++++++++++++++++++++++++ src/v2/RelayerRegistry.sol | 41 +++++------ src/v2/TornadoRouter.sol | 35 +++++++++- storage/v2.RelayerRegistry.md | 29 ++++---- 5 files changed, 191 insertions(+), 43 deletions(-) create mode 100644 gas/all.md diff --git a/coverage/index.html b/coverage/index.html index b53761c..7a73d99 100644 --- a/coverage/index.html +++ b/coverage/index.html @@ -37,7 +37,7 @@ Date: - 2023-06-19 06:07:36 + 2023-06-19 03:07:36 Functions: 68 diff --git a/gas/all.md b/gas/all.md new file mode 100644 index 0000000..e447981 --- /dev/null +++ b/gas/all.md @@ -0,0 +1,127 @@ +| src/proposals/CRVUSDInstancesProposal.sol:CRVUSDInstancesProposal contract | | | | | | +| -------------------------------------------------------------------------- | --------------- | ------- | ------- | ------- | ------- | +| Deployment Cost | Deployment Size | | | | | +| 1061627 | 5622 | | | | | +| Function Name | min | avg | median | max | # calls | +| executeProposal | 1388555 | 1388555 | 1388555 | 1388555 | 2 | + + +| src/proposals/InfrastructureUpgradeProposal.sol:InfrastructureUpgradeProposal contract | | | | | | +| -------------------------------------------------------------------------------------- | --------------- | ------- | ------- | ------- | ------- | +| Deployment Cost | Deployment Size | | | | | +| 1324091 | 7219 | | | | | +| Function Name | min | avg | median | max | # calls | +| executeProposal | 2763651 | 2763651 | 2763651 | 2763651 | 4 | + + +| src/v2/CurveFeeOracle.sol:CurveFeeOracle contract | | | | | | +| ------------------------------------------------- | --------------- | ----- | ------ | ------ | ------- | +| Deployment Cost | Deployment Size | | | | | +| 1206432 | 6125 | | | | | +| Function Name | min | avg | median | max | # calls | +| getChainedOracleHashForInstance | 1332 | 1332 | 1332 | 1332 | 1 | +| getChainedOracleNameForInstance | 2308 | 2308 | 2308 | 2308 | 1 | +| getChainedOracleNameForOracleHash | 1324 | 1324 | 1324 | 1324 | 1 | +| getFee | 1978 | 11498 | 15567 | 24067 | 26 | +| modifyChainedOracleForInstance | 74546 | 95310 | 83150 | 133973 | 12 | +| setTornOracleIsUniswap | 1122 | 2394 | 1122 | 6212 | 4 | +| setUniswapFeeOracle | 1841 | 8918 | 3841 | 21741 | 9 | +| update | 1914 | 1914 | 1914 | 1914 | 32 | + + +| src/v2/FeeOracleManager.sol:FeeOracleManager contract | | | | | | +| ----------------------------------------------------- | --------------- | ------ | ------ | ------ | ------- | +| Deployment Cost | Deployment Size | | | | | +| 1593993 | 8295 | | | | | +| Function Name | min | avg | median | max | # calls | +| feeUpdaterAddress | 535 | 535 | 535 | 535 | 2 | +| getAllFeeDeviations | 236346 | 236346 | 236346 | 236346 | 1 | +| getFeeDeviationsForInstances | 13169 | 13169 | 13169 | 13169 | 1 | +| getFeePercentForInstance | 1127 | 1127 | 1127 | 1127 | 1 | +| getFeeUpdateIntervalForInstance | 1083 | 1083 | 1083 | 1083 | 1 | +| getLastFeeForInstance | 1103 | 1103 | 1103 | 1103 | 15 | +| getLastUpdatedTimeForInstance | 599 | 599 | 599 | 599 | 3 | +| getUpdatedFeeForInstance | 12274 | 12274 | 12274 | 12274 | 1 | +| initialize | 2721 | 594230 | 889874 | 889874 | 6 | +| instanceFeeOracles | 852 | 852 | 852 | 852 | 1 | +| populateInstanceWithFeeData | 6050 | 6050 | 6050 | 6050 | 2 | +| setFeeOracle | 892 | 49144 | 59580 | 59580 | 13 | +| setFeePercentForInstance | 952 | 2537 | 2651 | 2651 | 15 | +| setFeeUpdateIntervalForInstance | 543 | 1765 | 1867 | 1867 | 13 | +| setFeeUpdater | 1937 | 1937 | 1937 | 1937 | 12 | +| setInstanceRegistry | 879 | 1503 | 1503 | 2127 | 2 | +| updateAllFees | 272841 | 347294 | 345960 | 424415 | 4 | +| updateFee | 645 | 14534 | 10854 | 71231 | 30 | +| updateFees | 65263 | 85553 | 85553 | 105843 | 2 | +| version | 694 | 694 | 694 | 694 | 1 | + + +| src/v2/InstanceRegistry.sol:InstanceRegistry contract | | | | | | +| --------------------------------------------------------------- | --------------- | ------ | ------- | ------- | ------- | +| Deployment Cost | Deployment Size | | | | | +| 1340269 | 6888 | | | | | +| Function Name | min | avg | median | max | # calls | +| addInstance | 44222 | 81368 | 84823 | 89823 | 12 | +| getAllInstanceStates | 29231 | 29231 | 29231 | 29231 | 1 | +| getAllInstances | 10872 | 12044 | 10872 | 13804 | 5 | +| getInstanceByENSName | 27929 | 27929 | 27929 | 27929 | 4 | +| getInstanceIndex | 645 | 645 | 645 | 645 | 1 | +| getInstanceState(address)((address,uint80,bool,bool)) | 1513 | 1513 | 1513 | 1513 | 137 | +| getInstanceState(uint256)((address,uint80,bool,bool)) | 1379 | 1379 | 1379 | 1379 | 2 | +| getInstanceState(uint256,uint256)((address,uint80,bool,bool)[]) | 6013 | 6013 | 6013 | 6013 | 1 | +| getInstanceToken | 773 | 773 | 773 | 773 | 2 | +| initialize | 1618 | 946913 | 1419451 | 1419451 | 6 | +| instanceData | 1170 | 1170 | 1170 | 1170 | 6 | +| isEnabledInstance | 945 | 945 | 945 | 945 | 1 | +| isRegisteredInstance | 611 | 611 | 611 | 611 | 1 | +| removeInstanceByAddress | 10144 | 10144 | 10144 | 10144 | 1 | +| removeInstanceByIndex | 3459 | 3459 | 3459 | 3459 | 1 | +| router | 854 | 854 | 854 | 854 | 1 | +| setTornadoRouter | 1491 | 1491 | 1491 | 1491 | 1 | +| version | 738 | 738 | 738 | 738 | 1 | + + +| src/v2/RelayerRegistry.sol:RelayerRegistry contract | | | | | | +| --------------------------------------------------- | --------------- | ----- | ------ | ----- | ------- | +| Deployment Cost | Deployment Size | | | | | +| 1566320 | 8132 | | | | | +| Function Name | min | avg | median | max | # calls | +| initialize | 68059 | 68059 | 68059 | 68059 | 4 | + + +| src/v2/TornadoRouter.sol:TornadoRouter contract | | | | | | +| ----------------------------------------------- | --------------- | ------ | ------ | ------ | ------- | +| Deployment Cost | Deployment Size | | | | | +| 1258189 | 6483 | | | | | +| Function Name | min | avg | median | max | # calls | +| approveTokenForInstance | 5065 | 29024 | 28086 | 33669 | 64 | +| deposit | 831816 | 831816 | 831816 | 831816 | 1 | +| initialize | 919 | 45923 | 68316 | 68316 | 6 | +| version | 670 | 670 | 670 | 670 | 1 | + + +| src/v2/TornadoStakingRewards.sol:TornadoStakingRewards contract | | | | | | +| --------------------------------------------------------------- | --------------- | ---- | ------ | ---- | ------- | +| Deployment Cost | Deployment Size | | | | | +| 970722 | 5409 | | | | | +| Function Name | min | avg | median | max | # calls | +| updateRewardsOnLockedBalanceChange | 3663 | 3663 | 3663 | 3663 | 4 | + + +| src/v2/UniswapFeeOracle.sol:UniswapFeeOracle contract | | | | | | +| ----------------------------------------------------- | --------------- | ----- | ------ | ----- | ------- | +| Deployment Cost | Deployment Size | | | | | +| 1590565 | 8795 | | | | | +| Function Name | min | avg | median | max | # calls | +| getAverageTORNPerETH | 754 | 754 | 754 | 754 | 1 | +| getFee | 2000 | 10436 | 7537 | 20695 | 58 | +| getLastUpdatedTime | 544 | 544 | 544 | 544 | 1 | +| getTORNPerToken | 2248 | 3381 | 2248 | 8748 | 15 | +| getTWAPData | 745 | 745 | 745 | 745 | 1 | +| setFeeOracleManagerAddress | 439 | 1063 | 1063 | 1687 | 2 | +| setMinObservationCardinality | 713 | 14599 | 23825 | 23825 | 12 | +| setPoolFeeForToken | 741 | 11496 | 5795 | 36695 | 72 | +| update | 2243 | 4585 | 2326 | 49062 | 78 | + + + diff --git a/src/v2/RelayerRegistry.sol b/src/v2/RelayerRegistry.sol index e102010..a9d503d 100644 --- a/src/v2/RelayerRegistry.sol +++ b/src/v2/RelayerRegistry.sol @@ -78,11 +78,6 @@ contract RelayerRegistry is RegistryLegacyStorage, EnsResolver, Initializable { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NEW STORAGE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - /** - * @notice Basis points are 1/100th of a % - */ - uint256 public constant BIP_DIVISOR = 10_000; - /** * @notice The address of the Governance proxy. */ @@ -94,9 +89,9 @@ contract RelayerRegistry is RegistryLegacyStorage, EnsResolver, Initializable { TORN public immutable torn; /** - * @notice The Staking Rewards contract. + * @notice The Staking Rewards proxy which we need to forwards funds */ - TornadoStakingRewards public stakingRewards; + address public stakingRewardsProxyAddress; /** * @notice The address from which slashes may come from. @@ -114,15 +109,12 @@ contract RelayerRegistry is RegistryLegacyStorage, EnsResolver, Initializable { // Contract general event ENSUpdated(address ens); event RouterAddressUpdated(address routerAddress); - event StakingRewardsUpdated(address stakingRewards); event FeeOracleManagerUpdated(address feeOracleManagerAddress); + event StakingRewardsProxyUpdated(address stakingRewards); event MinimumStakingAmountOracleUpdated(bytes20 oracle, bool isContract); // Relayer metadata event RelayerRegistered(string ensName, bytes32 relayer, address relayerAddress, uint256 stakedAmount); - event RelayerSlashed( - address indexed relayer, address beneficiary, uint256 slashedAmount, uint256 stakerKickbackBips - ); // Relayer Stake event StakeAddedToRelayer(address relayer, uint256 amountStakeAdded); @@ -163,14 +155,14 @@ contract RelayerRegistry is RegistryLegacyStorage, EnsResolver, Initializable { return "v2-oracle-manager"; } - function initialize(address _routerAddress, address _stakingRewardsAddress, bytes20 _minStakeAmountOracle) - public - virtual - initializer - { + function initialize( + address _routerAddress, + address _stakingRewardsProxyAddress, + bytes20 _minStakeAmountOracle + ) public virtual initializer { routerAddress = _routerAddress; - stakingRewards = TornadoStakingRewards(_stakingRewardsAddress); minStakeAmountOracle = _minStakeAmountOracle; + stakingRewardsProxyAddress = _stakingRewardsProxyAddress; } function register(string calldata _name, uint256 _staked, address[] calldata _workers) public virtual { @@ -209,7 +201,7 @@ contract RelayerRegistry is RegistryLegacyStorage, EnsResolver, Initializable { require(getMinimumStakingAmount() <= _staked, "RelayerRegistry: stake too low"); // Then transfer it here - IERC20(torn).safeTransferFrom(_relayer, address(stakingRewards), _staked); + IERC20(torn).safeTransferFrom(_relayer, address(stakingRewardsProxyAddress), _staked); // Then store metadata ("register") metadata[_relayer] = RelayerMetadata({ balance: _staked, node: _node }); @@ -271,7 +263,7 @@ contract RelayerRegistry is RegistryLegacyStorage, EnsResolver, Initializable { internal onlyRelayer(_relayer, _relayer) { - IERC20(torn).safeTransferFrom(_staker, address(stakingRewards), _staked); + IERC20(torn).safeTransferFrom(_staker, address(stakingRewardsProxyAddress), _staked); metadata[_relayer].balance = _staked.add(metadata[_relayer].balance); emit StakeAddedToRelayer(_relayer, _staked); } @@ -283,7 +275,6 @@ contract RelayerRegistry is RegistryLegacyStorage, EnsResolver, Initializable { onlyRelayer(_relayer, _sender) { metadata[_relayer].balance = metadata[_relayer].balance.sub(_burned); - stakingRewards.addBurnRewards(_burned); emit StakeBurned(_relayer, _burned); } @@ -294,9 +285,13 @@ contract RelayerRegistry is RegistryLegacyStorage, EnsResolver, Initializable { emit RouterAddressUpdated(_newRouterAddress); } - function setStakingRewards(address _newStakingRewardsAddress) public virtual onlyGovernance { - stakingRewards = TornadoStakingRewards(_newStakingRewardsAddress); - emit StakingRewardsUpdated(_newStakingRewardsAddress); + function setStakingRewardsProxyAddress(address _newStakingRewardsProxyAddress) + public + virtual + onlyGovernance + { + stakingRewardsProxyAddress = _newStakingRewardsProxyAddress; + emit StakingRewardsProxyUpdated(_newStakingRewardsProxyAddress); } function setMinimumStakingAmountOracle(bytes20 _newOracle, bool _isContractOracle) diff --git a/src/v2/TornadoRouter.sol b/src/v2/TornadoRouter.sol index ead4f8f..5a689b7 100644 --- a/src/v2/TornadoRouter.sol +++ b/src/v2/TornadoRouter.sol @@ -18,8 +18,9 @@ import { ITornadoInstance } from "tornado-anonymity-mining/contracts/interfaces/ // Local imports import { RelayerRegistry } from "./RelayerRegistry.sol"; -import { InstanceRegistry, InstanceState } from "./InstanceRegistry.sol"; import { FeeOracleManager } from "./FeeOracleManager.sol"; +import { TornadoStakingRewards } from "./TornadoStakingRewards.sol"; +import { InstanceRegistry, InstanceState } from "./InstanceRegistry.sol"; /** * @title TornadoRouter @@ -52,6 +53,11 @@ contract TornadoRouter is Initializable { */ FeeOracleManager public feeOracleManager; + /** + * @notice The Staking Rewards contract + */ + TornadoStakingRewards public stakingRewards; + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EVENTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ event EncryptedNote(address indexed sender, bytes encryptedNote); @@ -64,6 +70,7 @@ contract TornadoRouter is Initializable { event InstanceRegistryUpdated(address newInstanceRegistryProxyAddress); event RelayerRegistryUpdated(address newRelayerRegistryProxyAddress); event FeeOracleManagerUpdated(address newFeeOracleManagerProxyAddress); + event StakingRewardsUpdated(address newStakingRewardsProxyAddress); /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LOGIC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -124,7 +131,10 @@ contract TornadoRouter is Initializable { /** * @notice Withdraw from a Tornado Instance. The registry proxy will be set to 0, this will then * guarantee that the contract is not upgradeable and thus that it will never be able to block - * withdrawals. + * withdrawals via the `isWorker` function. In any case, both manual users, Governance relayers + * and non-Governance relayers may use this function to process a withdrawal. Only withdrawals + * which include a `_relayer` field in the proof which belongs to a registered relayer, but which + * attempt to withdraw via an unregistered worker are not allowed to withdraw. * @param _tornado The Tornado instance to withdraw from. * @param _proof Bytes proof data. * @param _root A current or historical bytes32 root of the Merkle Tree within the proofs context. @@ -147,12 +157,26 @@ contract TornadoRouter is Initializable { ) public payable virtual { // The registry proxy admin has been tossed meaning that below function can't be // upgraded to break withdrawals from the instances + // + // The next check confirms that `_relayer` is registered with Governance if (relayerRegistry.isWorker(_relayer)) { + // Check whether someone is impersonating a relayer or a relayer is avoiding require(relayerRegistry.isWorkerOfRelayer(_relayer, msg.sender), "TornadoRouter: invalid relayer"); + + // Check whether the instance is enabled require(instanceRegistry.isEnabledInstance(_tornado), "TornadoRouter: instance not enabled"); - relayerRegistry.deductBalance(msg.sender, _relayer, feeOracleManager.updateFee(_tornado, true)); + + // Get the fee for the instance + uint256 fee = feeOracleManager.updateFee(_tornado, true); + + // Deduct the relayers balance + relayerRegistry.deductBalance(msg.sender, _relayer, fee); + + // Add burn rewards + stakingRewards.addBurnRewards(fee); } + // In any case withdraw, again, can't break, above logic is based on an "immutable conditional" _tornado.withdraw{ value: msg.value }( _proof, _root, _nullifierHash, _recipient, _relayer, _fee, _refund ); @@ -207,4 +231,9 @@ contract TornadoRouter is Initializable { feeOracleManager = FeeOracleManager(_newFeeOracleManagerProxyAddress); emit FeeOracleManagerUpdated(_newFeeOracleManagerProxyAddress); } + + function setStakingRewards(address _newStakingRewardsProxyAddress) external onlyGovernance { + stakingRewards = TornadoStakingRewards(_newStakingRewardsProxyAddress); + emit StakingRewardsUpdated(_newStakingRewardsProxyAddress); + } } diff --git a/storage/v2.RelayerRegistry.md b/storage/v2.RelayerRegistry.md index 59c1fad..a4db3ff 100644 --- a/storage/v2.RelayerRegistry.md +++ b/storage/v2.RelayerRegistry.md @@ -1,16 +1,13 @@ -| Name | Type | Slot | Offset | Bytes | Contract | -|---------------------------|--------------------------------------------|------|--------|-------|--------------------------------------------| -| _deprecatedInitialized | bool | 0 | 0 | 1 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| _deprecatedInitializing | bool | 0 | 1 | 1 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| _deprecatedRouterAddress | address | 0 | 2 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| _deprecatedMinStakeAmount | uint256 | 1 | 0 | 32 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| metadata | mapping(address => struct RelayerMetadata) | 2 | 0 | 32 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| workers | mapping(address => address) | 3 | 0 | 32 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| _initialized | bool | 4 | 0 | 1 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| _initializing | bool | 4 | 1 | 1 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| ens | contract IENS | 4 | 2 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| feeOracleManager | contract FeeOracleManager | 5 | 0 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| stakingRewards | contract TornadoStakingRewards | 6 | 0 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| routerAddress | address | 7 | 0 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| minStakeAmountOracle | bytes20 | 8 | 0 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry | -| stakerKickbackBips | uint256 | 9 | 0 | 32 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| Name | Type | Slot | Offset | Bytes | Contract | +|----------------------------|--------------------------------------------|------|--------|-------|--------------------------------------------| +| _deprecatedInitialized | bool | 0 | 0 | 1 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| _deprecatedInitializing | bool | 0 | 1 | 1 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| _deprecatedRouterAddress | address | 0 | 2 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| _deprecatedMinStakeAmount | uint256 | 1 | 0 | 32 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| metadata | mapping(address => struct RelayerMetadata) | 2 | 0 | 32 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| workers | mapping(address => address) | 3 | 0 | 32 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| _initialized | bool | 4 | 0 | 1 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| _initializing | bool | 4 | 1 | 1 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| stakingRewardsProxyAddress | address | 4 | 2 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| routerAddress | address | 5 | 0 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry | +| minStakeAmountOracle | bytes20 | 6 | 0 | 20 | src/v2/RelayerRegistry.sol:RelayerRegistry |