Line data Source code
1 : // SPDX-License-Identifier: MIT 2 : 3 : pragma solidity ^0.6.12; 4 : pragma experimental ABIEncoderV2; 5 : 6 : import { IGovernance, Proposal, ProposalState } from "common/interfaces/IGovernance.sol"; 7 : 8 : import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 : 10 : import { Test } from "forge-std/Test.sol"; 11 : 12 : import { TornadoAddresses } from "common/TornadoAddresses.sol"; 13 : 14 : contract TornadoProposalTest is Test, TornadoAddresses { 15 : // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PERMIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 16 : 17 : bytes32 public constant PERMIT_TYPEHASH = 18 : keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); 19 : 20 : bytes32 public constant EIP712_DOMAIN = keccak256( 21 : abi.encode( 22 : keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), 23 : keccak256(bytes("TornadoCash")), 24 : keccak256(bytes("1")), 25 : 1, 26 : VERIFIER_ADDRESS 27 : ) 28 : ); 29 : 30 : uint16 public constant PERMIT_FUNC_SELECTOR = uint16(0x1901); 31 : 32 : // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TEST DUMMIES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 : 34 : address public constant TEST_REAL_ADDRESS_WITH_BALANCE = 0x9Ff3C1Bea9ffB56a78824FE29f457F066257DD58; 35 : 36 : address public constant TEST_RELAYER_ADDRESS = 0x30F96AEF199B399B722F8819c9b0723016CEAe6C; // moon-relayer.eth 37 : // (just for testing) 38 : 39 : uint256 public constant TEST_PRIVATE_KEY_ONE = 40 : 0x66ddbd7cbe4a566df405f6ded0b908c669f88cdb1656380c050e3a457bd21df0; 41 : uint256 public constant TEST_PRIVATE_KEY_TWO = 42 : 0xa4c8c98120e77741a87a116074a2df4ddb20d1149069290fd4a3d7ee65c55064; 43 : 44 : address public constant TEST_ADDRESS_ONE = 0x118251976c65AFAf291f5255450ddb5b6A4d8B88; 45 : address public constant TEST_ADDRESS_TWO = 0x63aE7d90Eb37ca39FC62dD9991DbEfeE70673a20; 46 : 47 : // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ADDRESSES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 48 : 49 : address public constant VERIFIER_ADDRESS = 0x77777FeDdddFfC19Ff86DB637967013e6C6A116C; 50 : 51 : // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GOVERNANCE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52 : 53 : string public constant PROPOSAL_DESCRIPTION = "{title:'Some proposal',description:''}"; 54 : 55 : uint256 public EXECUTION_DELAY; 56 : uint256 public EXECUTION_EXPIRATION; 57 : uint256 public QUORUM_VOTES; 58 : uint256 public PROPOSAL_THRESHOLD; 59 : uint256 public VOTING_DELAY; 60 : uint256 public VOTING_PERIOD; 61 : uint256 public CLOSING_PERIOD; 62 : uint256 public VOTE_EXTEND_TIME; 63 : 64 : IGovernance public immutable governance = IGovernance(getGovernanceProxyAddress()); 65 : 66 : // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TEST UTILS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 : 68 : function setUp() public virtual { 69 0 : vm.createSelectFork(vm.envString("MAINNET_RPC_URL")); 70 0 : _fetchConfiguration(); 71 : } 72 : 73 : // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HELPERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 74 : 75 : function waitUntilExecutable(uint256 proposalId) internal { 76 0 : uint256 proposalExecutableTime = getProposalExecutableTime(proposalId); 77 0 : require(block.timestamp < proposalExecutableTime, "Too late to execute proposal"); 78 0 : vm.warp(proposalExecutableTime); 79 : } 80 : 81 : function easyPropose(address proposalAddress) public returns (uint256) { 82 0 : retrieveAndLockBalance(TEST_PRIVATE_KEY_ONE, TEST_ADDRESS_ONE, QUORUM_VOTES); 83 0 : retrieveAndLockBalance(TEST_PRIVATE_KEY_TWO, TEST_ADDRESS_TWO, 1 ether); 84 : 85 : /* ----------PROPOSER------------ */ 86 0 : vm.startPrank(TEST_ADDRESS_ONE); 87 : 88 0 : uint256 proposalId = governance.propose(proposalAddress, PROPOSAL_DESCRIPTION); 89 : 90 : // TIME-TRAVEL 91 0 : vm.warp(block.timestamp + 6 hours); 92 : 93 0 : governance.castVote(proposalId, true); 94 : 95 0 : vm.stopPrank(); 96 : /* ------------------------------ */ 97 : 98 : /* -------------VOTER-------------*/ 99 0 : vm.startPrank(TEST_ADDRESS_TWO); 100 0 : governance.castVote(proposalId, true); 101 0 : vm.stopPrank(); 102 : /* ------------------------------ */ 103 : 104 0 : return proposalId; 105 : } 106 : 107 : function retrieveAndLockBalance(uint256, address voter, uint256 amount) internal { 108 : /* ----------GOVERNANCE------- */ 109 0 : vm.startPrank(getGovernanceProxyAddress()); 110 0 : IERC20(getTornTokenAddress()).transfer(voter, amount); 111 0 : vm.stopPrank(); 112 : /* ----------------------------*/ 113 : 114 : /* ----------VOTER------------ */ 115 0 : vm.startPrank(voter); 116 0 : IERC20(getTornTokenAddress()).approve(address(governance), amount); 117 0 : governance.lockWithApproval(amount); 118 0 : vm.stopPrank(); 119 : /* ----------------------------*/ 120 : } 121 : 122 : // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GETTERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 123 : 124 : function getProposalExecutableTime(uint256 proposalId) internal view returns (uint256) { 125 0 : Proposal memory proposal = IGovernance(getGovernanceProxyAddress()).proposals(proposalId); 126 0 : return proposal.endTime + EXECUTION_DELAY + 1 hours; 127 : } 128 : 129 : function _fetchConfiguration() internal { 130 0 : EXECUTION_DELAY = governance.EXECUTION_DELAY(); 131 0 : EXECUTION_EXPIRATION = governance.EXECUTION_EXPIRATION(); 132 0 : QUORUM_VOTES = governance.QUORUM_VOTES(); 133 0 : PROPOSAL_THRESHOLD = governance.PROPOSAL_THRESHOLD(); 134 0 : VOTING_DELAY = governance.VOTING_DELAY(); 135 0 : VOTING_PERIOD = governance.VOTING_PERIOD(); 136 0 : CLOSING_PERIOD = governance.CLOSING_PERIOD(); 137 0 : VOTE_EXTEND_TIME = governance.VOTE_EXTEND_TIME(); 138 : } 139 : }