Commit e83176ba authored by James Kim's avatar James Kim

refactor optimistInviterHelper

parent 471b4af5
...@@ -8,9 +8,7 @@ import { OptimistInviter } from "../universal/op-nft/OptimistInviter.sol"; ...@@ -8,9 +8,7 @@ import { OptimistInviter } from "../universal/op-nft/OptimistInviter.sol";
import { Optimist } from "../universal/op-nft/Optimist.sol"; import { Optimist } from "../universal/op-nft/Optimist.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { TestERC1271Wallet } from "../testing/helpers/TestERC1271Wallet.sol"; import { TestERC1271Wallet } from "../testing/helpers/TestERC1271Wallet.sol";
import { import { OptimistInviterHelper } from "../testing/helpers/OptimistInviterHelper.sol";
ClaimableInviteEIP712TypedData
} from "../testing/helpers/ClaimableInviteEIP712TypedData.sol";
contract OptimistInviter_Initializer is Test { contract OptimistInviter_Initializer is Test {
event InviteClaimed(address indexed issuer, address indexed claimer); event InviteClaimed(address indexed issuer, address indexed claimer);
...@@ -35,16 +33,14 @@ contract OptimistInviter_Initializer is Test { ...@@ -35,16 +33,14 @@ contract OptimistInviter_Initializer is Test {
address internal carol; address internal carol;
uint256 internal carolPrivateKey; uint256 internal carolPrivateKey;
uint256 currentNonce;
TestERC1271Wallet carolERC1271Wallet; TestERC1271Wallet carolERC1271Wallet;
AttestationStation attestationStation; AttestationStation attestationStation;
OptimistInviter optimistInviter; OptimistInviter optimistInviter;
function setUp() public { OptimistInviterHelper optimistInviterHelper;
currentNonce = 0;
function setUp() public {
alice_inviteGranter = makeAddr("alice_inviteGranter"); alice_inviteGranter = makeAddr("alice_inviteGranter");
sally = makeAddr("sally"); sally = makeAddr("sally");
ted = makeAddr("ted"); ted = makeAddr("ted");
...@@ -83,14 +79,8 @@ contract OptimistInviter_Initializer is Test { ...@@ -83,14 +79,8 @@ contract OptimistInviter_Initializer is Test {
vm.expectEmit(true, true, true, true, address(optimistInviter)); vm.expectEmit(true, true, true, true, address(optimistInviter));
emit Initialized(1); emit Initialized(1);
optimistInviter.initialize("OptimistInviter"); optimistInviter.initialize("OptimistInviter");
}
/** optimistInviterHelper = new OptimistInviterHelper(optimistInviter, "OptimistInviter");
* @notice Returns a bytes32 nonce that should change everytime. In practice, people should use
* pseudorandom nonces.
*/
function _consumeNonce() internal returns (bytes32) {
return bytes32(keccak256(abi.encode(currentNonce++)));
} }
/** /**
...@@ -157,18 +147,14 @@ contract OptimistInviter_Initializer is Test { ...@@ -157,18 +147,14 @@ contract OptimistInviter_Initializer is Test {
uint256 _eip712Chainid, uint256 _eip712Chainid,
address _eip712VerifyingContract address _eip712VerifyingContract
) internal returns (OptimistInviter.ClaimableInvite memory, bytes memory) { ) internal returns (OptimistInviter.ClaimableInvite memory, bytes memory) {
bytes32 nonce = _consumeNonce();
address issuer = vm.addr(_issuerPrivateKey); address issuer = vm.addr(_issuerPrivateKey);
OptimistInviter.ClaimableInvite memory claimableInvite = OptimistInviter.ClaimableInvite( OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper
issuer, .getClaimableInviteWithNewNonce(issuer);
nonce
);
return ( return (
claimableInvite, claimableInvite,
_getSignature( _getSignature(
_issuerPrivateKey, _issuerPrivateKey,
ClaimableInviteEIP712TypedData.getDigest( optimistInviterHelper.getDigestWithEIP712Domain(
claimableInvite, claimableInvite,
_eip712Name, _eip712Name,
_eip712Version, _eip712Version,
...@@ -261,25 +247,6 @@ contract OptimistInviter_Initializer is Test { ...@@ -261,25 +247,6 @@ contract OptimistInviter_Initializer is Test {
assertEq(_getInviteCount(_to), 3); assertEq(_getInviteCount(_to), 3);
} }
/**
* @notice Issues 3 invites to the given address. Checks that all expected events are emitted
* and that state is updated correctly.
*/
function _getEIP712Digest(OptimistInviter.ClaimableInvite memory _claimableInvite)
internal
view
returns (bytes32)
{
return
ClaimableInviteEIP712TypedData.getDigest(
_claimableInvite,
bytes("OptimistInviter"),
bytes(optimistInviter.EIP712_VERSION()),
block.chainid,
address(optimistInviter)
);
}
} }
contract OptimistInviterTest is OptimistInviter_Initializer { contract OptimistInviterTest is OptimistInviter_Initializer {
...@@ -521,13 +488,13 @@ contract OptimistInviterTest is OptimistInviter_Initializer { ...@@ -521,13 +488,13 @@ contract OptimistInviterTest is OptimistInviter_Initializer {
function test_claimInvite_usingERC1271Wallet_succeeds() external { function test_claimInvite_usingERC1271Wallet_succeeds() external {
_grantInvitesTo(address(carolERC1271Wallet)); _grantInvitesTo(address(carolERC1271Wallet));
bytes32 nonce = _consumeNonce(); OptimistInviter.ClaimableInvite memory claimableInvite = optimistInviterHelper
OptimistInviter.ClaimableInvite memory claimableInvite = OptimistInviter.ClaimableInvite( .getClaimableInviteWithNewNonce(address(carolERC1271Wallet));
address(carolERC1271Wallet),
nonce
);
bytes memory signature = _getSignature(carolPrivateKey, _getEIP712Digest(claimableInvite)); bytes memory signature = _getSignature(
carolPrivateKey,
optimistInviterHelper.getDigest(claimableInvite)
);
// Sally tries to claim the invite // Sally tries to claim the invite
_commitInviteAs(sally, signature); _commitInviteAs(sally, signature);
......
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { OptimistInviter } from "../../universal/op-nft/OptimistInviter.sol"; import { OptimistInviter } from "../../universal/op-nft/OptimistInviter.sol";
/** /**
* Helper library that generates the EIP712 digest for a ClaimableInvite. * Simple helper contract that helps with testing flow and signature for OptimistInviter contract.
* Made this a separate contract instead of including in OptimistInviter.t.sol for reusability.
*/ */
library ClaimableInviteEIP712TypedData { contract OptimistInviterHelper {
bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = bytes32 public constant CLAIMABLE_INVITE_TYPEHASH =
keccak256("ClaimableInvite(address issuer,bytes32 nonce)"); keccak256("ClaimableInvite(address issuer,bytes32 nonce)");
...@@ -16,8 +18,21 @@ library ClaimableInviteEIP712TypedData { ...@@ -16,8 +18,21 @@ library ClaimableInviteEIP712TypedData {
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
); );
function _getStructHash(OptimistInviter.ClaimableInvite memory _claimableInvite) OptimistInviter public optimistInviter;
internal string public name;
uint256 public currentNonce;
constructor(OptimistInviter _optimistInviter, string memory _name) {
optimistInviter = _optimistInviter;
name = _name;
currentNonce = 0;
}
/**
* @notice Returns the hash of the struct ClaimableInvite
*/
function getClaimableInviteStructHash(OptimistInviter.ClaimableInvite memory _claimableInvite)
public
pure pure
returns (bytes32) returns (bytes32)
{ {
...@@ -31,11 +46,47 @@ library ClaimableInviteEIP712TypedData { ...@@ -31,11 +46,47 @@ library ClaimableInviteEIP712TypedData {
); );
} }
/**
* @notice Returns a bytes32 nonce that should change everytime. In practice, people should use
* pseudorandom nonces.
*/
function consumeNonce() public returns (bytes32) {
return bytes32(keccak256(abi.encode(currentNonce++)));
}
/**
* @notice Returns a ClaimableInvite with the issuer and current nonce
*/
function getClaimableInviteWithNewNonce(address _issuer)
public
returns (OptimistInviter.ClaimableInvite memory)
{
return OptimistInviter.ClaimableInvite(_issuer, consumeNonce());
}
/**
* @notice Computes the EIP712 digest with default correct parameters.
*/
function getDigest(OptimistInviter.ClaimableInvite calldata _claimableInvite)
public
view
returns (bytes32)
{
return
getDigestWithEIP712Domain(
_claimableInvite,
bytes(name),
bytes(optimistInviter.EIP712_VERSION()),
block.chainid,
address(optimistInviter)
);
}
/** /**
* @notice Computes the EIP712 digest with the given domain parameters. * @notice Computes the EIP712 digest with the given domain parameters.
* Used for testing that different domain parameters fail. * Used for testing that different domain parameters fail.
*/ */
function getDigest( function getDigestWithEIP712Domain(
OptimistInviter.ClaimableInvite calldata _claimableInvite, OptimistInviter.ClaimableInvite calldata _claimableInvite,
bytes memory _name, bytes memory _name,
bytes memory _version, bytes memory _version,
...@@ -51,6 +102,7 @@ library ClaimableInviteEIP712TypedData { ...@@ -51,6 +102,7 @@ library ClaimableInviteEIP712TypedData {
_verifyingContract _verifyingContract
) )
); );
return ECDSA.toTypedDataHash(domainSeparator, _getStructHash(_claimableInvite)); return
ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite));
} }
} }
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