gov v2 refactored
This commit is contained in:
parent
3b80de8117
commit
1bee8e29f6
|
@ -8,7 +8,8 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quotes": ["error", "double"],
|
"quotes": ["error", "double"],
|
||||||
"indent": ["error", 2]
|
"indent": ["error", 2],
|
||||||
|
"compiler-version": ["error", "^0.6.0"]
|
||||||
},
|
},
|
||||||
"plugins": ["prettier"]
|
"plugins": ["prettier"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"solidity.compileUsingRemoteVersion": "v0.6.12+commit.27d51765"
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
pragma solidity ^0.6.12;
|
pragma solidity ^0.6.12;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import { GovernanceVaultUpgrade } from "../vault/GovernanceVaultUpgrade.sol";
|
import { GovernanceVaultUpgrade } from "./GovernanceVaultUpgrade.sol";
|
||||||
import { GasCompensator } from "./GasCompensator.sol";
|
import { GasCompensator } from "./GasCompensator.sol";
|
||||||
import { Math } from "@openzeppelin/contracts/math/Math.sol";
|
import { Math } from "@openzeppelin/contracts/math/Math.sol";
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
pragma solidity ^0.6.12;
|
pragma solidity ^0.6.12;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import { Governance } from "../../v1/Governance.sol";
|
import { Governance } from "../v1/Governance.sol";
|
||||||
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
|
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
|
||||||
import { ITornadoVault } from "../interfaces/ITornadoVault.sol";
|
import { ITornadoVault } from "./interfaces/ITornadoVault.sol";
|
||||||
|
|
||||||
/// @title Version 2 Governance contract of the tornado.cash governance
|
/// @title Version 2 Governance contract of the tornado.cash governance
|
||||||
contract GovernanceVaultUpgrade is Governance {
|
contract GovernanceVaultUpgrade is Governance {
|
|
@ -1,39 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
interface IGovernanceMultisigAddress {
|
|
||||||
function returnMultisigAddress() external pure returns (address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice Contract which hold governance information. Useful for avoiding code duplication.
|
|
||||||
* */
|
|
||||||
contract ImmutableGovernanceInformation {
|
|
||||||
address internal constant GovernanceAddress = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce;
|
|
||||||
address internal constant TornTokenAddress = 0x77777FeDdddFfC19Ff86DB637967013e6C6A116C;
|
|
||||||
|
|
||||||
modifier onlyGovernance() {
|
|
||||||
require(msg.sender == GovernanceAddress, "only governance");
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev this modifier calls the pure governance returnMultisigAddress() function,
|
|
||||||
* if governance version is not -> vault-and-gas upgrade <= version
|
|
||||||
* then this will not work!
|
|
||||||
*/
|
|
||||||
modifier onlyMultisig() {
|
|
||||||
require(msg.sender == IGovernanceMultisigAddress(GovernanceAddress).returnMultisigAddress(), "only multisig");
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice Function to return a payable version of the governance address.
|
|
||||||
* @return payable version of the address
|
|
||||||
* */
|
|
||||||
function returnPayableGovernance() internal pure returns (address payable) {
|
|
||||||
return payable(GovernanceAddress);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
|
|
||||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
||||||
import { LoopbackProxy } from "tornado-governance/contracts/LoopbackProxy.sol";
|
|
||||||
|
|
||||||
import { TornadoVault } from "./vault/TornadoVault.sol";
|
|
||||||
import { TornadoAuctionHandler } from "./auction/TornadoAuctionHandler.sol";
|
|
||||||
import { GovernanceGasUpgrade } from "./gas/GovernanceGasUpgrade.sol";
|
|
||||||
|
|
||||||
import { IGovernanceVesting } from "./interfaces/IGovernanceVesting.sol";
|
|
||||||
import { ImmutableGovernanceInformation } from "./ImmutableGovernanceInformation.sol";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice This proposal should upgrade governance to the vault and gas version without breaking any logic.
|
|
||||||
* */
|
|
||||||
contract VaultAndGasProposal is ImmutableGovernanceInformation {
|
|
||||||
using SafeMath for uint256;
|
|
||||||
|
|
||||||
IGovernanceVesting public constant GovernanceVesting = IGovernanceVesting(0x179f48C78f57A3A78f0608cC9197B8972921d1D2);
|
|
||||||
address public immutable gasCompLogic;
|
|
||||||
/// @notice the new voting period we would like to include
|
|
||||||
uint256 public immutable votingPeriod;
|
|
||||||
|
|
||||||
event TornadoAuctionHandlerCreated(address indexed handler);
|
|
||||||
|
|
||||||
constructor(address _gasCompLogic, uint256 _votingPeriod) public {
|
|
||||||
gasCompLogic = _gasCompLogic;
|
|
||||||
votingPeriod = _votingPeriod;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @notice the entry point for the governance upgrade logic execution
|
|
||||||
/// @dev this function bundles all of the initialization logic for all of the contracts of the project
|
|
||||||
function executeProposal() external {
|
|
||||||
address vault = address(new TornadoVault());
|
|
||||||
|
|
||||||
LoopbackProxy(returnPayableGovernance()).upgradeTo(address(new GovernanceGasUpgrade(gasCompLogic, vault)));
|
|
||||||
|
|
||||||
GovernanceGasUpgrade newGovernance = GovernanceGasUpgrade(returnPayableGovernance());
|
|
||||||
IERC20 tornToken = IERC20(TornTokenAddress);
|
|
||||||
|
|
||||||
newGovernance.setVotingPeriod(votingPeriod);
|
|
||||||
|
|
||||||
/**
|
|
||||||
The below variable holds the total amount of TORN outflows from all of the proposal executions,
|
|
||||||
which will be used to calculate the proper amount of TORN for transfer to Governance.
|
|
||||||
For an explanation as to how this variable has been calculated with these fix values, please look at:
|
|
||||||
https://github.com/h-ivor/tornado-lottery-period/blob/production/scripts/balance_estimation.md
|
|
||||||
*/
|
|
||||||
uint256 totalOutflowsOfProposalExecutions = 120000000000000000000000 +
|
|
||||||
22916666666666666666666 +
|
|
||||||
54999999999999969408000 -
|
|
||||||
27e18;
|
|
||||||
|
|
||||||
require(
|
|
||||||
tornToken.transfer(
|
|
||||||
address(newGovernance.userVault()),
|
|
||||||
(tornToken.balanceOf(address(this))).sub(GovernanceVesting.released().sub(totalOutflowsOfProposalExecutions))
|
|
||||||
),
|
|
||||||
"TORN: transfer failed"
|
|
||||||
);
|
|
||||||
|
|
||||||
uint96 amountOfTornToAuctionOff = 787 ether;
|
|
||||||
uint96 minBuyAmount = 11 ether;
|
|
||||||
uint256 minBidInTorn = 10 ether;
|
|
||||||
uint256 fundingThreshold = 9 ether;
|
|
||||||
|
|
||||||
TornadoAuctionHandler auctionHandler = new TornadoAuctionHandler();
|
|
||||||
|
|
||||||
emit TornadoAuctionHandlerCreated(address(auctionHandler));
|
|
||||||
|
|
||||||
tornToken.transfer(address(auctionHandler), amountOfTornToAuctionOff);
|
|
||||||
|
|
||||||
/**
|
|
||||||
As with above, please see:
|
|
||||||
https://github.com/h-ivor/tornado-lottery-period/blob/production/contracts/auction/TornadoAuctionHandler.sol
|
|
||||||
*/
|
|
||||||
auctionHandler.initializeAuction(
|
|
||||||
block.timestamp + 5 days,
|
|
||||||
amountOfTornToAuctionOff,
|
|
||||||
minBuyAmount,
|
|
||||||
minBidInTorn,
|
|
||||||
fundingThreshold
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
# Auctioning some Tornado for compensations ETH
|
|
||||||
|
|
||||||
To boost voting activity, one of our ideas is to compensate gas used for voting on proposals.
|
|
||||||
Both for the castVote and castDelegatedVote functionality.
|
|
||||||
|
|
||||||
To make this as smooth as possible, we will compensate users directly in **ETH** (non-wrapped) for voting.
|
|
||||||
The priority fee is not compensated for, as to make exploiting the compensations unnecessary and unprofitable.
|
|
||||||
|
|
||||||
In order to receive ETH, TORN will be auctioned off by the governance contract with the help of a auction helper
|
|
||||||
(see contracts/auction/TornadoAuctionHandler.sol).
|
|
||||||
|
|
||||||
This contract has two functionalities:
|
|
||||||
|
|
||||||
- Initiate an auction.
|
|
||||||
|
|
||||||
- Convert all WETH it holds into ETH and send to Governance (callable by anyone).
|
|
||||||
|
|
||||||
This way, Governance does not need to handle WETH swap logic (would require extra logic) and ETH will be directly sent to the governance contract.
|
|
||||||
|
|
||||||
The initializeAuction function takes a couple of parameters:
|
|
||||||
|
|
||||||
```
|
|
||||||
function initializeAuction(
|
|
||||||
uint256 _auctionEndDate,
|
|
||||||
uint96 _auctionedSellAmount,
|
|
||||||
uint96 _minBuyAmount,
|
|
||||||
uint256 _minBidPerOrder,
|
|
||||||
uint256 _minFundingThreshold
|
|
||||||
) external onlyGovernance {
|
|
||||||
```
|
|
||||||
|
|
||||||
- \_auctionEndDate -> the auction end date expressed in UNIX format.
|
|
||||||
- \_auctionedSellAmount -> the amount of TORN to be sold in the auction.
|
|
||||||
- \_minBuyAmount -> this variable helps to define the minimum price via the following formula: \_auctionedSellAmount/\_minBuyAmount, in other words the minimum amount of TORN per ETH.
|
|
||||||
- \_minBidPerOrder -> minimum buy amount per a single order (of tokens being auctioned), is also used to prevent users from buying too low amounts and hurting themselves.
|
|
||||||
- \_minFundingThreshold -> minimum amount of buy tokens (ETH) for the ENTIRE auction. If this is not reached, the auction reverts and all tokens are sent back to their original owners.
|
|
||||||
|
|
||||||
This function does not take all the parameters for initializing the auction, the entire function may be seen below, some were left out of convenience:
|
|
||||||
|
|
||||||
```
|
|
||||||
IEasyAuction(EasyAuctionAddress).initiateAuction(
|
|
||||||
IERC20(TornTokenAddress),
|
|
||||||
IERC20(WETHAddress),
|
|
||||||
0, // orderCancellationEndDate
|
|
||||||
_auctionEndDate,
|
|
||||||
_auctionedSellAmount,
|
|
||||||
_minBuyAmount,
|
|
||||||
_minBidPerOrder,
|
|
||||||
_minFundingThreshold,
|
|
||||||
true, // isAtomicClosureAllowed
|
|
||||||
address(0x0000000000000000000000000000000000000000), // access
|
|
||||||
new bytes(0) // access
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
- Addresses of the tokens being bought/sold (ETH/TORN).
|
|
||||||
- orderCancellationEndDate -> date until order can be cancelled. For us, this is 0, meaning orders can't be cancelled once set.
|
|
||||||
- isAtomicClosureAllowed -> when auction end date is reached, a participant may set a last order in exchange for closing the auction, meaning it incentivizes the user to end the auction (gas payments, time saving) by giving him a risk-free action at the end. For us, false, due to tests showing that dust collection might not work if this is used.
|
|
||||||
- Last two fields are for access management, we have no whitelist for the auction, thus redundant and set to 0 for us.
|
|
|
@ -1,58 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
|
|
||||||
import { IWETH } from "./interfaces/IWETH.sol";
|
|
||||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
||||||
import { EtherSend } from "../libraries/EtherSend.sol";
|
|
||||||
import { IEasyAuction } from "./interfaces/IEasyAuction.sol";
|
|
||||||
import { ImmutableGovernanceInformation } from "../ImmutableGovernanceInformation.sol";
|
|
||||||
|
|
||||||
/// @notice Handler which should help governance start an auction and transfer results of an auction to governance.
|
|
||||||
/// @dev The reasoning behind this contract is to not bloat governance with unnecessary logic.
|
|
||||||
contract TornadoAuctionHandler is ImmutableGovernanceInformation {
|
|
||||||
using EtherSend for address;
|
|
||||||
|
|
||||||
address public constant EasyAuctionAddress = 0x0b7fFc1f4AD541A4Ed16b40D8c37f0929158D101;
|
|
||||||
address public constant WETHAddress = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
|
||||||
|
|
||||||
/// @notice main auction initialization function, please see: https://github.com/h-ivor/tornado-lottery-period/blob/only-vault-and-gas/contracts/auction/Auction.md
|
|
||||||
/// @dev calls easy auction deployed on eth mainnet
|
|
||||||
function initializeAuction(
|
|
||||||
uint256 _auctionEndDate,
|
|
||||||
uint96 _auctionedSellAmount,
|
|
||||||
uint96 _minBuyAmount,
|
|
||||||
uint256 _minBidPerOrder,
|
|
||||||
uint256 _minFundingThreshold
|
|
||||||
) external onlyGovernance {
|
|
||||||
require(IERC20(TornTokenAddress).balanceOf(address(this)) >= _auctionedSellAmount, "torn balance not enough");
|
|
||||||
IERC20(TornTokenAddress).approve(EasyAuctionAddress, _auctionedSellAmount);
|
|
||||||
|
|
||||||
IEasyAuction(EasyAuctionAddress).initiateAuction(
|
|
||||||
IERC20(TornTokenAddress),
|
|
||||||
IERC20(WETHAddress),
|
|
||||||
0,
|
|
||||||
_auctionEndDate,
|
|
||||||
_auctionedSellAmount,
|
|
||||||
_minBuyAmount,
|
|
||||||
_minBidPerOrder,
|
|
||||||
_minFundingThreshold,
|
|
||||||
false,
|
|
||||||
address(0x0000000000000000000000000000000000000000),
|
|
||||||
new bytes(0)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @notice function to transfer all eth and TORN dust to governance
|
|
||||||
function convertAndTransferToGovernance() external {
|
|
||||||
IWETH(WETHAddress).withdraw(IWETH(WETHAddress).balanceOf(address(this)));
|
|
||||||
if (address(this).balance > 0) require(GovernanceAddress.sendEther(address(this).balance), "pay fail");
|
|
||||||
if (IERC20(TornTokenAddress).balanceOf(address(this)) > 0)
|
|
||||||
IERC20(TornTokenAddress).transfer(GovernanceAddress, IERC20(TornTokenAddress).balanceOf(address(this)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @notice receive eth that should only allow mainnet WETH to send eth
|
|
||||||
receive() external payable {
|
|
||||||
require(msg.sender == WETHAddress, "only weth");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
|
|
||||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
||||||
|
|
||||||
interface IEasyAuction {
|
|
||||||
function initiateAuction(
|
|
||||||
IERC20 _auctioningToken,
|
|
||||||
IERC20 _biddingToken,
|
|
||||||
uint256 orderCancellationEndDate,
|
|
||||||
uint256 auctionEndDate,
|
|
||||||
uint96 _auctionedSellAmount,
|
|
||||||
uint96 _minBuyAmount,
|
|
||||||
uint256 minimumBiddingAmountPerOrder,
|
|
||||||
uint256 minFundingThreshold,
|
|
||||||
bool isAtomicClosureAllowed,
|
|
||||||
address accessManagerContract,
|
|
||||||
bytes memory accessManagerContractData
|
|
||||||
) external returns (uint256);
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
|
|
||||||
interface IPayableGovernance {
|
|
||||||
function receiveEther() external payable returns (bool);
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
|
|
||||||
interface IWETH {
|
|
||||||
function balanceOf(address account) external view returns (uint256);
|
|
||||||
|
|
||||||
function deposit() external payable;
|
|
||||||
|
|
||||||
function withdraw(uint256 wad) external;
|
|
||||||
|
|
||||||
function totalSupply() external view returns (uint256);
|
|
||||||
|
|
||||||
function approve(address guy, uint256 wad) external returns (bool);
|
|
||||||
|
|
||||||
function transfer(address dst, uint256 wad) external returns (bool);
|
|
||||||
|
|
||||||
function transferFrom(
|
|
||||||
address src,
|
|
||||||
address dst,
|
|
||||||
uint256 wad
|
|
||||||
) external returns (bool);
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.8.7;
|
|
||||||
|
|
||||||
import { EtherSend } from "../libraries/EtherSend.sol";
|
|
||||||
|
|
||||||
interface IPayableGovernance {
|
|
||||||
function receiveEther() external payable returns (bool);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice this contract should store ether for gas compensations and also retrieve the basefee
|
|
||||||
* */
|
|
||||||
contract GasCompensationVault {
|
|
||||||
using EtherSend for address;
|
|
||||||
|
|
||||||
address private constant GovernanceAddress = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce;
|
|
||||||
|
|
||||||
modifier onlyGovernance() {
|
|
||||||
require(msg.sender == GovernanceAddress, "only gov");
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice function to compensate gas by sending amount eth to a recipient
|
|
||||||
* @param recipient address to receive amount eth
|
|
||||||
* @param gasAmount the amount of gas to be compensated
|
|
||||||
* */
|
|
||||||
function compensateGas(address recipient, uint256 gasAmount) external onlyGovernance {
|
|
||||||
uint256 vaultBalance = address(this).balance;
|
|
||||||
uint256 toCompensate = gasAmount * block.basefee;
|
|
||||||
if (vaultBalance == 0) return;
|
|
||||||
payable(recipient).send((toCompensate > vaultBalance) ? vaultBalance : toCompensate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice function to withdraw compensate eth back to governance
|
|
||||||
* @param amount the amount of eth to withdraw back to governance
|
|
||||||
* */
|
|
||||||
function withdrawToGovernance(uint256 amount) external onlyGovernance {
|
|
||||||
uint256 vaultBalance = address(this).balance;
|
|
||||||
require(GovernanceAddress.sendEther((amount > vaultBalance) ? vaultBalance : amount), "pay fail");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice receive ether function, does nothing but receive ether
|
|
||||||
* */
|
|
||||||
receive() external payable {}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
interface IGovernanceVesting {
|
|
||||||
function released() external view returns (uint256);
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12 || ^0.8.7;
|
|
||||||
|
|
||||||
/// @notice very short library which implements a method to transfer ether via <address>.call
|
|
||||||
library EtherSend {
|
|
||||||
/**
|
|
||||||
* @notice function to transfer ether via filling the value field of a call
|
|
||||||
* @dev DICLAIMER: you must handle the possibility of reentrancy when using this function!!!
|
|
||||||
* @param to address to be transferred to
|
|
||||||
* @param amount amount to be transferred
|
|
||||||
* @return success true if transfer successful
|
|
||||||
* */
|
|
||||||
function sendEther(address to, uint256 amount) internal returns (bool success) {
|
|
||||||
(success, ) = payable(to).call{ value: amount }("");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.8.7;
|
|
||||||
|
|
||||||
contract GasCompensationVault {
|
|
||||||
address private constant GovernanceAddress = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce;
|
|
||||||
|
|
||||||
modifier onlyGovernance() {
|
|
||||||
require(msg.sender == GovernanceAddress, "only gov");
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
function compensateGas(address recipient, uint256 amount) external onlyGovernance {
|
|
||||||
if (address(this).balance == 0) return;
|
|
||||||
require(
|
|
||||||
(amount > address(this).balance) ? payable(recipient).send(address(this).balance) : payable(recipient).send(amount),
|
|
||||||
"compensation failed"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
receive() external payable {}
|
|
||||||
|
|
||||||
function getBasefee() external view returns (uint256) {
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
|
|
||||||
import "tornado-governance/contracts/Governance.sol";
|
|
||||||
|
|
||||||
contract MockProposal1 {
|
|
||||||
address public constant GovernanceAddress = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce;
|
|
||||||
|
|
||||||
function executeProposal() external {
|
|
||||||
Governance gov = Governance(GovernanceAddress);
|
|
||||||
|
|
||||||
gov.setVotingPeriod(27000);
|
|
||||||
require(gov.VOTING_PERIOD() == 27000, "Voting period change failed!");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
import { IterableOrderedOrderSet } from "@gnosis.pm/ido-contracts/contracts/libraries/IterableOrderedOrderSet.sol";
|
|
||||||
|
|
||||||
contract OrderEncoderHelper {
|
|
||||||
function encodeOrder(
|
|
||||||
uint64 userId,
|
|
||||||
uint96 buyAmount,
|
|
||||||
uint96 sellAmount
|
|
||||||
) external pure returns (bytes32) {
|
|
||||||
return IterableOrderedOrderSet.encodeOrder(userId, buyAmount, sellAmount);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
pragma solidity ^0.6.12;
|
|
||||||
|
|
||||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
||||||
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
|
||||||
|
|
||||||
/// @title Vault which holds user funds
|
|
||||||
contract TornadoVault {
|
|
||||||
using SafeERC20 for IERC20;
|
|
||||||
|
|
||||||
address internal constant TornTokenAddress = 0x77777FeDdddFfC19Ff86DB637967013e6C6A116C;
|
|
||||||
address internal constant GovernanceAddress = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce;
|
|
||||||
|
|
||||||
/// @notice withdraws TORN from the contract
|
|
||||||
/// @param amount amount to withdraw
|
|
||||||
function withdrawTorn(address recipient, uint256 amount) external {
|
|
||||||
require(msg.sender == GovernanceAddress, "only gov");
|
|
||||||
IERC20(TornTokenAddress).safeTransfer(recipient, amount);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,24 +23,6 @@ module.exports = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
version: '0.8.7',
|
|
||||||
settings: {
|
|
||||||
optimizer: {
|
|
||||||
enabled: true,
|
|
||||||
runs: 1000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
version: '0.7.6',
|
|
||||||
settings: {
|
|
||||||
optimizer: {
|
|
||||||
enabled: true,
|
|
||||||
runs: 1000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
networks: {
|
networks: {
|
||||||
|
|
Loading…
Reference in New Issue