github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/test/periphery/faucet/authmodules/AdminFaucetAuthModule.t.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity 0.8.15; 3 4 import { Test } from "forge-std/Test.sol"; 5 import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; 6 import { Faucet } from "src/periphery/faucet/Faucet.sol"; 7 import { FaucetHelper } from "test/mocks/FaucetHelper.sol"; 8 9 /// @title AdminFaucetAuthModuleTest 10 /// @notice Tests the AdminFaucetAuthModule contract. 11 contract AdminFaucetAuthModuleTest is Test { 12 /// @notice The admin of the `AdminFaucetAuthModule` contract. 13 address internal admin; 14 15 /// @notice Private key of the `admin`. 16 uint256 internal adminKey; 17 18 /// @notice Not an admin of the `AdminFaucetAuthModule` contract. 19 address internal nonAdmin; 20 21 /// @notice Private key of the `nonAdmin`. 22 uint256 internal nonAdminKey; 23 24 /// @notice An instance of the `AdminFaucetAuthModule` contract. 25 AdminFaucetAuthModule internal adminFam; 26 27 /// @notice An instance of the `FaucetHelper` contract. 28 FaucetHelper internal faucetHelper; 29 30 string internal adminFamName = "AdminFAM"; 31 32 string internal adminFamVersion = "1"; 33 34 /// @notice Deploy the `AdminFaucetAuthModule` contract. 35 function setUp() external { 36 adminKey = 0xB0B0B0B0; 37 admin = vm.addr(adminKey); 38 39 nonAdminKey = 0xC0C0C0C0; 40 nonAdmin = vm.addr(nonAdminKey); 41 42 adminFam = new AdminFaucetAuthModule(admin, adminFamName, adminFamVersion); 43 44 faucetHelper = new FaucetHelper(); 45 } 46 47 /// @notice Get signature as a bytes blob. 48 function _getSignature(uint256 _signingPrivateKey, bytes32 _digest) internal pure returns (bytes memory) { 49 (uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest); 50 51 bytes memory signature = abi.encodePacked(r, s, v); 52 return signature; 53 } 54 55 /// @notice Signs a proof with the given private key and returns the signature using 56 /// the given EIP712 domain separator. This assumes that the issuer's address is the 57 /// corresponding public key to _issuerPrivateKey. 58 function issueProofWithEIP712Domain( 59 uint256 _issuerPrivateKey, 60 bytes memory _eip712Name, 61 bytes memory _contractVersion, 62 uint256 _eip712Chainid, 63 address _eip712VerifyingContract, 64 address recipient, 65 bytes32 id, 66 bytes32 nonce 67 ) 68 internal 69 view 70 returns (bytes memory) 71 { 72 AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof(recipient, nonce, id); 73 return _getSignature( 74 _issuerPrivateKey, 75 faucetHelper.getDigestWithEIP712Domain( 76 proof, _eip712Name, _contractVersion, _eip712Chainid, _eip712VerifyingContract 77 ) 78 ); 79 } 80 81 /// @notice Assert that verify returns true for valid proofs signed by admins. 82 function test_adminProof_verify_succeeds() external { 83 bytes32 nonce = faucetHelper.consumeNonce(); 84 address fundsReceiver = makeAddr("fundsReceiver"); 85 bytes memory proof = issueProofWithEIP712Domain( 86 adminKey, 87 bytes(adminFamName), 88 bytes(adminFamVersion), 89 block.chainid, 90 address(adminFam), 91 fundsReceiver, 92 keccak256(abi.encodePacked(fundsReceiver)), 93 nonce 94 ); 95 96 vm.prank(nonAdmin); 97 assertEq( 98 adminFam.verify( 99 Faucet.DripParameters(payable(fundsReceiver), nonce), keccak256(abi.encodePacked(fundsReceiver)), proof 100 ), 101 true 102 ); 103 } 104 105 /// @notice Assert that verify returns false for proofs signed by nonadmins. 106 function test_nonAdminProof_verify_succeeds() external { 107 bytes32 nonce = faucetHelper.consumeNonce(); 108 address fundsReceiver = makeAddr("fundsReceiver"); 109 bytes memory proof = issueProofWithEIP712Domain( 110 nonAdminKey, 111 bytes(adminFamName), 112 bytes(adminFamVersion), 113 block.chainid, 114 address(adminFam), 115 fundsReceiver, 116 keccak256(abi.encodePacked(fundsReceiver)), 117 nonce 118 ); 119 120 vm.prank(admin); 121 assertEq( 122 adminFam.verify( 123 Faucet.DripParameters(payable(fundsReceiver), nonce), keccak256(abi.encodePacked(fundsReceiver)), proof 124 ), 125 false 126 ); 127 } 128 129 /// @notice Assert that verify returns false for proofs where the id in the proof is different 130 /// than the id in the call to verify. 131 function test_proofWithWrongId_verify_succeeds() external { 132 bytes32 nonce = faucetHelper.consumeNonce(); 133 address fundsReceiver = makeAddr("fundsReceiver"); 134 address randomAddress = makeAddr("randomAddress"); 135 bytes memory proof = issueProofWithEIP712Domain( 136 adminKey, 137 bytes(adminFamName), 138 bytes(adminFamVersion), 139 block.chainid, 140 address(adminFam), 141 fundsReceiver, 142 keccak256(abi.encodePacked(fundsReceiver)), 143 nonce 144 ); 145 146 vm.prank(admin); 147 assertEq( 148 adminFam.verify( 149 Faucet.DripParameters(payable(fundsReceiver), nonce), keccak256(abi.encodePacked(randomAddress)), proof 150 ), 151 false 152 ); 153 } 154 }