Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

noto: add "lock" functionality #483

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open

noto: add "lock" functionality #483

wants to merge 29 commits into from

Conversation

awrichar
Copy link
Contributor

@awrichar awrichar commented Dec 17, 2024

Resolves #455
In a chain with #490

Allows an owner to "lock" some portion of value such that it cannot be spent except when specific conditions are met.

New methods on Noto private ABI:

  • lock(bytes32 lockId, uint256 amount, bytes calldata data) - lock some amount of my Noto value and assign it a unique lock ID
  • unlock(bytes32 lockId, string calldata from, string[] calldata to, uint256[] calldata amounts, bytes calldata data) - unlock some value that I previously locked, and send it to one or more recipients (only valid when lock has not been delegated - see approveUnlock)
  • prepareUnlock(bytes32 lockId, string calldata from, string[] calldata to, uint256[] calldata amounts, bytes calldata data) - prepare to unlock some value that I previously locked, and record the prepared transition on the base ledger (but do not actually unlock)
  • approveUnlock(bytes32 lockId, address delegate, bytes calldata data) - delegate to another address that will be able to execute the prepared unlock operation (requires prepareUnlock to have been called)

Some notes about these methods:

  • It's possible some of the methods could be combined. You could make a case for lock + prepareUnlock or prepareUnlock + approveUnlock or even lock + prepareUnlock + approveUnlock, but for the moment I've left them all as separate transactions.
  • I've also explored whether it should be possible to prepare multiple unlock possibilities at one time, but for now have settled on having at most one prepared unlock operation per lock.
  • Calling prepareUnlock currently stores all of the prepared outputs state IDs on chain. It's possible we could optimize storage (and gas usage) slightly, by storing an EIP-712 hash of the unlock operation instead. But this would require the preparer to distribute the state details to the unlocker so that they can be passed back in to unlockWithApproval below.
  • Although currently unlock only allows the original lock owner to unlock the states, I believe more complex flows could be implemented via Pente hooks. Particularly something like Exploration on contracts for NotoDepositWithdraw #485 should be possible, where one party locks some value and spawns a separate contract to track it (such as an ERC20), and then various other parties are able to claim portions of the locked value by presenting proofs of their entitlement to unlock it.

New methods on Noto public ABI:

  • unlockWithApproval(bytes32 lockId, bytes calldata data) - trigger a prepared+approved unlock operation, returning control of any remaining locked value to the original lock owner
  • cancelUnlockApproval(bytes32 lockId, bytes calldata data) - cancel a prepared+approved unlock operation, returning control of the lock to the original lock owner

This PR also removes the "NotoSelfSubmit" variant. This contract was not fully proved out, and it doesn't seem useful to continue adding features to it at this time. We can always bring it back in the future if needed.

This variant isn't fully proved out, and may begin causing confusion.
We can bring it back at the time we're able to work through all of the
flows in detail.

Signed-off-by: Andrew Richardson <[email protected]>
Allows an owner to "lock" some portion of value such that it cannot be
spent except when specific conditions are met.

Signed-off-by: Andrew Richardson <[email protected]>
Currently you can only unlock to return the value to yourself (additional
work needed to allow specifying and executing a transfer).

Signed-off-by: Andrew Richardson <[email protected]>
Also gather two separate sender signatures for transfer + lock, so that
they can be emitted separately in the two blockchain events.

Signed-off-by: Andrew Richardson <[email protected]>
Signed-off-by: Andrew Richardson <[email protected]>
Use shorter names "restrictMint" and "allowBurn".

Signed-off-by: Andrew Richardson <[email protected]>
Allows a domain to directly trigger a new transaction, such as in response to
an event.

Signed-off-by: Andrew Richardson <[email protected]>
Change Noto to ensure notary name is fully qualified during deploy, and to
check on contract init if the current node is the notary.

Signed-off-by: Andrew Richardson <[email protected]>
Signed-off-by: Andrew Richardson <[email protected]>
Signed-off-by: Andrew Richardson <[email protected]>
Signed-off-by: Andrew Richardson <[email protected]>
Some functionality for delegating locks is lost, but will be added back in.

Signed-off-by: Andrew Richardson <[email protected]>
Signed-off-by: Andrew Richardson <[email protected]>
Signed-off-by: Andrew Richardson <[email protected]>
Example is working again (without hoooks for now).

Signed-off-by: Andrew Richardson <[email protected]>
@awrichar awrichar marked this pull request as ready for review December 27, 2024 20:32
@jimthematrix
Copy link
Contributor

should approveUnlock() be called delegateLock() to better reflect what it does?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add locking functionality to Noto
2 participants