pragmasolidity^0.8.0;import"@openzeppelin/contracts/utils/cryptography/ECDSA.sol";contractSmartWallet{usingECDSAforbytes32;uint32publicvalid=1;//to make AtomSign invalid
addressprivateimmutableoriginal;addresspublicowner;addresspublicbundler;mapping(bytes32=>bool)publicusedMsgHashes;modifieronlyBundler(){require(bundler==msg.sender,"onlyBundler: caller is not the bundler");_;}modifieronlyOwnerAndOriginal(){require(owner==msg.sender||original==msg.sender,"onlyOwnerAndOriginal: caller is not the owner");_;}constructor(address_bundler){original=address(this);owner=msg.sender;bundler=_bundler;}functionatomSignCall(bytescalldataatomCallbytes,uint32deadline,bytescalldatasignature)externalonlyBundler{require(deadline>=block.timestamp,"atomSignCall: Expired");bytes32msgHash=keccak256(bytes.concat(msg.data[:msg.data.length-signature.length-32],bytes32(block.chainid),bytes20(address(this)),bytes4(valid)));require(!usedMsgHashes[msgHash],"atomSignCall: Used msgHash");require(owner==msgHash.toEthSignedMessageHash().recover(signature),"atomSignCall: Invalid Signature");//do calls
//执行调用
uinti;while(i<atomCallbytes.length){addressto=address(uint160(bytes20(atomCallbytes[i:i+20])));uintvalue=uint(bytes32(atomCallbytes[i+20:i+52]));uintlen=uint(bytes32(atomCallbytes[i+52:i+84]));(boolsuccess,bytesmemoryresult)=to.call{value:value}(atomCallbytes[i+84:i+84+len]);if(!success){assembly{revert(add(result,32),mload(result))}}i+=84+len;}usedMsgHashes[msgHash]=true;}/**
* if you signed something then regretted, make it invalid
* 如果你签署了某些内容然后后悔了,使其无效
*/functionmakeAtomSignInvalid()publiconlyOwnerAndOriginal{valid=uint32(uint(blockhash(block.number)));}}
Bundler.sol
pragmasolidity^0.8.0;contractBundler{addresspublicowner;modifieronlyOwner(){require(owner==msg.sender,"onlyOwner: caller is not the owner");_;}constructor(){owner=msg.sender;}functionexecuteOperation(addresswallet,bytescalldatadata)publiconlyOwner{(boolsuccess,bytesmemoryresult)=_callTo.call{value:0}(data);if(!success){assembly{revert(add(result,32),mload(result))}}}}