// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.7.0 <0.9.0; /** * @title SignatureDecoder - Decodes signatures encoded as bytes * @author Richard Meissner - @rmeissner */ abstract contract SignatureDecoder { /** * @notice Splits signature bytes into `uint8 v, bytes32 r, bytes32 s`. * @dev Make sure to perform a bounds check for @param pos, to avoid out of bounds access on @param signatures * The signature format is a compact form of {bytes32 r}{bytes32 s}{uint8 v} * Compact means uint8 is not padded to 32 bytes. * @param pos Which signature to read. * A prior bounds check of this parameter should be performed, to avoid out of bounds access. * @param signatures Concatenated {r, s, v} signatures. * @return v Recovery ID or Safe signature type. * @return r Output value r of the signature. * @return s Output value s of the signature. */ function signatureSplit(bytes memory signatures, uint256 pos) internal pure returns (uint8 v, bytes32 r, bytes32 s) { /* solhint-disable no-inline-assembly */ /// @solidity memory-safe-assembly assembly { let signaturePos := mul(0x41, pos) r := mload(add(signatures, add(signaturePos, 0x20))) s := mload(add(signatures, add(signaturePos, 0x40))) v := byte(0, mload(add(signatures, add(signaturePos, 0x60)))) } /* solhint-enable no-inline-assembly */ } }