Redeploy staking as proxy & format all with new foundry settings

This commit is contained in:
Theo 2023-05-26 15:01:45 +03:00
parent dc1bf7e2a7
commit af38a8dcc9
30 changed files with 1256 additions and 1287 deletions

View File

@ -4,9 +4,11 @@
"prettier/prettier": [
"error",
{
"printWidth": 110
"printWidth": 110,
"bracketSpacing": true
}
],
"no-console": "off",
"quotes": ["error", "double"],
"indent": ["error", 2],
"compiler-version": ["error", "^0.6.0"]

View File

@ -6,3 +6,10 @@ libs = ["node_modules", "lib"]
chain_id = 1
optimizer = true
optimizer-runs = 10_000_000
[fmt]
line_length = 140
bracket_spacing = true
multiline_func_header = 'attributes_first'
number_underscore = 'thousands'

View File

@ -1,8 +1,8 @@
{
"name": "proposal-22-forge-tests",
"version": "1.0.0",
"repository": "https://git.tornado.ws/AlienTornadosaurusHex/proposal-22-forge-tests.git",
"author": "AlienTornadosaurusHex",
"repository": "https://git.tornado.ws/Theo/proposal-22-forge-tests.git",
"author": "Theo",
"license": "MIT",
"scripts": {
"test": "forge test -vvv --fork-url https://rpc.mevblocker.io --fork-block-number 17336117 --gas-report"

View File

@ -29,7 +29,7 @@ contract Configuration {
function _initializeConfiguration() internal {
EXECUTION_DELAY = 2 days;
EXECUTION_EXPIRATION = 3 days;
QUORUM_VOTES = 25000e18; // 0.25% of TORN
QUORUM_VOTES = 25_000e18; // 0.25% of TORN
PROPOSAL_THRESHOLD = 1000e18; // 0.01% of TORN
VOTING_DELAY = 75 seconds;
VOTING_PERIOD = 3 days;

View File

@ -29,26 +29,14 @@ abstract contract Delegation is Core {
emit Undelegated(msg.sender, previous);
}
function proposeByDelegate(
address from,
address target,
string memory description
) external returns (uint256) {
function proposeByDelegate(address from, address target, string memory description) external returns (uint256) {
require(delegatedTo[from] == msg.sender, "Governance: not authorized");
return _propose(from, target, description);
}
function _propose(
address proposer,
address target,
string memory description
) internal virtual returns (uint256);
function _propose(address proposer, address target, string memory description) internal virtual returns (uint256);
function castDelegatedVote(
address[] memory from,
uint256 proposalId,
bool support
) external virtual {
function castDelegatedVote(address[] memory from, uint256 proposalId, bool support) external virtual {
for (uint256 i = 0; i < from.length; i++) {
require(delegatedTo[from[i]] == msg.sender, "Governance: not authorized");
_castVote(from[i], proposalId, support);
@ -58,9 +46,5 @@ abstract contract Delegation is Core {
}
}
function _castVote(
address voter,
uint256 proposalId,
bool support
) internal virtual;
function _castVote(address voter, uint256 proposalId, bool support) internal virtual;
}

View File

@ -14,6 +14,7 @@ import "./Configuration.sol";
contract Governance is Initializable, Configuration, Delegation, EnsResolve {
using SafeMath for uint256;
/// @notice Possible states that a proposal may be in
enum ProposalState {
Pending,
Active,
@ -67,12 +68,7 @@ contract Governance is Initializable, Configuration, Delegation, EnsResolve {
/// @notice An event emitted when a new proposal is created
event ProposalCreated(
uint256 indexed id,
address indexed proposer,
address target,
uint256 startTime,
uint256 endTime,
string description
uint256 indexed id, address indexed proposer, address target, uint256 startTime, uint256 endTime, string description
);
/// @notice An event emitted when a vote has been cast on a proposal
@ -106,14 +102,7 @@ contract Governance is Initializable, Configuration, Delegation, EnsResolve {
_initializeConfiguration();
}
function lock(
address owner,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
function lock(address owner, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual {
torn.permit(owner, address(this), amount, deadline, v, r, s);
_transferTokens(owner, amount);
}
@ -139,11 +128,12 @@ contract Governance is Initializable, Configuration, Delegation, EnsResolve {
* @param description description of the proposal
* @return the new proposal id
*/
function _propose(
address proposer,
address target,
string memory description
) internal virtual override(Delegation) returns (uint256) {
function _propose(address proposer, address target, string memory description)
internal
virtual
override(Delegation)
returns (uint256)
{
uint256 votingPower = lockedBalance[proposer];
require(votingPower >= PROPOSAL_THRESHOLD, "Governance::propose: proposer votes below proposal threshold");
// target should be a contract
@ -204,11 +194,7 @@ contract Governance is Initializable, Configuration, Delegation, EnsResolve {
_castVote(msg.sender, proposalId, support);
}
function _castVote(
address voter,
uint256 proposalId,
bool support
) internal override(Delegation) {
function _castVote(address voter, uint256 proposalId, bool support) internal override(Delegation) {
require(state(proposalId) == ProposalState.Active, "Governance::_castVote: voting is closed");
Proposal storage proposal = proposals[proposalId];
Receipt storage receipt = proposal.receipts[voter];

View File

@ -11,6 +11,7 @@ interface IProxy {
contract NewImplementation is MockGovernance {
uint256 public newVariable;
event Overriden(uint256 x);
function execute(uint256 proposalId) public payable override {

View File

@ -11,11 +11,10 @@ struct Recipient2 {
}
contract TORNMock2 is TORNMock {
constructor(
address _governance,
uint256 _pausePeriod,
Recipient2[] memory vesting
) public TORNMock(solve(_governance), _pausePeriod, solve2(vesting)) {}
constructor(address _governance, uint256 _pausePeriod, Recipient2[] memory vesting)
public
TORNMock(solve(_governance), _pausePeriod, solve2(vesting))
{ }
function solve(address x) private returns (bytes32) {
return bytes32(uint256(x) << 96);

View File

@ -12,7 +12,8 @@ interface IGasCompensationVault {
/**
* @notice This abstract contract is used to add gas compensation functionality to a contract.
* */
*
*/
abstract contract GasCompensator {
using SafeMath for uint256;
@ -29,12 +30,9 @@ abstract contract GasCompensator {
* @param account address to be compensated
* @param eligible if the account is eligible for compensations or not
* @param extra extra amount in gas to be compensated, will be multiplied by basefee
* */
modifier gasCompensation(
address account,
bool eligible,
uint256 extra
) {
*
*/
modifier gasCompensation(address account, bool eligible, uint256 extra) {
if (eligible) {
uint256 startGas = gasleft();
_;
@ -48,11 +46,13 @@ abstract contract GasCompensator {
/**
* @notice inheritable unimplemented function to withdraw ether from the vault
* */
*
*/
function withdrawFromHelper(uint256 amount) external virtual;
/**
* @notice inheritable unimplemented function to deposit ether into the vault
* */
*
*/
function setGasCompensations(uint256 _gasCompensationsLimit) external virtual;
}

View File

@ -10,18 +10,16 @@ import { Math } from "@openzeppelin/contracts/math/Math.sol";
/**
* @notice This contract should upgrade governance to be able to compensate gas for certain actions.
* These actions are set to castVote, castDelegatedVote in this contract.
* */
*
*/
contract GovernanceGasUpgrade is GovernanceVaultUpgrade, GasCompensator {
/**
* @notice constructor
* @param _gasCompLogic gas compensation vault address
* @param _userVault tornado vault address
* */
constructor(address _gasCompLogic, address _userVault)
public
GovernanceVaultUpgrade(_userVault)
GasCompensator(_gasCompLogic)
{}
*
*/
constructor(address _gasCompLogic, address _userVault) public GovernanceVaultUpgrade(_userVault) GasCompensator(_gasCompLogic) { }
/// @notice check that msg.sender is multisig
modifier onlyMultisig() {
@ -31,14 +29,16 @@ contract GovernanceGasUpgrade is GovernanceVaultUpgrade, GasCompensator {
/**
* @notice receive ether function, does nothing but receive ether
* */
*
*/
receive() external payable { }
/**
* @notice function to add a certain amount of ether for gas compensations
* @dev send ether is used in the logic as we don't expect multisig to make a reentrancy attack on governance
* @param gasCompensationsLimit the amount of gas to be compensated
* */
*
*/
function setGasCompensations(uint256 gasCompensationsLimit) external virtual override onlyMultisig {
require(payable(address(gasCompensationVault)).send(Math.min(gasCompensationsLimit, address(this).balance)));
}
@ -47,7 +47,8 @@ contract GovernanceGasUpgrade is GovernanceVaultUpgrade, GasCompensator {
* @notice function to withdraw funds from the gas compensator
* @dev send ether is used in the logic as we don't expect multisig to make a reentrancy attack on governance
* @param amount the amount of ether to withdraw
* */
*
*/
function withdrawFromHelper(uint256 amount) external virtual override onlyMultisig {
gasCompensationVault.withdrawToGovernance(amount);
}
@ -56,13 +57,14 @@ contract GovernanceGasUpgrade is GovernanceVaultUpgrade, GasCompensator {
* @notice function to cast callers votes on a proposal
* @dev IMPORTANT: This function uses the gasCompensation modifier.
* as such this function can trigger a payable fallback.
It is not possible to vote without revert more than once,
without hasAccountVoted being true, eliminating gas refunds in this case.
Gas compensation is also using the low level send(), forwarding 23000 gas
as to disallow further logic execution above that threshold.
* It is not possible to vote without revert more than once,
* without hasAccountVoted being true, eliminating gas refunds in this case.
* Gas compensation is also using the low level send(), forwarding 23000 gas
* as to disallow further logic execution above that threshold.
* @param proposalId id of proposal account is voting on
* @param support true if yes false if no
* */
*
*/
function castVote(uint256 proposalId, bool support)
external
virtual
@ -81,12 +83,9 @@ contract GovernanceGasUpgrade is GovernanceVaultUpgrade, GasCompensator {
* @param from array of addresses that should have delegated to voter
* @param proposalId id of proposal account is voting on
* @param support true if yes false if no
* */
function castDelegatedVote(
address[] memory from,
uint256 proposalId,
bool support
) external virtual override {
*
*/
function castDelegatedVote(address[] memory from, uint256 proposalId, bool support) external virtual override {
require(from.length > 0, "Can not be empty");
_castDelegatedVote(from, proposalId, support, !hasAccountVoted(proposalId, msg.sender) && !checkIfQuorumReached(proposalId));
}
@ -101,7 +100,8 @@ contract GovernanceGasUpgrade is GovernanceVaultUpgrade, GasCompensator {
* @notice function to check if quorum has been reached on a given proposal
* @param proposalId id of proposal
* @return true if quorum has been reached
* */
*
*/
function checkIfQuorumReached(uint256 proposalId) public view returns (bool) {
return (proposals[proposalId].forVotes + proposals[proposalId].againstVotes >= QUORUM_VOTES);
}
@ -111,7 +111,8 @@ contract GovernanceGasUpgrade is GovernanceVaultUpgrade, GasCompensator {
* @param proposalId id of proposal account should have voted on
* @param account address of the account
* @return true if acc has voted
* */
*
*/
function hasAccountVoted(uint256 proposalId, address account) public view returns (bool) {
return proposals[proposalId].receipts[account].hasVoted;
}
@ -121,7 +122,8 @@ contract GovernanceGasUpgrade is GovernanceVaultUpgrade, GasCompensator {
* @dev reasoning: if multisig changes we need governance to approve the next multisig address,
* so simply inherit in a governance upgrade from this function and set the new address
* @return the multisig address
* */
*
*/
function returnMultisigAddress() public pure virtual returns (address) {
return 0xb04E030140b30C27bcdfaafFFA98C57d80eDa7B4;
}
@ -138,13 +140,12 @@ contract GovernanceGasUpgrade is GovernanceVaultUpgrade, GasCompensator {
* @param proposalId id of proposal account is voting on
* @param support true if yes false if no
* @param gasCompensated true if gas should be compensated (given all internal checks pass)
* */
function _castDelegatedVote(
address[] memory from,
uint256 proposalId,
bool support,
bool gasCompensated
) internal gasCompensation(msg.sender, gasCompensated, (msg.sender == tx.origin ? 21e3 : 0)) {
*
*/
function _castDelegatedVote(address[] memory from, uint256 proposalId, bool support, bool gasCompensated)
internal
gasCompensation(msg.sender, gasCompensated, (msg.sender == tx.origin ? 21e3 : 0))
{
for (uint256 i = 0; i < from.length; i++) {
address delegator = from[i];
require(delegatedTo[delegator] == msg.sender || delegator == msg.sender, "Governance: not authorized");

View File

@ -10,7 +10,7 @@ contract MockProposal {
function executeProposal() external {
Governance gov = Governance(GovernanceAddress);
gov.setVotingPeriod(27000);
require(gov.VOTING_PERIOD() == 27000, "Voting period change failed!");
gov.setVotingPeriod(27_000);
require(gov.VOTING_PERIOD() == 27_000, "Voting period change failed!");
}
}

View File

@ -18,11 +18,10 @@ contract GovernanceStakingUpgrade is GovernanceGasUpgrade {
event RewardUpdateSuccessful(address indexed account);
event RewardUpdateFailed(address indexed account, bytes indexed errorData);
constructor(
address stakingRewardsAddress,
address gasCompLogic,
address userVaultAddress
) public GovernanceGasUpgrade(gasCompLogic, userVaultAddress) {
constructor(address stakingRewardsAddress, address gasCompLogic, address userVaultAddress)
public
GovernanceGasUpgrade(gasCompLogic, userVaultAddress)
{
Staking = ITornadoStakingRewards(stakingRewardsAddress);
}
@ -30,7 +29,8 @@ contract GovernanceStakingUpgrade is GovernanceGasUpgrade {
* @notice This modifier should make a call to Staking to update the rewards for account without impacting logic on revert
* @dev try / catch block to handle reverts
* @param account Account to update rewards for.
* */
*
*/
modifier updateRewards(address account) {
try Staking.updateRewardsOnLockedBalanceChange(account, lockedBalance[account]) {
emit RewardUpdateSuccessful(account);
@ -40,14 +40,12 @@ contract GovernanceStakingUpgrade is GovernanceGasUpgrade {
_;
}
function lock(
address owner,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override updateRewards(owner) {
function lock(address owner, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
public
virtual
override
updateRewards(owner)
{
super.lock(owner, amount, deadline, v, r, s);
}

View File

@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
import "@openzeppelin/contracts/proxy/TransparentUpgradeableProxy.sol";
/**
* @dev TransparentUpgradeableProxy where admin is allowed to call implementation methods.
*/
contract AdminUpgradeableProxy is TransparentUpgradeableProxy {
/**
* @dev Initializes an upgradeable proxy backed by the implementation at `_logic`.
*/
constructor(address _logic, address _admin, bytes memory _data) public payable TransparentUpgradeableProxy(_logic, _admin, _data) { }
/**
* @dev Override to allow admin access the fallback function.
*/
function _beforeFallback() internal override { }
}

View File

@ -9,11 +9,10 @@ import "../v3-relayer-registry/GovernanceStakingUpgrade.sol";
contract GovernancePatchUpgrade is GovernanceStakingUpgrade {
mapping(uint256 => bytes32) public proposalCodehashes;
constructor(
address stakingRewardsAddress,
address gasCompLogic,
address userVaultAddress
) public GovernanceStakingUpgrade(stakingRewardsAddress, gasCompLogic, userVaultAddress) {}
constructor(address stakingRewardsAddress, address gasCompLogic, address userVaultAddress)
public
GovernanceStakingUpgrade(stakingRewardsAddress, gasCompLogic, userVaultAddress)
{ }
/// @notice Return the version of the contract
function version() external pure virtual override returns (string memory) {
@ -51,11 +50,12 @@ contract GovernancePatchUpgrade is GovernanceStakingUpgrade {
* @param description description of the proposal
* @return proposalId new proposal id
*/
function _propose(
address proposer,
address target,
string memory description
) internal virtual override(Governance) returns (uint256 proposalId) {
function _propose(address proposer, address target, string memory description)
internal
virtual
override(Governance)
returns (uint256 proposalId)
{
// Implies all former predicates were valid
proposalId = super._propose(proposer, target, description);

View File

@ -5,6 +5,7 @@ pragma experimental ABIEncoderV2;
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
import { LoopbackProxy } from "../v1/LoopbackProxy.sol";
import { AdminUpgradeableProxy } from "./AdminUpgradeableProxy.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
@ -12,10 +13,6 @@ import { GovernancePatchUpgrade } from "./GovernancePatchUpgrade.sol";
import { TornadoStakingRewards } from "./TornadoStakingRewards.sol";
import { RelayerRegistry } from "./RelayerRegistry.sol";
interface Proxy {
function upgradeTo(address newImplementation) external;
}
/**
* @notice Contract which should help the proposal deploy the necessary contracts.
*/
@ -27,11 +24,7 @@ contract PatchProposalContractsFactory {
* @param registry The address of the relayer registry.
* @return The address of the new staking contract.
*/
function createStakingRewards(
address governance,
address torn,
address registry
) external returns (address) {
function createStakingRewards(address governance, address torn, address registry) external returns (address) {
return address(new TornadoStakingRewards(governance, torn, registry));
}
@ -43,13 +36,10 @@ contract PatchProposalContractsFactory {
* @param staking The TornadoStakingRewards contract address.
* @return The address of the new registry contract.
*/
function createRegistryContract(
address torn,
address governance,
address ens,
address staking,
address feeManager
) external returns (address) {
function createRegistryContract(address torn, address governance, address ens, address staking, address feeManager)
external
returns (address)
{
return address(new RelayerRegistry(torn, governance, ens, staking, feeManager));
}
}
@ -61,8 +51,8 @@ contract PatchProposal {
using SafeMath for uint256;
using Address for address;
address public constant feeManagerAddress = 0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7;
address public constant ensAddress = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e;
address public immutable feeManagerAddress = 0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7;
address public immutable ensAddress = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e;
address public immutable registry = 0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2;
IERC20 public constant TORN = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C);
@ -88,22 +78,21 @@ contract PatchProposal {
// Get the small amount of TORN left
oldStaking.withdrawTorn(TORN.balanceOf(address(oldStaking)));
// And create a new staking contract
TornadoStakingRewards newStaking = TornadoStakingRewards(
patchProposalContractsFactory.createStakingRewards(address(governance), address(TORN), registry)
);
// And create a new staking logic contract
TornadoStakingRewards newStakingImplementation =
TornadoStakingRewards(patchProposalContractsFactory.createStakingRewards(address(governance), address(TORN), registry));
// Create new staking proxy contract (without initialization value)
bytes memory empty;
AdminUpgradeableProxy newStaking = new AdminUpgradeableProxy(address(newStakingImplementation), address(governance), empty);
// And a new registry implementation
address newRegistryImplementationAddress = patchProposalContractsFactory.createRegistryContract(
address(TORN),
address(governance),
ensAddress,
address(newStaking),
feeManagerAddress
address(TORN), address(governance), ensAddress, address(newStaking), feeManagerAddress
);
// Upgrade the registry proxy
Proxy(registry).upgradeTo(newRegistryImplementationAddress);
AdminUpgradeableProxy(payable(registry)).upgradeTo(newRegistryImplementationAddress);
// Now upgrade the governance to the latest stuff
LoopbackProxy(payable(governance)).upgradeTo(address(new GovernancePatchUpgrade(address(newStaking), gasComp, vault)));

View File

@ -60,11 +60,7 @@ library ENSNamehash {
return len;
}
function keccak(
bytes memory data,
uint256 offset,
uint256 len
) private pure returns (bytes32 ret) {
function keccak(bytes memory data, uint256 offset, uint256 len) private pure returns (bytes32 ret) {
require(offset + len <= data.length);
assembly {
ret := keccak256(add(add(data, 32), offset), len)
@ -93,7 +89,8 @@ struct RelayerState {
* - if setter functions are compromised, relayer metadata would be at risk, including the noted amount of his balance
* - if burn function is compromised, relayers run the risk of being unable to handle withdrawals
* - the above risk also applies to the nullify balance function
* */
*
*/
contract RelayerRegistry is Initializable, EnsResolve {
using SafeMath for uint256;
using SafeERC20 for TORN;
@ -135,13 +132,7 @@ contract RelayerRegistry is Initializable, EnsResolve {
_;
}
constructor(
address _torn,
address _governance,
address _ens,
address _staking,
address _feeManager
) public {
constructor(address _torn, address _governance, address _ens, address _staking, address _feeManager) public {
torn = TORN(_torn);
governance = _governance;
ens = IENS(_ens);
@ -153,7 +144,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
* @notice initialize function for upgradeability
* @dev this contract will be deployed behind a proxy and should not assign values at logic address,
* params left out because self explainable
* */
*
*/
function initialize(bytes32 _tornadoRouter) external initializer {
tornadoRouter = resolve(_tornadoRouter);
}
@ -163,18 +155,16 @@ contract RelayerRegistry is Initializable, EnsResolve {
* @dev Relayer can't steal other relayers workers since they are registered, and a wallet (msg.sender check) can always unregister itself
* @param ensName ens name of the relayer
* @param stake the initial amount of stake in TORN the relayer is depositing
* */
function register(
string calldata ensName,
uint256 stake,
address[] calldata workersToRegister
) external {
*
*/
function register(string calldata ensName, uint256 stake, address[] calldata workersToRegister) external {
_register(msg.sender, ensName, stake, workersToRegister);
}
/**
* @dev Register function equivalent with permit-approval instead of regular approve.
* */
*
*/
function registerPermit(
string calldata ensName,
uint256 stake,
@ -189,12 +179,7 @@ contract RelayerRegistry is Initializable, EnsResolve {
_register(relayer, ensName, stake, workersToRegister);
}
function _register(
address relayer,
string calldata ensName,
uint256 stake,
address[] calldata workersToRegister
) internal {
function _register(address relayer, string calldata ensName, uint256 stake, address[] calldata workersToRegister) internal {
bytes32 ensHash = bytes(ensName).namehash();
require(relayer == ens.owner(ensHash), "only ens owner");
require(workers[relayer] == address(0), "cant register again");
@ -222,7 +207,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
* @notice This function should allow relayers to register more workeres
* @param relayer Relayer which should send message from any worker which is already registered
* @param worker Address to register
* */
*
*/
function registerWorker(address relayer, address worker) external onlyRelayer(msg.sender, relayer) {
_registerWorker(relayer, worker);
}
@ -239,7 +225,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
* - this should be followed by an action like burning relayer stake
* - there was an option of allowing the sender to burn relayer stake in case of malicious behaviour, this feature was not included in the end
* - reverts if trying to unregister master, otherwise contract would break. in general, there should be no reason to unregister master at all
* */
*
*/
function unregisterWorker(address worker) external {
if (worker != msg.sender) require(workers[worker] == msg.sender, "only owner of worker");
require(workers[worker] != worker, "cant unregister master");
@ -251,7 +238,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
* @notice This function should allow anybody to stake to a relayer more TORN
* @param relayer Relayer main address to stake to
* @param stake Stake to be added to relayer
* */
*
*/
function stakeToRelayer(address relayer, uint256 stake) external {
_stakeToRelayer(msg.sender, relayer, stake);
}
@ -259,25 +247,16 @@ contract RelayerRegistry is Initializable, EnsResolve {
/**
* @dev stakeToRelayer function equivalent with permit-approval instead of regular approve.
* @param staker address from that stake is paid
* */
function stakeToRelayerPermit(
address relayer,
uint256 stake,
address staker,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
*
*/
function stakeToRelayerPermit(address relayer, uint256 stake, address staker, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
external
{
torn.permit(staker, address(this), stake, deadline, v, r, s);
_stakeToRelayer(staker, relayer, stake);
}
function _stakeToRelayer(
address staker,
address relayer,
uint256 stake
) internal {
function _stakeToRelayer(address staker, address relayer, uint256 stake) internal {
require(workers[relayer] == relayer, "!registered");
torn.safeTransferFrom(staker, address(staking), stake);
relayers[relayer].balance = stake.add(relayers[relayer].balance);
@ -294,12 +273,9 @@ contract RelayerRegistry is Initializable, EnsResolve {
* @param sender worker to check sender == relayer
* @param relayer address of relayer who's stake is being burned
* @param pool instance to get fee for
* */
function burn(
address sender,
address relayer,
ITornadoInstance pool
) external onlyTornadoRouter {
*
*/
function burn(address sender, address relayer, ITornadoInstance pool) external onlyTornadoRouter {
address masterAddress = workers[sender];
if (masterAddress == address(0)) {
require(workers[relayer] == address(0), "Only custom relayer");
@ -316,7 +292,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
/**
* @notice This function should allow governance to set the minimum stake amount
* @param minAmount new minimum stake amount
* */
*
*/
function setMinStakeAmount(uint256 minAmount) external onlyGovernance {
minStakeAmount = minAmount;
emit MinimumStakeAmount(minAmount);
@ -325,7 +302,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
/**
* @notice This function should allow governance to set a new tornado proxy address
* @param tornadoRouterAddress address of the new proxy
* */
*
*/
function setTornadoRouter(address tornadoRouterAddress) external onlyGovernance {
tornadoRouter = tornadoRouterAddress;
emit RouterRegistered(tornadoRouterAddress);
@ -337,7 +315,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
* - Should nullify the balance
* - Adding nullified balance as rewards was refactored to allow for the flexibility of these funds (for gov to operate with them)
* @param relayer address of relayer who's balance is to nullify
* */
*
*/
function nullifyBalance(address relayer) external onlyGovernance {
address masterAddress = workers[relayer];
require(relayer == masterAddress, "must be master");
@ -349,7 +328,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
* @notice This function should check if a worker is associated with a relayer
* @param toResolve address to check
* @return true if is associated
* */
*
*/
function isRelayer(address toResolve) external view returns (bool) {
return workers[toResolve] != address(0);
}
@ -359,7 +339,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
* @param relayer relayer to check
* @param toResolve address to check
* @return true if registered
* */
*
*/
function isRelayerRegistered(address relayer, address toResolve) external view returns (bool) {
return workers[toResolve] == relayer;
}
@ -368,7 +349,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
* @notice This function should get a relayers ensHash
* @param relayer address to fetch for
* @return relayer's ensHash
* */
*
*/
function getRelayerEnsHash(address relayer) external view returns (bytes32) {
return relayers[workers[relayer]].ensHash;
}
@ -377,7 +359,8 @@ contract RelayerRegistry is Initializable, EnsResolve {
* @notice This function should get a relayers balance
* @param relayer relayer who's balance is to fetch
* @return relayer's balance
* */
*
*/
function getRelayerBalance(address relayer) external view returns (uint256) {
return relayers[workers[relayer]].balance;
}

View File

@ -25,7 +25,8 @@ interface ITornadoGovernance {
* and properly attribute rewards to addresses without security issues.
* @dev CONTRACT RISKS:
* - Relayer staked TORN at risk if contract is compromised.
* */
*
*/
contract TornadoStakingRewards is Initializable, EnsResolve {
using SafeMath for uint256;
using SafeERC20 for IERC20;
@ -52,11 +53,7 @@ contract TornadoStakingRewards is Initializable, EnsResolve {
}
// Minor code change here we won't resolve the registry by ENS
constructor(
address governanceAddress,
address tornAddress,
address _relayerRegistry
) public {
constructor(address governanceAddress, address tornAddress, address _relayerRegistry) public {
Governance = ITornadoGovernance(governanceAddress);
torn = IERC20(tornAddress);
relayerRegistry = _relayerRegistry;
@ -88,16 +85,16 @@ contract TornadoStakingRewards is Initializable, EnsResolve {
*/
function addBurnRewards(uint256 amount) external {
require(msg.sender == address(Governance) || msg.sender == relayerRegistry, "unauthorized");
accumulatedRewardPerTorn = accumulatedRewardPerTorn.add(
amount.mul(ratioConstant).div(torn.balanceOf(address(Governance.userVault())))
);
accumulatedRewardPerTorn =
accumulatedRewardPerTorn.add(amount.mul(ratioConstant).div(torn.balanceOf(address(Governance.userVault()))));
}
/**
* @notice This function should allow governance to properly update the accumulated rewards rate for an account
* @param account address of account to update data for
* @param amountLockedBeforehand the balance locked beforehand in the governance contract
* */
*
*/
function updateRewardsOnLockedBalanceChange(address account, uint256 amountLockedBeforehand) external onlyGovernance {
uint256 claimed = _updateReward(account, amountLockedBeforehand);
accumulatedRewards[account] = accumulatedRewards[account].add(claimed);
@ -105,7 +102,8 @@ contract TornadoStakingRewards is Initializable, EnsResolve {
/**
* @notice This function should allow governance rescue tokens from the staking rewards contract
* */
*
*/
function withdrawTorn(uint256 amount) external onlyGovernance {
if (amount == type(uint256).max) amount = torn.balanceOf(address(this));
torn.safeTransfer(address(Governance), amount);
@ -122,10 +120,10 @@ contract TornadoStakingRewards is Initializable, EnsResolve {
* @return claimed the rewards attributed to user since the last update
*/
function _updateReward(address account, uint256 amountLockedBeforehand) private returns (uint256 claimed) {
if (amountLockedBeforehand != 0)
claimed = (accumulatedRewardPerTorn.sub(accumulatedRewardRateOnLastUpdate[account])).mul(amountLockedBeforehand).div(
ratioConstant
);
if (amountLockedBeforehand != 0) {
claimed =
(accumulatedRewardPerTorn.sub(accumulatedRewardRateOnLastUpdate[account])).mul(amountLockedBeforehand).div(ratioConstant);
}
accumulatedRewardRateOnLastUpdate[account] = accumulatedRewardPerTorn;
emit RewardsUpdated(account, claimed);
}
@ -136,8 +134,9 @@ contract TornadoStakingRewards is Initializable, EnsResolve {
*/
function checkReward(address account) external view returns (uint256 rewards) {
uint256 amountLocked = Governance.lockedBalance(account);
if (amountLocked != 0)
if (amountLocked != 0) {
rewards = (accumulatedRewardPerTorn.sub(accumulatedRewardRateOnLastUpdate[account])).mul(amountLocked).div(ratioConstant);
}
rewards = rewards.add(accumulatedRewards[account]);
}
}