Redeploy staking as proxy & format all with new foundry settings
This commit is contained in:
parent
dc1bf7e2a7
commit
af38a8dcc9
@ -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"]
|
||||
|
@ -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'
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -11,6 +11,7 @@ interface IProxy {
|
||||
|
||||
contract NewImplementation is MockGovernance {
|
||||
uint256 public newVariable;
|
||||
|
||||
event Overriden(uint256 x);
|
||||
|
||||
function execute(uint256 proposalId) public payable override {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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!");
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
20
src/v4-patch/AdminUpgradeableProxy.sol
Normal file
20
src/v4-patch/AdminUpgradeableProxy.sol
Normal 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 { }
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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)));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user