Commit afcc6e55 authored by tre's avatar tre

add tests

parent 629e9bc0
......@@ -7,19 +7,28 @@ import { AdminFaucetAuthModule } from "../universal/faucet/authmodules/AdminFauc
import { FaucetHelper } from "../testing/helpers/FaucetHelper.sol";
contract Faucet_Initializer is Test {
event Drip(
string indexed authModule,
bytes indexed userId,
uint256 amount,
address indexed recipient
);
address internal faucetContractAdmin;
address internal faucetAuthAdmin;
address internal nonAdmin;
address internal fundsReceiver;
uint256 internal faucetAuthAdminKey;
uint256 internal nonAdminKey;
uint256 internal startingTimestamp = 1000;
Faucet faucet;
AdminFaucetAuthModule adminFam;
AdminFaucetAuthModule optimistNftFam;
AdminFaucetAuthModule githubFam;
FaucetHelper faucetHelper;
function setUp() public {
vm.warp(startingTimestamp);
faucetContractAdmin = makeAddr("faucetContractAdmin");
fundsReceiver = makeAddr("fundsReceiver");
......@@ -41,15 +50,22 @@ contract Faucet_Initializer is Test {
// Fill faucet with ether.
vm.deal(address(faucet), 10 ether);
adminFam = new AdminFaucetAuthModule(faucetAuthAdmin);
adminFam.initialize("AdminFAM");
optimistNftFam = new AdminFaucetAuthModule(faucetAuthAdmin);
optimistNftFam.initialize("OptimistNftFam");
githubFam = new AdminFaucetAuthModule(faucetAuthAdmin);
githubFam.initialize("GithubFam");
faucetHelper = new FaucetHelper();
}
function _enableFaucetAuthModule() internal {
function _enableFaucetAuthModules() internal {
vm.prank(faucetContractAdmin);
faucet.configure(adminFam, Faucet.ModuleConfig("OptimistModule", true, 1 days, 1 ether));
faucet.configure(
optimistNftFam,
Faucet.ModuleConfig("OptimistNftModule", true, 1 days, 1 ether)
);
vm.prank(faucetContractAdmin);
faucet.configure(githubFam, Faucet.ModuleConfig("GithubModule", true, 1 days, .05 ether));
}
/**
......@@ -106,15 +122,15 @@ contract FaucetTest is Faucet_Initializer {
assertEq(faucet.ADMIN(), faucetContractAdmin);
}
function test_AuthAdmin_drip_succeeds() external {
_enableFaucetAuthModule();
function test_authAdmin_drip_succeeds() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("AdminFAM"),
bytes(adminFam.version()),
bytes("OptimistNftFam"),
bytes(optimistNftFam.version()),
block.chainid,
address(adminFam),
address(optimistNftFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce
......@@ -123,19 +139,19 @@ contract FaucetTest is Faucet_Initializer {
vm.prank(nonAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(adminFam, abi.encodePacked(fundsReceiver), signature)
Faucet.AuthParameters(optimistNftFam, abi.encodePacked(fundsReceiver), signature)
);
}
function test_nonAdmin_drip_fails() external {
_enableFaucetAuthModule();
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
nonAdminKey,
bytes("AdminFAM"),
bytes(adminFam.version()),
bytes("OptimistNftFam"),
bytes(optimistNftFam.version()),
block.chainid,
address(adminFam),
address(optimistNftFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce
......@@ -145,7 +161,225 @@ contract FaucetTest is Faucet_Initializer {
vm.expectRevert("Faucet: drip parameters could not be verified by security module");
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(adminFam, abi.encodePacked(fundsReceiver), signature)
Faucet.AuthParameters(optimistNftFam, abi.encodePacked(fundsReceiver), signature)
);
}
function test_drip_optimistNft_sendsCorrectAmount() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("OptimistNftFam"),
bytes(optimistNftFam.version()),
block.chainid,
address(optimistNftFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce
);
uint256 recipientBalanceBefore = address(fundsReceiver).balance;
vm.prank(nonAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(optimistNftFam, abi.encodePacked(fundsReceiver), signature)
);
uint256 recipientBalanceAfter = address(fundsReceiver).balance;
assertEq(
recipientBalanceAfter - recipientBalanceBefore,
1 ether,
"expect increase of 1 ether"
);
}
function test_drip_github_sendsCorrectAmount() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("GithubFam"),
bytes(githubFam.version()),
block.chainid,
address(githubFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce
);
uint256 recipientBalanceBefore = address(fundsReceiver).balance;
vm.prank(nonAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature)
);
uint256 recipientBalanceAfter = address(fundsReceiver).balance;
assertEq(
recipientBalanceAfter - recipientBalanceBefore,
.05 ether,
"expect increase of .05 ether"
);
}
function test_drip_emitsEvent() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("GithubFam"),
bytes(githubFam.version()),
block.chainid,
address(githubFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce
);
vm.expectEmit(true, true, true, true, address(faucet));
emit Drip("GithubModule", abi.encodePacked(fundsReceiver), .05 ether, fundsReceiver);
vm.prank(nonAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature)
);
}
function test_drip_disabledModule_reverts() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("GithubFam"),
bytes(githubFam.version()),
block.chainid,
address(githubFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce
);
vm.startPrank(faucetContractAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature)
);
faucet.configure(githubFam, Faucet.ModuleConfig("GithubModule", false, 1 days, .05 ether));
vm.expectRevert("Faucet: provided auth module is not supported by this faucet");
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature)
);
vm.stopPrank();
}
function test_drip_preventsReplayAttacks() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("GithubFam"),
bytes(githubFam.version()),
block.chainid,
address(githubFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce
);
vm.startPrank(faucetContractAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature)
);
vm.expectRevert("Faucet: nonce has already been used");
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature)
);
vm.stopPrank();
}
function test_drip_beforeTimeout_reverts() external {
_enableFaucetAuthModules();
bytes32 nonce0 = faucetHelper.consumeNonce();
bytes memory signature0 = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("GithubFam"),
bytes(githubFam.version()),
block.chainid,
address(githubFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce0
);
vm.startPrank(faucetContractAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce0),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature0)
);
bytes32 nonce1 = faucetHelper.consumeNonce();
bytes memory signature1 = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("GithubFam"),
bytes(githubFam.version()),
block.chainid,
address(githubFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce1
);
vm.expectRevert("Faucet: auth cannot be used yet because timeout has not elapsed");
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce1),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature1)
);
vm.stopPrank();
}
function test_drip_afterTimeout_succeeds() external {
_enableFaucetAuthModules();
bytes32 nonce0 = faucetHelper.consumeNonce();
bytes memory signature0 = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("GithubFam"),
bytes(githubFam.version()),
block.chainid,
address(githubFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce0
);
vm.startPrank(faucetContractAdmin);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce0),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature0)
);
bytes32 nonce1 = faucetHelper.consumeNonce();
bytes memory signature1 = issueProofWithEIP712Domain(
faucetAuthAdminKey,
bytes("GithubFam"),
bytes(githubFam.version()),
block.chainid,
address(githubFam),
fundsReceiver,
abi.encodePacked(fundsReceiver),
nonce1
);
vm.warp(startingTimestamp + 1 days + 1 seconds);
faucet.drip(
Faucet.DripParameters(payable(fundsReceiver), nonce1),
Faucet.AuthParameters(githubFam, abi.encodePacked(fundsReceiver), signature1)
);
vm.stopPrank();
}
}
......@@ -21,6 +21,20 @@ contract SafeSend {
* @notice Faucet contract that drips ETH to users.
*/
contract Faucet {
/**
* @notice Emitted on each drip.
* @param authModule The type of authentication that was used for verifying the drip.
* @param userId The id of the user that requested the drip.
* @param amount The amount of funds sent.
* @param recipient The recipient of the drip.
*/
event Drip(
string indexed authModule,
bytes indexed userId,
uint256 amount,
address indexed recipient
);
/**
* @notice Parameters for a drip.
*/
......@@ -147,7 +161,12 @@ contract Faucet {
// Set the next timestamp at which this auth id can be used.
timeouts[_auth.module][_auth.id] = block.timestamp + config.ttl;
// Mark the nonce as used.
usedNonces[_auth.id][_params.nonce] = true;
// Execute a safe transfer of ETH to the recipient account.
new SafeSend{ value: config.amount }(_params.recipient);
emit Drip(config.name, _auth.id, config.amount, _params.recipient);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment