// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./IDBIS_EIP712Helper.sol"; /** * @title DBIS_EIP712Helper * @notice Helper contract for EIP-712 hashing and ecrecover (own stack when called). */ contract DBIS_EIP712Helper is IDBIS_EIP712Helper { function hashAddressArray(address[] calldata arr) external pure override returns (bytes32) { bytes32[] memory hashes = new bytes32[](arr.length); for (uint256 i = 0; i < arr.length; i++) { hashes[i] = keccak256(abi.encode(arr[i])); } return keccak256(abi.encodePacked(hashes)); } function hashUint256Array(uint256[] calldata arr) external pure override returns (bytes32) { bytes32[] memory hashes = new bytes32[](arr.length); for (uint256 i = 0; i < arr.length; i++) { hashes[i] = keccak256(abi.encode(arr[i])); } return keccak256(abi.encodePacked(hashes)); } function getMintAuthStructHash( bytes32 typeHash, bytes32 messageId, bytes32 isoType, bytes32 isoHash, bytes32 accountingRef, uint8 fundsStatus, bytes32 corridor, uint8 assetClass, bytes32 recipientsHash, bytes32 amountsHash, uint64 notBefore, uint64 expiresAt, uint256 chainId, address verifyingContract ) external pure override returns (bytes32) { return keccak256(abi.encode( typeHash, messageId, isoType, isoHash, accountingRef, fundsStatus, corridor, assetClass, recipientsHash, amountsHash, notBefore, expiresAt, chainId, verifyingContract )); } function getDigest(bytes32 domainSeparator, bytes32 structHash) external pure override returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } function recover(bytes32 digest, bytes calldata signature) external pure override returns (address) { return _recover(digest, signature); } function recoverSigners(bytes32 digest, bytes[] calldata signatures) external pure override returns (address[] memory signers) { uint256 n = signatures.length; signers = new address[](n); unchecked { for (uint256 i; i < n; i++) { signers[i] = _recover(digest, signatures[i]); } } } function getSwapAuthDigest( bytes32 domainSeparator, bytes32 typeHash, bytes32 messageId, bytes32 lpaId, bytes32 venue, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, uint256 deadline, bytes32 quoteHash, address quoteIssuer, uint256 chainId, address verifyingContract ) external pure override returns (bytes32) { bytes32 structHash = keccak256(abi.encode( typeHash, messageId, lpaId, venue, tokenIn, tokenOut, amountIn, minAmountOut, deadline, quoteHash, quoteIssuer, chainId, verifyingContract )); return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } function _recover(bytes32 digest, bytes calldata signature) private pure returns (address) { require(signature.length == 65, "DBIS: sig length"); bytes32 r; bytes32 s; uint8 v; assembly { r := calldataload(signature.offset) s := calldataload(add(signature.offset, 32)) v := byte(0, calldataload(add(signature.offset, 64))) } if (v < 27) v += 27; require(v == 27 || v == 28, "DBIS: invalid v"); return ecrecover(digest, v, r, s); } }