// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; library GhostPacking { struct RotationBits { uint128 xorKey; uint128 bitMask; } struct GovernancePayload { uint64 chainId; address target; } struct RequestPayload { uint32 bounty; uint64 chainId; address receiver; } function pack(uint128 xorKey, uint128 bitMask) internal pure returns (uint256 packed) { packed = (uint256(xorKey) << 128) | uint256(bitMask); } function pack(RotationBits calldata state) internal pure returns (uint256 packed) { packed = pack(state.xorKey, state.bitMask); } function unpackRotationBits(uint256 packed) internal pure returns (RotationBits memory state) { // forge-lint: disable-next-line(unsafe-typecast) state.xorKey = uint128(packed >> 128); // forge-lint: disable-next-line(unsafe-typecast) state.bitMask = uint128(packed & 0xFFFFFFFFFFFFFFFFffffffffffffffff); } function pack(uint64 chainId, address target) internal pure returns (uint256 packed) { packed = (uint256(chainId) << 192) | (uint256(uint160(target)) << 32); } function pack(GovernancePayload calldata data) internal pure returns (uint256 packed) { packed = pack(data.chainId, data.target); } function unpackGovernance(uint256 packed) internal pure returns (GovernancePayload memory state) { // forge-lint: disable-next-line(unsafe-typecast) state.target = address(uint160(packed >> 32)); // forge-lint: disable-next-line(unsafe-typecast) state.chainId = uint64(packed >> 192); } function pack(uint32 bounty, uint64 chainId, address receiver) internal pure returns (uint256 packed) { packed = (uint256(uint160(receiver)) << 96) | (uint256(chainId) << 32) | uint256(bounty); } function pack(RequestPayload calldata data) internal pure returns (uint256 packed) { packed = pack(data.bounty, data.chainId, data.receiver); } function unpackRequest(uint256 packed) internal pure returns (RequestPayload memory state) { // forge-lint: disable-next-line(unsafe-typecast) state.bounty = uint32(packed & 0xFFFFFFFF); // forge-lint: disable-next-line(unsafe-typecast) state.chainId = uint64((packed >> 32) & 0xFFFFFFFFFFFFFFFF); // forge-lint: disable-next-line(unsafe-typecast) state.receiver = address(uint160(packed >> 96)); } }