diff --git a/.gitmodules b/.gitmodules index b7af30b..140d7df 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std - branch = v1.5.1 + branch = v1.5.3 diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 0000000..fc560fa --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit fc560fa34fa12a335a50c35d92e55a6628ca467c diff --git a/package.json b/package.json index 76a9f01..1ab731d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "test": "test" }, "scripts": { - "test": "forge test -vvvvv --fork-url https://api.securerpc.com/v1 --block-number 16216695" + "test": "forge test -vvvvv --fork-url https://api.securerpc.com/v1 --block-number 17011300" }, "author": "", "license": "ISC" diff --git a/src/Proposal.sol b/src/Proposal.sol index 940402e..401f1c2 100644 --- a/src/Proposal.sol +++ b/src/Proposal.sol @@ -1,11 +1,25 @@ pragma solidity 0.8.1; import "./interfaces/IRelayerRegistry.sol"; -import "./proprietary/Parameters.sol"; -contract Proposal is Parameters { +contract Proposal { function executeProposal() external { + address[10] memory VIOLATING_RELAYERS = [ + 0x30F96AEF199B399B722F8819c9b0723016CEAe6C, // moon-relayer.eth + 0xEFa22d23de9f293B11e0c4aC865d7b440647587a, // tornado-relayer.eth + 0x996ad81FD83eD7A87FD3D03694115dff19db0B3b, // secure-tornado.eth + 0x7853E027F37830790685622cdd8685fF0c8255A2, // tornado-secure.eth + 0x36DD7b862746fdD3eDd3577c8411f1B76FDC2Af5, // tornado-crypto-bot-exchange.eth + 0x18F516dD6D5F46b2875Fd822B994081274be2a8b, // torn69.eth + 0x853281B7676DFB66B87e2f26c9cB9D10Ce883F37, // available-reliable-relayer.eth + 0xaaaaD0b504B4CD22348C4Db1071736646Aa314C6, // tornrelayers.eth + 0x0000208a6cC0299dA631C08fE8c2EDe435Ea83B8, // 0xtornadocash.eth + 0xf0D9b969925116074eF43e7887Bcf035Ff1e7B19 // lowfee-relayer.eth + ]; + + address _registryAddress = 0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2; + IRelayerRegistry(_registryAddress).nullifyBalance(VIOLATING_RELAYERS[0]); IRelayerRegistry(_registryAddress).nullifyBalance(VIOLATING_RELAYERS[1]); IRelayerRegistry(_registryAddress).nullifyBalance(VIOLATING_RELAYERS[2]); diff --git a/src/interfaces/IRelayerRegistry.sol b/src/interfaces/IRelayerRegistry.sol index 60807a9..ba03629 100644 --- a/src/interfaces/IRelayerRegistry.sol +++ b/src/interfaces/IRelayerRegistry.sol @@ -2,6 +2,10 @@ pragma solidity ^0.8.1; interface IRelayerRegistry { + function getRelayerBalance(address relayer) external returns (uint256); + + function isRelayer(address relayer) external returns (bool); + function nullifyBalance(address relayer) external; } \ No newline at end of file diff --git a/src/proprietary/Mock.sol b/src/proprietary/Mock.sol index 1cbe61f..51ebbf1 100644 --- a/src/proprietary/Mock.sol +++ b/src/proprietary/Mock.sol @@ -13,7 +13,7 @@ contract Mock { address constant VERIFIER_ADDRESS = 0x77777FeDdddFfC19Ff86DB637967013e6C6A116C; - bytes32 constant public PERMIT_TYPEHASH = keccak256( + bytes32 constant PERMIT_TYPEHASH = keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ); @@ -29,4 +29,8 @@ contract Mock { uint16 constant PERMIT_FUNC_SELECTOR = uint16(0x1901); + address constant _tokenAddress = 0x77777FeDdddFfC19Ff86DB637967013e6C6A116C; + address constant _governanceAddress = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce; + + } \ No newline at end of file diff --git a/src/proprietary/Parameters.sol b/src/proprietary/Parameters.sol index 03f49d8..bcacb0f 100644 --- a/src/proprietary/Parameters.sol +++ b/src/proprietary/Parameters.sol @@ -1,20 +1,20 @@ -pragma solidity 0.8.1; +pragma solidity ^0.8.1; contract Parameters { - address[10] VIOLATING_RELAYERS = [ - 0x30F96AEF199B399B722F8819c9b0723016CEAe6C, // moon-relayer.eth + address[10] VIOLATING_RELAYERS = [ + 0x30F96AEF199B399B722F8819c9b0723016CEAe6C, // moon-relayer.eth 0xEFa22d23de9f293B11e0c4aC865d7b440647587a, // tornado-relayer.eth - 0x996ad81FD83eD7A87FD3D03694115dff19db0B3b, // secure-tornado.eth - 0x7853E027F37830790685622cdd8685fF0c8255A2, // tornado-secure.eth - 0x36DD7b862746fdD3eDd3577c8411f1B76FDC2Af5, // tornado-crypto-bot-exchange.eth - 0x18F516dD6D5F46b2875Fd822B994081274be2a8b, // torn69.eth - 0x853281B7676DFB66B87e2f26c9cB9D10Ce883F37, // available-reliable-relayer.eth - 0xaaaaD0b504B4CD22348C4Db1071736646Aa314C6, // tornrelayers.eth - 0x0000208a6cC0299dA631C08fE8c2EDe435Ea83B8, // 0xtornadocash.eth - 0xf0D9b969925116074eF43e7887Bcf035Ff1e7B19 // lowfee-relayer.eth - ]; + 0x996ad81FD83eD7A87FD3D03694115dff19db0B3b, // secure-tornado.eth + 0x7853E027F37830790685622cdd8685fF0c8255A2, // tornado-secure.eth + 0x36DD7b862746fdD3eDd3577c8411f1B76FDC2Af5, // tornado-crypto-bot-exchange.eth + 0x18F516dD6D5F46b2875Fd822B994081274be2a8b, // torn69.eth + 0x853281B7676DFB66B87e2f26c9cB9D10Ce883F37, // available-reliable-relayer.eth + 0xaaaaD0b504B4CD22348C4Db1071736646Aa314C6, // tornrelayers.eth + 0x0000208a6cC0299dA631C08fE8c2EDe435Ea83B8, // 0xtornadocash.eth + 0xf0D9b969925116074eF43e7887Bcf035Ff1e7B19 // lowfee-relayer.eth + ]; - address _registryAddress = 0x01e2919679362dFBC9ee1644Ba9C6da6D6245BB1; + address _registryAddress = 0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2; -} +} \ No newline at end of file diff --git a/test/Proposal.t.sol b/test/Proposal.t.sol index 170d4bd..bce4b9a 100644 --- a/test/Proposal.t.sol +++ b/test/Proposal.t.sol @@ -1,5 +1,6 @@ pragma solidity ^0.8.1; +import "../src/interfaces/IRelayerRegistry.sol"; import "../src/interfaces/IGovernance.sol"; import "../src/interfaces/IERC20.sol"; @@ -9,84 +10,93 @@ import "../src/proprietary/Mock.sol"; import "../src/Proposal.sol"; import "forge-std/Test.sol"; -contract ProposalTest is Test, Mock, Parameters { +contract ProposalTest is Test, Parameters, Mock { - function testProposal() public { - checkParameters(); + function testProposal() public { + checkParameters(); - uint256 proposalId = voteAndCreateProposal(address(new Proposal())); + uint256 proposalId = voteAndCreateProposal(address(new Proposal())); - IGovernance(governanceAddress).execute(proposalId); - } + IGovernance(_governanceAddress).execute(proposalId); - function voteAndCreateProposal(address proposalAddress) public returns (uint256) { - retrieveAndLockBalance(TEST_PRIVATE_KEY_ONE, TEST_ADDRESS_ONE, PROPOSAL_THRESHOLD); - retrieveAndLockBalance(TEST_PRIVATE_KEY_TWO, TEST_ADDRESS_TWO, 1 ether); + checkResults(); + } - /* ----------PROPOSER------------ */ - vm.startPrank(TEST_ADDRESS_ONE); + function voteAndCreateProposal(address proposalAddress) public returns (uint256) { + retrieveAndLockBalance(TEST_PRIVATE_KEY_ONE, TEST_ADDRESS_ONE, PROPOSAL_THRESHOLD); + retrieveAndLockBalance(TEST_PRIVATE_KEY_TWO, TEST_ADDRESS_TWO, 1 ether); + + /* ----------PROPOSER------------ */ + vm.startPrank(TEST_ADDRESS_ONE); - uint256 proposalId = IGovernance(governanceAddress).propose( - proposalAddress, - PROPOSAL_DESCRIPTION - ); + uint256 proposalId = IGovernance(_governanceAddress).propose(proposalAddress, PROPOSAL_DESCRIPTION); - // TIME-TRAVEL - vm.warp(block.timestamp + 6 hours); + // TIME-TRAVEL + vm.warp(block.timestamp + 6 hours); - IGovernance(governanceAddress).castVote(proposalId, true); + IGovernance(_governanceAddress).castVote(proposalId, true); - vm.stopPrank(); - /* ------------------------------ */ + vm.stopPrank(); + /* ------------------------------ */ - /* -------------VOTER-------------*/ - vm.startPrank(TEST_ADDRESS_TWO); - IGovernance(governanceAddress).castVote(proposalId, true); - vm.stopPrank(); - /* ------------------------------ */ + /* -------------VOTER-------------*/ + vm.startPrank(TEST_ADDRESS_TWO); + IGovernance(_governanceAddress).castVote(proposalId, true); + vm.stopPrank(); + /* ------------------------------ */ - // TIME-TRAVEL - vm.warp(block.timestamp + PROPOSAL_DURATION); + // TIME-TRAVEL + vm.warp(block.timestamp + PROPOSAL_DURATION); - return proposalId; - } + return proposalId; + } - function retrieveAndLockBalance(uint256 privateKey, address voter, uint256 amount) internal { - uint256 lockTimestamp = block.timestamp + PROPOSAL_DURATION; - bytes32 messageHash = keccak256( - abi.encodePacked( - PERMIT_FUNC_SELECTOR, - EIP712_DOMAIN, - keccak256( - abi.encode( - PERMIT_TYPEHASH, - voter, - governanceAddress, - amount, - 0, - lockTimestamp - ) - ) - ) - ); + function retrieveAndLockBalance(uint256 privateKey, address voter, uint256 amount) internal { + uint256 lockTimestamp = block.timestamp + PROPOSAL_DURATION; + bytes32 messageHash = keccak256(abi.encodePacked( + PERMIT_FUNC_SELECTOR, + EIP712_DOMAIN, + keccak256(abi.encode(PERMIT_TYPEHASH, voter, _governanceAddress, amount, 0, lockTimestamp)) + )); - /* ----------GOVERNANCE------- */ - vm.startPrank(governanceAddress); - IERC20(tokenAddress).transfer(voter, amount); - vm.stopPrank(); - /* ----------------------------*/ + /* ----------GOVERNANCE------- */ + vm.startPrank(_governanceAddress); + IERC20(_tokenAddress).transfer(voter, amount); + vm.stopPrank(); + /* ----------------------------*/ - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, messageHash); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, messageHash); - /* ----------VOTER------------ */ - vm.startPrank(voter); - IGovernance(governanceAddress).lock(voter, amount, lockTimestamp, v, r, s); - vm.stopPrank(); - /* ----------------------------*/ - } + /* ----------VOTER------------ */ + vm.startPrank(voter); + IGovernance(_governanceAddress).lock(voter, amount, lockTimestamp, v, r, s); + vm.stopPrank(); + /* ----------------------------*/ + } - function checkParameters() internal {} - - function checkResults() internal {} + function checkParameters() internal { + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[0])); + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[1])); + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[2])); + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[3])); + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[4])); + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[5])); + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[6])); + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[7])); + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[8])); + require(IRelayerRegistry(_registryAddress).isRelayer(VIOLATING_RELAYERS[9])); + } + function checkResults() internal { + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[0]) == 0); + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[1]) == 0); + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[2]) == 0); + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[3]) == 0); + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[4]) == 0); + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[5]) == 0); + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[6]) == 0); + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[7]) == 0); + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[8]) == 0); + require(IRelayerRegistry(_registryAddress).getRelayerBalance(VIOLATING_RELAYERS[9]) == 0); + } }