AdminFaucetAuthModule.t.sol 5.67 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
//SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { Test } from "forge-std/Test.sol";
import { AdminFaucetAuthModule } from "../universal/faucet/authmodules/AdminFaucetAuthModule.sol";
import { Faucet } from "../universal/faucet/Faucet.sol";
import { FaucetHelper } from "../testing/helpers/FaucetHelper.sol";

/**
 * @title  AdminFaucetAuthModuleTest
 * @notice Tests the AdminFaucetAuthModule contract.
 */
contract AdminFaucetAuthModuleTest is Test {
    /**
     * @notice The admin of the `AdminFaucetAuthModule` contract.
     */
    address internal admin;
    /**
     * @notice Private key of the `admin`.
     */
    uint256 internal adminKey;
    /**
     * @notice Not an admin of the `AdminFaucetAuthModule` contract.
     */
    address internal nonAdmin;
    /**
     * @notice Private key of the `nonAdmin`.
     */
    uint256 internal nonAdminKey;
    /**
     * @notice An instance of the `AdminFaucetAuthModule` contract.
     */
tre's avatar
tre committed
33
    AdminFaucetAuthModule internal adminFam;
34 35 36
    /**
     * @notice An instance of the `FaucetHelper` contract.
     */
tre's avatar
tre committed
37 38 39
    FaucetHelper internal faucetHelper;
    string internal adminFamName = "AdminFAM";
    string internal adminFamVersion = "1";
40 41 42 43 44 45 46 47 48 49 50

    /**
     * @notice Deploy the `AdminFaucetAuthModule` contract.
     */
    function setUp() external {
        adminKey = 0xB0B0B0B0;
        admin = vm.addr(adminKey);

        nonAdminKey = 0xC0C0C0C0;
        nonAdmin = vm.addr(nonAdminKey);

tre's avatar
tre committed
51
        adminFam = new AdminFaucetAuthModule(admin, adminFamName, adminFamVersion);
52 53 54 55 56 57 58 59

        faucetHelper = new FaucetHelper();
    }

    /**
     * @notice Get signature as a bytes blob.
     *
     */
tre's avatar
tre committed
60 61 62 63 64
    function _getSignature(uint256 _signingPrivateKey, bytes32 _digest)
        internal
        pure
        returns (bytes memory)
    {
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
        (uint8 v, bytes32 r, bytes32 s) = vm.sign(_signingPrivateKey, _digest);

        bytes memory signature = abi.encodePacked(r, s, v);
        return signature;
    }

    /**
     * @notice Signs a proof with the given private key and returns the signature using
     *         the given EIP712 domain separator. This assumes that the issuer's address is the
     *         corresponding public key to _issuerPrivateKey.
     */
    function issueProofWithEIP712Domain(
        uint256 _issuerPrivateKey,
        bytes memory _eip712Name,
        bytes memory _contractVersion,
        uint256 _eip712Chainid,
        address _eip712VerifyingContract,
        address recipient,
83
        bytes32 id,
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
        bytes32 nonce
    ) internal view returns (bytes memory) {
        AdminFaucetAuthModule.Proof memory proof = AdminFaucetAuthModule.Proof(
            recipient,
            nonce,
            id
        );
        return
            _getSignature(
                _issuerPrivateKey,
                faucetHelper.getDigestWithEIP712Domain(
                    proof,
                    _eip712Name,
                    _contractVersion,
                    _eip712Chainid,
                    _eip712VerifyingContract
                )
            );
    }

    /**
     * @notice assert that verify returns true for valid proofs signed by admins.
     */
    function test_adminProof_verify_returnsTrue() external {
        bytes32 nonce = faucetHelper.consumeNonce();
        address fundsReceiver = makeAddr("fundsReceiver");
        bytes memory proof = issueProofWithEIP712Domain(
            adminKey,
tre's avatar
tre committed
112 113
            bytes(adminFamName),
            bytes(adminFamVersion),
114 115 116
            block.chainid,
            address(adminFam),
            fundsReceiver,
117
            keccak256(abi.encodePacked(fundsReceiver)),
118 119 120 121
            nonce
        );

        vm.prank(nonAdmin);
tre's avatar
tre committed
122 123 124
        assertEq(
            adminFam.verify(
                Faucet.DripParameters(payable(fundsReceiver), nonce),
125
                keccak256(abi.encodePacked(fundsReceiver)),
tre's avatar
tre committed
126 127 128
                proof
            ),
            true
129 130 131 132 133 134 135 136 137 138 139
        );
    }

    /**
     * @notice assert that verify returns false for proofs signed by nonadmins.
     */
    function test_nonAdminProof_verify_returnsFalse() external {
        bytes32 nonce = faucetHelper.consumeNonce();
        address fundsReceiver = makeAddr("fundsReceiver");
        bytes memory proof = issueProofWithEIP712Domain(
            nonAdminKey,
tre's avatar
tre committed
140 141
            bytes(adminFamName),
            bytes(adminFamVersion),
142 143 144
            block.chainid,
            address(adminFam),
            fundsReceiver,
145
            keccak256(abi.encodePacked(fundsReceiver)),
146 147 148 149 150 151 152
            nonce
        );

        vm.prank(admin);
        assertEq(
            adminFam.verify(
                Faucet.DripParameters(payable(fundsReceiver), nonce),
153
                keccak256(abi.encodePacked(fundsReceiver)),
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
                proof
            ),
            false
        );
    }

    /**
     * @notice assert that verify returns false for proofs where the id in the proof is different
     * than the id in the call to verify.
     */
    function test_proofWithWrongId_verify_returnsFalse() external {
        bytes32 nonce = faucetHelper.consumeNonce();
        address fundsReceiver = makeAddr("fundsReceiver");
        address randomAddress = makeAddr("randomAddress");
        bytes memory proof = issueProofWithEIP712Domain(
            adminKey,
tre's avatar
tre committed
170 171
            bytes(adminFamName),
            bytes(adminFamVersion),
172 173 174
            block.chainid,
            address(adminFam),
            fundsReceiver,
175
            keccak256(abi.encodePacked(fundsReceiver)),
176 177 178 179 180 181 182
            nonce
        );

        vm.prank(admin);
        assertEq(
            adminFam.verify(
                Faucet.DripParameters(payable(fundsReceiver), nonce),
183
                keccak256(abi.encodePacked(randomAddress)),
184 185 186 187 188 189
                proof
            ),
            false
        );
    }
}