编译器
0.8.18+commit.87f61d96
文件 1 的 22:GuestModule.sol
pragma solidity 0.8.18;
import "../utils/LibOptim.sol";
import "./commons/submodules/auth/SequenceBaseSig.sol";
import "./commons/ModuleAuth.sol";
import "./commons/ModuleCalls.sol";
import "./commons/ModuleCreator.sol";
contract GuestModule is
ModuleAuth,
ModuleCalls,
ModuleCreator
{
error DelegateCallNotAllowed(uint256 _index);
error NotSupported();
function execute(
Transaction[] calldata _txs,
uint256,
bytes calldata
) public override {
bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode('guest:', _txs)));
_executeGuest(txHash, _txs);
}
function selfExecute(
Transaction[] calldata _txs
) public override {
bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode('self:', _txs)));
_executeGuest(txHash, _txs);
}
function _executeGuest(
bytes32 _txHash,
Transaction[] calldata _txs
) private {
uint256 size = _txs.length;
for (uint256 i = 0; i < size; i++) {
Transaction calldata transaction = _txs[i];
if (transaction.delegateCall) revert DelegateCallNotAllowed(i);
uint256 gasLimit = transaction.gasLimit;
if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft());
bool success = LibOptim.call(
transaction.target,
transaction.value,
gasLimit == 0 ? gasleft() : gasLimit,
transaction.data
);
if (success) {
emit TxExecuted(_txHash, i);
} else {
_revertBytes(
transaction.revertOnError,
_txHash,
i,
LibOptim.returnData()
);
}
}
}
function _isValidImage(bytes32) internal override pure returns (bool) {
return true;
}
function _updateImageHash(bytes32) internal override virtual {
revert NotSupported();
}
function supportsInterface(
bytes4 _interfaceID
) public override (
ModuleAuth,
ModuleCalls,
ModuleCreator
) pure returns (bool) {
return super.supportsInterface(_interfaceID);
}
}
文件 2 的 22:IERC1271Wallet.sol
pragma solidity 0.8.18;
interface IERC1271Wallet {
function isValidSignature(
bytes calldata _data,
bytes calldata _signature)
external
view
returns (bytes4 magicValue);
function isValidSignature(
bytes32 _hash,
bytes calldata _signature)
external
view
returns (bytes4 magicValue);
}
文件 3 的 22:IModuleAuth.sol
pragma solidity 0.8.18;
abstract contract IModuleAuth {
bytes32 internal constant IMAGE_HASH_KEY = bytes32(0xea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8);
event ImageHashUpdated(bytes32 newImageHash);
error ImageHashIsZero();
error InvalidSignatureType(bytes1 _type);
function _signatureValidation(
bytes32 _digest,
bytes calldata _signature
) internal virtual view returns (
bool isValid,
bytes32 subdigest
);
function signatureRecovery(
bytes32 _digest,
bytes calldata _signature
) public virtual view returns (
uint256 threshold,
uint256 weight,
bytes32 imageHash,
bytes32 subdigest,
uint256 checkpoint
);
function _isValidImage(bytes32) internal virtual view returns (bool) {
return false;
}
function updateImageHash(bytes32 _imageHash) external virtual;
function _updateImageHash(bytes32 _imageHash) internal virtual;
}
文件 4 的 22:IModuleCalls.sol
pragma solidity 0.8.18;
interface IModuleCalls {
event TxFailed(bytes32 indexed _tx, uint256 _index, bytes _reason);
event TxExecuted(bytes32 indexed _tx, uint256 _index);
error NotEnoughGas(uint256 _index, uint256 _requested, uint256 _available);
error InvalidSignature(bytes32 _hash, bytes _signature);
struct Transaction {
bool delegateCall;
bool revertOnError;
uint256 gasLimit;
address target;
uint256 value;
bytes data;
}
function execute(
Transaction[] calldata _txs,
uint256 _nonce,
bytes calldata _signature
) external;
function selfExecute(
Transaction[] calldata _txs
) external;
}
文件 5 的 22:IModuleCreator.sol
pragma solidity 0.8.18;
interface IModuleCreator {
error CreateFailed(bytes _code);
function createContract(bytes calldata _code) external payable returns (address addr);
}
文件 6 的 22:LibBytes.sol
pragma solidity 0.8.18;
library LibBytes {
function readBytes32(
bytes calldata data,
uint256 index
) internal pure returns (
bytes32 a
) {
assembly {
a := calldataload(add(data.offset, index))
}
}
function readUint8(
bytes calldata data,
uint256 index
) internal pure returns (
uint8 a
) {
assembly {
let word := calldataload(add(index, data.offset))
a := shr(248, word)
}
}
function readFirstUint16(
bytes calldata data
) internal pure returns (
uint16 a
) {
assembly {
let word := calldataload(data.offset)
a := shr(240, word)
}
}
function readUint32(
bytes calldata data,
uint256 index
) internal pure returns (
uint32 a
) {
assembly {
let word := calldataload(add(index, data.offset))
a := shr(224, word)
}
}
}
文件 7 的 22:LibBytesPointer.sol
pragma solidity 0.8.18;
library LibBytesPointer {
function readFirstUint16(
bytes calldata _data
) internal pure returns (
uint16 a,
uint256 newPointer
) {
assembly {
let word := calldataload(_data.offset)
a := shr(240, word)
newPointer := 2
}
}
function readUint8(
bytes calldata _data,
uint256 _index
) internal pure returns (
uint8 a,
uint256 newPointer
) {
assembly {
let word := calldataload(add(_index, _data.offset))
a := shr(248, word)
newPointer := add(_index, 1)
}
}
function readUint8Address(
bytes calldata _data,
uint256 _index
) internal pure returns (
uint8 a,
address b,
uint256 newPointer
) {
assembly {
let word := calldataload(add(_index, _data.offset))
a := shr(248, word)
b := and(shr(88, word), 0xffffffffffffffffffffffffffffffffffffffff)
newPointer := add(_index, 21)
}
}
function readUint16(
bytes calldata _data,
uint256 _index
) internal pure returns (
uint16 a,
uint256 newPointer
) {
assembly {
let word := calldataload(add(_index, _data.offset))
a := and(shr(240, word), 0xffff)
newPointer := add(_index, 2)
}
}
function readUint24(
bytes calldata _data,
uint256 _index
) internal pure returns (
uint24 a,
uint256 newPointer
) {
assembly {
let word := calldataload(add(_index, _data.offset))
a := and(shr(232, word), 0xffffff)
newPointer := add(_index, 3)
}
}
function readUint64(
bytes calldata _data,
uint256 _index
) internal pure returns (
uint64 a,
uint256 newPointer
) {
assembly {
let word := calldataload(add(_index, _data.offset))
a := and(shr(192, word), 0xffffffffffffffff)
newPointer := add(_index, 8)
}
}
function readBytes32(
bytes calldata _data,
uint256 _pointer
) internal pure returns (
bytes32 a,
uint256 newPointer
) {
assembly {
a := calldataload(add(_pointer, _data.offset))
newPointer := add(_pointer, 32)
}
}
}
文件 8 的 22:LibOptim.sol
pragma solidity 0.8.18;
library LibOptim {
function fkeccak256(
bytes32 _a,
bytes32 _b
) internal pure returns (bytes32 c) {
assembly {
mstore(0, _a)
mstore(32, _b)
c := keccak256(0, 64)
}
}
function returnData() internal pure returns (bytes memory r) {
assembly {
let size := returndatasize()
r := mload(0x40)
let start := add(r, 32)
mstore(0x40, add(start, size))
mstore(r, size)
returndatacopy(start, 0, size)
}
}
function call(
address _to,
uint256 _val,
uint256 _gas,
bytes calldata _data
) internal returns (bool r) {
assembly {
let tmp := mload(0x40)
calldatacopy(tmp, _data.offset, _data.length)
r := call(
_gas,
_to,
_val,
tmp,
_data.length,
0,
0
)
}
}
function delegatecall(
address _to,
uint256 _gas,
bytes calldata _data
) internal returns (bool r) {
assembly {
let tmp := mload(0x40)
calldatacopy(tmp, _data.offset, _data.length)
r := delegatecall(
_gas,
_to,
tmp,
_data.length,
0,
0
)
}
}
}
文件 9 的 22:ModuleAuth.sol
pragma solidity 0.8.18;
import "../../utils/LibBytes.sol";
import "../../interfaces/IERC1271Wallet.sol";
import "./interfaces/IModuleAuth.sol";
import "./ModuleERC165.sol";
import "./submodules/auth/SequenceBaseSig.sol";
import "./submodules/auth/SequenceDynamicSig.sol";
import "./submodules/auth/SequenceNoChainIdSig.sol";
import "./submodules/auth/SequenceChainedSig.sol";
abstract contract ModuleAuth is
IModuleAuth,
ModuleERC165,
IERC1271Wallet,
SequenceChainedSig
{
using LibBytes for bytes;
bytes1 internal constant LEGACY_TYPE = hex"00";
bytes1 internal constant DYNAMIC_TYPE = hex"01";
bytes1 internal constant NO_CHAIN_ID_TYPE = hex"02";
bytes1 internal constant CHAINED_TYPE = hex"03";
bytes4 internal constant SELECTOR_ERC1271_BYTES_BYTES = 0x20c13b0b;
bytes4 internal constant SELECTOR_ERC1271_BYTES32_BYTES = 0x1626ba7e;
function signatureRecovery(
bytes32 _digest,
bytes calldata _signature
) public override virtual view returns (
uint256 threshold,
uint256 weight,
bytes32 imageHash,
bytes32 subdigest,
uint256 checkpoint
) {
bytes1 signatureType = _signature[0];
if (signatureType == LEGACY_TYPE) {
subdigest = SequenceBaseSig.subdigest(_digest);
(threshold, weight, imageHash, checkpoint) = SequenceBaseSig.recover(subdigest, _signature);
return (threshold, weight, imageHash, subdigest, checkpoint);
}
if (signatureType == DYNAMIC_TYPE) {
subdigest = SequenceBaseSig.subdigest(_digest);
(threshold, weight, imageHash, checkpoint) = SequenceDynamicSig.recover(subdigest, _signature);
return (threshold, weight, imageHash, subdigest, checkpoint);
}
if (signatureType == NO_CHAIN_ID_TYPE) {
subdigest = SequenceNoChainIdSig.subdigest(_digest);
(threshold, weight, imageHash, checkpoint) = SequenceDynamicSig.recover(subdigest, _signature);
return (threshold, weight, imageHash, subdigest, checkpoint);
}
if (signatureType == CHAINED_TYPE) {
return chainedRecover(_digest, _signature);
}
revert InvalidSignatureType(signatureType);
}
function _signatureValidation(
bytes32 _digest,
bytes calldata _signature
) internal override virtual view returns (
bool isValid,
bytes32 subdigest
) {
uint256 threshold; uint256 weight; bytes32 imageHash;
(threshold, weight, imageHash, subdigest,) = signatureRecovery(_digest, _signature);
isValid = weight >= threshold && _isValidImage(imageHash);
}
function isValidSignature(
bytes calldata _data,
bytes calldata _signatures
) public override virtual view returns (bytes4) {
(bool isValid,) = _signatureValidation(keccak256(_data), _signatures);
if (isValid) {
return SELECTOR_ERC1271_BYTES_BYTES;
}
return bytes4(0);
}
function isValidSignature(
bytes32 _hash,
bytes calldata _signatures
) public override virtual view returns (bytes4) {
(bool isValid,) = _signatureValidation(_hash, _signatures);
if (isValid) {
return SELECTOR_ERC1271_BYTES32_BYTES;
}
return bytes4(0);
}
function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {
if (
_interfaceID == type(IModuleAuth).interfaceId ||
_interfaceID == type(IERC1271Wallet).interfaceId
) {
return true;
}
return super.supportsInterface(_interfaceID);
}
function updateImageHash(bytes32 _imageHash) external override virtual onlySelf {
_updateImageHash(_imageHash);
}
}
文件 10 的 22:ModuleCalls.sol
pragma solidity 0.8.18;
import "./ModuleSelfAuth.sol";
import "./ModuleStorage.sol";
import "./ModuleERC165.sol";
import "./ModuleNonce.sol";
import "./ModuleOnlyDelegatecall.sol";
import "./interfaces/IModuleCalls.sol";
import "./interfaces/IModuleAuth.sol";
import "./submodules/nonce/SubModuleNonce.sol";
import "./submodules/auth/SequenceBaseSig.sol";
import "../../utils/LibOptim.sol";
abstract contract ModuleCalls is IModuleCalls, IModuleAuth, ModuleERC165, ModuleOnlyDelegatecall, ModuleSelfAuth, ModuleNonce {
function execute(
Transaction[] calldata _txs,
uint256 _nonce,
bytes calldata _signature
) external override virtual onlyDelegatecall {
_validateNonce(_nonce);
(bool isValid, bytes32 txHash) = _signatureValidation(
keccak256(
abi.encode(
_nonce,
_txs
)
),
_signature
);
if (!isValid) {
revert InvalidSignature(txHash, _signature);
}
_execute(txHash, _txs);
}
function selfExecute(
Transaction[] calldata _txs
) external override virtual onlySelf {
bytes32 txHash = SequenceBaseSig.subdigest(
keccak256(
abi.encode('self:', _txs)
)
);
_execute(txHash, _txs);
}
function _execute(
bytes32 _txHash,
Transaction[] calldata _txs
) private {
unchecked {
uint256 size = _txs.length;
for (uint256 i = 0; i < size; i++) {
Transaction calldata transaction = _txs[i];
uint256 gasLimit = transaction.gasLimit;
if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft());
bool success;
if (transaction.delegateCall) {
success = LibOptim.delegatecall(
transaction.target,
gasLimit == 0 ? gasleft() : gasLimit,
transaction.data
);
} else {
success = LibOptim.call(
transaction.target,
transaction.value,
gasLimit == 0 ? gasleft() : gasLimit,
transaction.data
);
}
if (success) {
emit TxExecuted(_txHash, i);
} else {
_revertBytes(
transaction.revertOnError,
_txHash,
i,
LibOptim.returnData()
);
}
}
}
}
function _revertBytes(
bool _revertOnError,
bytes32 _txHash,
uint256 _index,
bytes memory _reason
) internal {
if (_revertOnError) {
assembly { revert(add(_reason, 0x20), mload(_reason)) }
} else {
emit TxFailed(_txHash, _index, _reason);
}
}
function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {
if (_interfaceID == type(IModuleCalls).interfaceId) {
return true;
}
return super.supportsInterface(_interfaceID);
}
}
文件 11 的 22:ModuleCreator.sol
pragma solidity 0.8.18;
import "./interfaces/IModuleCreator.sol";
import "./ModuleSelfAuth.sol";
import "./ModuleERC165.sol";
contract ModuleCreator is IModuleCreator, ModuleERC165, ModuleSelfAuth {
event CreatedContract(address _contract);
function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {
assembly { addr := create(callvalue(), add(_code, 32), mload(_code)) }
if (addr == address(0)) revert CreateFailed(_code);
emit CreatedContract(addr);
}
function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {
if (_interfaceID == type(IModuleCreator).interfaceId) {
return true;
}
return super.supportsInterface(_interfaceID);
}
}
文件 12 的 22:ModuleERC165.sol
pragma solidity 0.8.18;
abstract contract ModuleERC165 {
function supportsInterface(bytes4 _interfaceID) virtual public pure returns (bool) {
return _interfaceID == this.supportsInterface.selector;
}
}
文件 13 的 22:ModuleNonce.sol
pragma solidity 0.8.18;
import "./ModuleStorage.sol";
import "./submodules/nonce/SubModuleNonce.sol";
contract ModuleNonce {
event NonceChange(uint256 _space, uint256 _newNonce);
error BadNonce(uint256 _space, uint256 _provided, uint256 _current);
bytes32 private constant NONCE_KEY = bytes32(0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e);
function nonce() external virtual view returns (uint256) {
return readNonce(0);
}
function readNonce(uint256 _space) public virtual view returns (uint256) {
return uint256(ModuleStorage.readBytes32Map(NONCE_KEY, bytes32(_space)));
}
function _writeNonce(uint256 _space, uint256 _nonce) internal {
ModuleStorage.writeBytes32Map(NONCE_KEY, bytes32(_space), bytes32(_nonce));
}
function _validateNonce(uint256 _rawNonce) internal virtual {
(uint256 space, uint256 providedNonce) = SubModuleNonce.decodeNonce(_rawNonce);
uint256 currentNonce = readNonce(space);
if (currentNonce != providedNonce) {
revert BadNonce(space, providedNonce, currentNonce);
}
unchecked {
uint256 newNonce = providedNonce + 1;
_writeNonce(space, newNonce);
emit NonceChange(space, newNonce);
return;
}
}
}
文件 14 的 22:ModuleOnlyDelegatecall.sol
pragma solidity 0.8.18;
contract ModuleOnlyDelegatecall {
address private immutable self;
error OnlyDelegatecall();
constructor() {
self = address(this);
}
modifier onlyDelegatecall() {
if (address(this) == self) {
revert OnlyDelegatecall();
}
_;
}
}
文件 15 的 22:ModuleSelfAuth.sol
pragma solidity 0.8.18;
contract ModuleSelfAuth {
error OnlySelfAuth(address _sender, address _self);
modifier onlySelf() {
if (msg.sender != address(this)) {
revert OnlySelfAuth(msg.sender, address(this));
}
_;
}
}
文件 16 的 22:ModuleStorage.sol
pragma solidity 0.8.18;
library ModuleStorage {
function writeBytes32(bytes32 _key, bytes32 _val) internal {
assembly { sstore(_key, _val) }
}
function readBytes32(bytes32 _key) internal view returns (bytes32 val) {
assembly { val := sload(_key) }
}
function writeBytes32Map(bytes32 _key, bytes32 _subKey, bytes32 _val) internal {
bytes32 key = keccak256(abi.encode(_key, _subKey));
assembly { sstore(key, _val) }
}
function readBytes32Map(bytes32 _key, bytes32 _subKey) internal view returns (bytes32 val) {
bytes32 key = keccak256(abi.encode(_key, _subKey));
assembly { val := sload(key) }
}
}
文件 17 的 22:SequenceBaseSig.sol
pragma solidity 0.8.18;
import "../../../../utils/SignatureValidator.sol";
import "../../../../utils/LibBytesPointer.sol";
import "../../../../utils/LibBytes.sol";
import "../../../../utils/LibOptim.sol";
library SequenceBaseSig {
using LibBytesPointer for bytes;
uint256 private constant FLAG_SIGNATURE = 0;
uint256 private constant FLAG_ADDRESS = 1;
uint256 private constant FLAG_DYNAMIC_SIGNATURE = 2;
uint256 private constant FLAG_NODE = 3;
uint256 private constant FLAG_BRANCH = 4;
uint256 private constant FLAG_SUBDIGEST = 5;
uint256 private constant FLAG_NESTED = 6;
error InvalidNestedSignature(bytes32 _hash, address _addr, bytes _signature);
error InvalidSignatureFlag(uint256 _flag);
function subdigest(
bytes32 _digest
) internal view returns (bytes32) {
return keccak256(
abi.encodePacked(
"\x19\x01",
block.chainid,
address(this),
_digest
)
);
}
function _leafForAddressAndWeight(
address _addr,
uint96 _weight
) internal pure returns (bytes32) {
unchecked {
return bytes32(uint256(_weight) << 160 | uint256(uint160(_addr)));
}
}
function _leafForHardcodedSubdigest(
bytes32 _subdigest
) internal pure returns (bytes32) {
return keccak256(abi.encodePacked('Sequence static digest:\n', _subdigest));
}
function _leafForNested(
bytes32 _node,
uint256 _threshold,
uint256 _weight
) internal pure returns (bytes32) {
return keccak256(abi.encodePacked('Sequence nested config:\n', _node, _threshold, _weight));
}
function recoverBranch(
bytes32 _subdigest,
bytes calldata _signature
) internal view returns (
uint256 weight,
bytes32 root
) {
unchecked {
uint256 rindex;
while (rindex < _signature.length) {
uint256 flag;
(flag, rindex) = _signature.readUint8(rindex);
if (flag == FLAG_ADDRESS) {
uint8 addrWeight; address addr;
(addrWeight, addr, rindex) = _signature.readUint8Address(rindex);
bytes32 node = _leafForAddressAndWeight(addr, addrWeight);
root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;
continue;
}
if (flag == FLAG_SIGNATURE) {
uint8 addrWeight;
(addrWeight, rindex) = _signature.readUint8(rindex);
uint256 nrindex = rindex + 66;
address addr = SignatureValidator.recoverSigner(_subdigest, _signature[rindex:nrindex]);
rindex = nrindex;
weight += addrWeight;
bytes32 node = _leafForAddressAndWeight(addr, addrWeight);
root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;
continue;
}
if (flag == FLAG_DYNAMIC_SIGNATURE) {
uint8 addrWeight; address addr;
(addrWeight, addr, rindex) = _signature.readUint8Address(rindex);
uint256 size;
(size, rindex) = _signature.readUint24(rindex);
uint256 nrindex = rindex + size;
if (!SignatureValidator.isValidSignature(_subdigest, addr, _signature[rindex:nrindex])) {
revert InvalidNestedSignature(_subdigest, addr, _signature[rindex:nrindex]);
}
rindex = nrindex;
weight += addrWeight;
bytes32 node = _leafForAddressAndWeight(addr, addrWeight);
root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;
continue;
}
if (flag == FLAG_NODE) {
bytes32 node;
(node, rindex) = _signature.readBytes32(rindex);
root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;
continue;
}
if (flag == FLAG_BRANCH) {
uint256 size;
(size, rindex) = _signature.readUint24(rindex);
uint256 nrindex = rindex + size;
uint256 nweight; bytes32 node;
(nweight, node) = recoverBranch(_subdigest, _signature[rindex:nrindex]);
weight += nweight;
root = LibOptim.fkeccak256(root, node);
rindex = nrindex;
continue;
}
if (flag == FLAG_NESTED) {
uint256 externalWeight;
(externalWeight, rindex) = _signature.readUint8(rindex);
uint256 internalThreshold;
(internalThreshold, rindex) = _signature.readUint16(rindex);
uint256 size;
(size, rindex) = _signature.readUint24(rindex);
uint256 nrindex = rindex + size;
uint256 internalWeight; bytes32 internalRoot;
(internalWeight, internalRoot) = recoverBranch(_subdigest, _signature[rindex:nrindex]);
rindex = nrindex;
if (internalWeight >= internalThreshold) {
weight += externalWeight;
}
bytes32 node = _leafForNested(internalRoot, internalThreshold, externalWeight);
root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;
continue;
}
if (flag == FLAG_SUBDIGEST) {
bytes32 hardcoded;
(hardcoded, rindex) = _signature.readBytes32(rindex);
if (hardcoded == _subdigest) {
weight = type(uint256).max;
}
bytes32 node = _leafForHardcodedSubdigest(hardcoded);
root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;
continue;
}
revert InvalidSignatureFlag(flag);
}
}
}
function recover(
bytes32 _subdigest,
bytes calldata _signature
) internal view returns (
uint256 threshold,
uint256 weight,
bytes32 imageHash,
uint256 checkpoint
) {
unchecked {
(weight, imageHash) = recoverBranch(_subdigest, _signature[6:]);
threshold = LibBytes.readFirstUint16(_signature);
checkpoint = LibBytes.readUint32(_signature, 2);
imageHash = LibOptim.fkeccak256(imageHash, bytes32(threshold));
imageHash = LibOptim.fkeccak256(imageHash, bytes32(checkpoint));
}
}
}
文件 18 的 22:SequenceChainedSig.sol
pragma solidity 0.8.18;
import "./SequenceBaseSig.sol";
import "../../interfaces/IModuleAuth.sol";
import "../../ModuleSelfAuth.sol";
import "../../ModuleStorage.sol";
import "../../../../utils/LibBytesPointer.sol";
import "../../../../utils/LibOptim.sol";
abstract contract SequenceChainedSig is IModuleAuth, ModuleSelfAuth {
using LibBytesPointer for bytes;
bytes32 public constant SET_IMAGE_HASH_TYPE_HASH = keccak256("SetImageHash(bytes32 imageHash)");
error LowWeightChainedSignature(bytes _signature, uint256 threshold, uint256 _weight);
error WrongChainedCheckpointOrder(uint256 _current, uint256 _prev);
function _hashSetImageHashStruct(bytes32 _imageHash) internal pure returns (bytes32) {
return LibOptim.fkeccak256(SET_IMAGE_HASH_TYPE_HASH, _imageHash);
}
function chainedRecover(
bytes32 _digest,
bytes calldata _signature
) internal view returns (
uint256 threshold,
uint256 weight,
bytes32 imageHash,
bytes32 subdigest,
uint256 checkpoint
) {
uint256 rindex = 1;
uint256 sigSize;
(sigSize, rindex) = _signature.readUint24(rindex);
uint256 nrindex = sigSize + rindex;
(
threshold,
weight,
imageHash,
subdigest,
checkpoint
) = signatureRecovery(
_digest,
_signature[rindex:nrindex]
);
if (weight < threshold) {
revert LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight);
}
rindex = nrindex;
while (rindex < _signature.length) {
(sigSize, rindex) = _signature.readUint24(rindex);
nrindex = sigSize + rindex;
uint256 nextCheckpoint;
(
threshold,
weight,
imageHash,,
nextCheckpoint
) = signatureRecovery(
_hashSetImageHashStruct(imageHash),
_signature[rindex:nrindex]
);
if (weight < threshold) {
revert LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight);
}
if (nextCheckpoint >= checkpoint) {
revert WrongChainedCheckpointOrder(nextCheckpoint, checkpoint);
}
checkpoint = nextCheckpoint;
rindex = nrindex;
}
}
}
文件 19 的 22:SequenceDynamicSig.sol
pragma solidity 0.8.18;
import "./SequenceBaseSig.sol";
library SequenceDynamicSig {
function recover(
bytes32 _subdigest,
bytes calldata _signature
) internal view returns (
uint256 threshold,
uint256 weight,
bytes32 imageHash,
uint256 checkpoint
) {
return SequenceBaseSig.recover(_subdigest, _signature[1:]);
}
}
文件 20 的 22:SequenceNoChainIdSig.sol
pragma solidity 0.8.18;
library SequenceNoChainIdSig {
function subdigest(bytes32 _digest) internal view returns (bytes32) {
return keccak256(
abi.encodePacked(
"\x19\x01",
uint256(0),
address(this),
_digest
)
);
}
}
文件 21 的 22:SignatureValidator.sol
pragma solidity 0.8.18;
import "../interfaces/IERC1271Wallet.sol";
import "./LibBytes.sol";
library SignatureValidator {
error InvalidSignatureLength(bytes _signature);
error EmptySignature();
error InvalidSValue(bytes _signature, bytes32 _s);
error InvalidVValue(bytes _signature, uint256 _v);
error UnsupportedSignatureType(bytes _signature, uint256 _type, bool _recoverMode);
error SignerIsAddress0(bytes _signature);
using LibBytes for bytes;
bytes4 constant internal ERC1271_MAGICVALUE = 0x20c13b0b;
bytes4 constant internal ERC1271_MAGICVALUE_BYTES32 = 0x1626ba7e;
uint256 private constant SIG_TYPE_EIP712 = 1;
uint256 private constant SIG_TYPE_ETH_SIGN = 2;
uint256 private constant SIG_TYPE_WALLET_BYTES32 = 3;
function recoverSigner(
bytes32 _hash,
bytes calldata _signature
) internal pure returns (address signer) {
if (_signature.length != 66) revert InvalidSignatureLength(_signature);
uint256 signatureType = _signature.readUint8(_signature.length - 1);
uint8 v = _signature.readUint8(64);
bytes32 r = _signature.readBytes32(0);
bytes32 s = _signature.readBytes32(32);
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
revert InvalidSValue(_signature, s);
}
if (v != 27 && v != 28) {
revert InvalidVValue(_signature, v);
}
if (signatureType == SIG_TYPE_EIP712) {
signer = ecrecover(_hash, v, r, s);
} else if (signatureType == SIG_TYPE_ETH_SIGN) {
signer = ecrecover(
keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)),
v,
r,
s
);
} else {
revert UnsupportedSignatureType(_signature, signatureType, true);
}
if (signer == address(0x0)) revert SignerIsAddress0(_signature);
return signer;
}
function isValidSignature(
bytes32 _hash,
address _signer,
bytes calldata _signature
) internal view returns (bool valid) {
if (_signature.length == 0) {
revert EmptySignature();
}
uint256 signatureType = uint8(_signature[_signature.length - 1]);
if (signatureType == SIG_TYPE_EIP712 || signatureType == SIG_TYPE_ETH_SIGN) {
valid = recoverSigner(_hash, _signature) == _signer;
} else if (signatureType == SIG_TYPE_WALLET_BYTES32) {
valid = ERC1271_MAGICVALUE_BYTES32 == IERC1271Wallet(_signer).isValidSignature(_hash, _signature[0:_signature.length - 1]);
} else {
revert UnsupportedSignatureType(_signature, signatureType, false);
}
}
}
文件 22 的 22:SubModuleNonce.sol
pragma solidity 0.8.18;
library SubModuleNonce {
uint256 internal constant NONCE_BITS = 96;
bytes32 internal constant NONCE_MASK = bytes32(uint256(type(uint96).max));
function decodeNonce(uint256 _rawNonce) internal pure returns (
uint256 _space,
uint256 _nonce
) {
unchecked {
_space = _rawNonce >> NONCE_BITS;
_nonce = uint256(bytes32(_rawNonce) & NONCE_MASK);
}
}
}
{
"compilationTarget": {
"contracts/modules/GuestModule.sol": "GuestModule"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 500000
},
"remappings": []
}
[{"inputs":[{"internalType":"uint256","name":"_space","type":"uint256"},{"internalType":"uint256","name":"_provided","type":"uint256"},{"internalType":"uint256","name":"_current","type":"uint256"}],"name":"BadNonce","type":"error"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"}],"name":"CreateFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"DelegateCallNotAllowed","type":"error"},{"inputs":[],"name":"EmptySignature","type":"error"},{"inputs":[],"name":"ImageHashIsZero","type":"error"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"address","name":"_addr","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"InvalidNestedSignature","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"InvalidSValue","type":"error"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"_flag","type":"uint256"}],"name":"InvalidSignatureFlag","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"InvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes1","name":"_type","type":"bytes1"}],"name":"InvalidSignatureType","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"uint256","name":"_v","type":"uint256"}],"name":"InvalidVValue","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"_weight","type":"uint256"}],"name":"LowWeightChainedSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_requested","type":"uint256"},{"internalType":"uint256","name":"_available","type":"uint256"}],"name":"NotEnoughGas","type":"error"},{"inputs":[],"name":"NotSupported","type":"error"},{"inputs":[],"name":"OnlyDelegatecall","type":"error"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_self","type":"address"}],"name":"OnlySelfAuth","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"SignerIsAddress0","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"uint256","name":"_type","type":"uint256"},{"internalType":"bool","name":"_recoverMode","type":"bool"}],"name":"UnsupportedSignatureType","type":"error"},{"inputs":[{"internalType":"uint256","name":"_current","type":"uint256"},{"internalType":"uint256","name":"_prev","type":"uint256"}],"name":"WrongChainedCheckpointOrder","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_contract","type":"address"}],"name":"CreatedContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"newImageHash","type":"bytes32"}],"name":"ImageHashUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_space","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newNonce","type":"uint256"}],"name":"NonceChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_tx","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"}],"name":"TxExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_tx","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"TxFailed","type":"event"},{"inputs":[],"name":"SET_IMAGE_HASH_TYPE_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"}],"name":"createContract","outputs":[{"internalType":"address","name":"addr","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"delegateCall","type":"bool"},{"internalType":"bool","name":"revertOnError","type":"bool"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IModuleCalls.Transaction[]","name":"_txs","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_space","type":"uint256"}],"name":"readNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"delegateCall","type":"bool"},{"internalType":"bool","name":"revertOnError","type":"bool"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IModuleCalls.Transaction[]","name":"_txs","type":"tuple[]"}],"name":"selfExecute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_digest","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"signatureRecovery","outputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"weight","type":"uint256"},{"internalType":"bytes32","name":"imageHash","type":"bytes32"},{"internalType":"bytes32","name":"subdigest","type":"bytes32"},{"internalType":"uint256","name":"checkpoint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_imageHash","type":"bytes32"}],"name":"updateImageHash","outputs":[],"stateMutability":"nonpayable","type":"function"}]