Skip to content

Commit

Permalink
refactor: generate witness as public field
Browse files Browse the repository at this point in the history
  • Loading branch information
anna-carroll committed Jul 19, 2024
1 parent e88165b commit 3ea69d2
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 23 deletions.
8 changes: 6 additions & 2 deletions src/Orders.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ abstract contract OrderDestination is IOrders, OrdersPermit2 {
/// @custom:emits Filled
function fillPermit2(Output[] memory outputs, OrdersPermit2.Permit2Batch calldata permit2) external {
// transfer all tokens to the Output recipients via permit2 (includes check on nonce & deadline)
_permitWitnessTransferFrom(outputs, _fillTransferDetails(outputs, permit2.permit.permitted), permit2);
_permitWitnessTransferFrom(
outputsWitness(outputs), _fillTransferDetails(outputs, permit2.permit.permitted), permit2
);

// emit
emit Filled(outputs);
Expand Down Expand Up @@ -123,7 +125,9 @@ abstract contract OrderOrigin is IOrders, OrdersPermit2 {
OrdersPermit2.Permit2Batch calldata permit2
) external {
// transfer all tokens to the tokenRecipient via permit2 (includes check on nonce & deadline)
_permitWitnessTransferFrom(outputs, _initiateTransferDetails(tokenRecipient, permit2.permit.permitted), permit2);
_permitWitnessTransferFrom(
outputsWitness(outputs), _initiateTransferDetails(tokenRecipient, permit2.permit.permitted), permit2
);

// emit
emit Order(permit2.permit.deadline, _inputs(permit2.permit.permitted), outputs);
Expand Down
4 changes: 2 additions & 2 deletions src/Passage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ contract Passage is PassagePermit2 {
public
{
// transfer tokens to this contract via permit2
_permitWitnessTransferFrom(_enterWitness(rollupChainId, rollupRecipient), true, permit2);
_permitWitnessTransferFrom(enterWitness(rollupChainId, rollupRecipient), permit2);
// check and emit
_enterToken(rollupChainId, rollupRecipient, permit2.permit.permitted.token, permit2.permit.permitted.amount);
}
Expand Down Expand Up @@ -197,7 +197,7 @@ contract RollupPassage is PassagePermit2 {
/// @custom:emits ExitToken
function exitTokenPermit2(address hostRecipient, PassagePermit2.Permit2 calldata permit2) public {
// transfer tokens to this contract
_permitWitnessTransferFrom(_exitWitness(hostRecipient), false, permit2);
_permitWitnessTransferFrom(exitWitness(hostRecipient), permit2);
// burn and emit
_exitToken(hostRecipient, permit2.permit.permitted.token, permit2.permit.permitted.amount);
}
Expand Down
48 changes: 31 additions & 17 deletions src/permit2/UsesPermit2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import {ISignatureTransfer} from "permit2/src/interfaces/ISignatureTransfer.sol"
import {IOrders} from "../interfaces/IOrders.sol";

abstract contract UsesPermit2 {
/// @notice Struct to hold the pre-hashed witness field and the witness type string.
struct Witness {
bytes32 witnessHash;
string witnessTypeString;
}

/// @notice The Permit2 contract address.
address immutable permit2Contract;

Expand Down Expand Up @@ -33,34 +39,35 @@ abstract contract OrdersPermit2 is UsesPermit2 {
error OutputMismatch();

/// @notice Transfer a batch of tokens using permit2.
/// @param outputs - the Outputs for the witness field.
/// @param _witness - the hashed witness and its typestring.
/// @param transferDetails - the TokenPermissions for the transfer, generated based on the use-case (see `_initiateTransferDetails` and `_fillTransferDetails`).
/// @param permit2 - the Permit2Batch information.
function _permitWitnessTransferFrom(
IOrders.Output[] memory outputs,
Witness memory _witness,
ISignatureTransfer.SignatureTransferDetails[] memory transferDetails,
Permit2Batch calldata permit2
) internal {
ISignatureTransfer(permit2Contract).permitWitnessTransferFrom(
permit2.permit,
transferDetails,
permit2.owner,
_witness(outputs),
_OUTPUT_WITNESS_TYPESTRING,
_witness.witnessHash,
_witness.witnessTypeString,
permit2.signature
);
}

/// @notice Encode the Output array according to EIP-712 for use as a permit2 witness.
/// @param outputs - the Outputs to encode.
/// @return witness - the encoded witness field.
function _witness(IOrders.Output[] memory outputs) internal pure returns (bytes32 witness) {
/// @return _witness - the encoded witness field.
function outputsWitness(IOrders.Output[] memory outputs) public pure returns (Witness memory _witness) {
uint256 num = outputs.length;
bytes32[] memory hashes = new bytes32[](num);
for (uint256 i = 0; i < num; ++i) {
hashes[i] = keccak256(abi.encode(_OUTPUT_TYPEHASH, outputs[i]));
}
witness = keccak256(abi.encodePacked(hashes));
_witness.witnessHash = keccak256(abi.encodePacked(hashes));
_witness.witnessTypeString = _OUTPUT_WITNESS_TYPESTRING;
}

/// @notice transform Output and TokenPermissions structs to TransferDetails structs, for passing to permit2.
Expand Down Expand Up @@ -145,29 +152,36 @@ abstract contract PassagePermit2 is UsesPermit2 {
}

/// @notice Transfer tokens using permit2.
/// @param witness - the pre-hashed witness field.
/// @param _witness - the hashed witness and its typestring.
/// @param permit2 - the Permit2 information.
function _permitWitnessTransferFrom(bytes32 witness, bool isEnter, Permit2 calldata permit2) internal {
function _permitWitnessTransferFrom(Witness memory _witness, Permit2 calldata permit2) internal {
ISignatureTransfer(permit2Contract).permitWitnessTransferFrom(
permit2.permit,
_passageTransferDetails(permit2.permit.permitted),
permit2.owner,
witness,
isEnter ? _ENTER_WITNESS_TYPESTRING : _EXIT_WITNESS_TYPESTRING,
_witness.witnessHash,
_witness.witnessTypeString,
permit2.signature
);
}

/// @notice Encode & hash the rollupChainId and rollupRecipient for use as a permit2 witness.
/// @return witness - the encoded witness field.
function _enterWitness(uint256 rollupChainId, address rollupRecipient) internal pure returns (bytes32 witness) {
witness = keccak256(abi.encode(_ENTER_WITNESS_TYPEHASH, EnterWitness(rollupChainId, rollupRecipient)));
/// @return _witness - the hashed witness and its typestring.
function enterWitness(uint256 rollupChainId, address rollupRecipient)
public
pure
returns (Witness memory _witness)
{
_witness.witnessHash =
keccak256(abi.encode(_ENTER_WITNESS_TYPEHASH, EnterWitness(rollupChainId, rollupRecipient)));
_witness.witnessTypeString = _ENTER_WITNESS_TYPESTRING;
}

/// @notice Hash the hostRecipient for use as a permit2 witness.
/// @return witness - the encoded witness field.
function _exitWitness(address hostRecipient) internal pure returns (bytes32 witness) {
witness = keccak256(abi.encode(_EXIT_WITNESS_TYPEHASH, ExitWitness(hostRecipient)));
/// @return _witness - the hashed witness and its typestring.
function exitWitness(address hostRecipient) public pure returns (Witness memory _witness) {
_witness.witnessHash = keccak256(abi.encode(_EXIT_WITNESS_TYPEHASH, ExitWitness(hostRecipient)));
_witness.witnessTypeString = _EXIT_WITNESS_TYPESTRING;
}

/// @notice transform TokenPermissions to TransferDetails, for passing to permit2.
Expand Down
2 changes: 0 additions & 2 deletions test/Passage.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ contract PassageTest is Test {
uint256 gas = 10_000_000;
uint256 maxFeePerGas = 50;

uint256 tokenAdminKey = 123;

event Enter(uint256 indexed rollupChainId, address indexed rollupRecipient, uint256 amount);

event EnterToken(
Expand Down

0 comments on commit 3ea69d2

Please sign in to comment.