Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions contracts/LockedUserOps.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
pragma solidity 0.8.19;

import {UserOperation} from "contracts/interfaces/UserOperation.sol";
import {IEntryPoint} from "contracts/interfaces/IEntryPoint.sol";

struct LockedOp {
UserOperation userOp;
uint256 expiry;
// uint256 value; // todo
}

contract LockedUserOps {
event UserOpRegistered(bytes32 indexed hashlock, LockedOp userOp);

mapping(bytes32 => LockedOp) public lockedUserOps;
IEntryPoint public entryPoint;

constructor(IEntryPoint _entryPoint) {
entryPoint = _entryPoint;
}

/**
* @dev Register a UserOperation that can be released by the user.
* @param hashlock - Hashlock of the UserOperation
* @param userOp - UserOperation to be registered
*/
function registerUserOp(
bytes32 hashlock,
LockedOp memory userOp
) public payable {
require(userOp.expiry > block.timestamp, "UserOp already expired");
require(lockedUserOps[hashlock].expiry == 0, "UserOp already registered");

lockedUserOps[hashlock] = userOp;
emit UserOpRegistered(hashlock, userOp);
// todo: account for transferred `value`
}

function releaseSHAuserOp(bytes calldata preimage) public {
// check
bytes32 hashlock = sha256(preimage);
LockedOp memory lockedOp = lockedUserOps[hashlock];
require(lockedOp.expiry > 0, "UserOp not found");

// effect
delete lockedUserOps[hashlock];

// interaction
// todo: pass in required `value` / `gas` parameters
executeUserOp(lockedOp.userOp);
}

function releaseUserOp(bytes calldata preimage) public {
// check
bytes32 hashlock = keccak256(preimage);
LockedOp memory lockedOp = lockedUserOps[hashlock];
require(lockedOp.expiry > 0, "UserOp not found");

// effect
delete lockedUserOps[hashlock];

// interaction
// todo: pass in required `value` / `gas` parameters
executeUserOp(lockedOp.userOp);
}

function executeUserOp(UserOperation memory userOp) internal {
UserOperation[] memory ops = new UserOperation[](1);
ops[0] = userOp;
entryPoint.handleOps(ops, payable(msg.sender));
}
}