Skip to content

CIP-0058 (Daml) - Minting escrowed canton coin #1056

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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

jose-velasco-ieu
Copy link

@jose-velasco-ieu jose-velasco-ieu commented Jun 10, 2025

Summary

This PR adds the DAML model logic required to support minting escrowed Canton Coin.
It introduces a new action requiring confirmation: AmuletRules_CreateAmuletMintOffer, which is exercised via the standard voting procedure using DsoRules.

This choice results in the creation of an AmuletMintOffer contract, which gives a beneficiary the right to accept the offer in order to receive a new Amulet. In exchange, the beneficiary must provide a sufficient list of UnclaimedReward contracts, which are then archived (burned).
The amount of Amulet to be minted matches the total amount of UnclaimedReward to be archived.
The beneficiary submits this list using explicit disclosure, since they might not be a stakeholder in the UnclaimedReward contracts.

Additionally, this PR introduces:

  • A happy-path test in splice-dso-governance-test that verifies the voting and minting flow
  • Several unhappy-path tests in splice-amulet-test for validation and failure scenarios.

As the DAML model has been updated, the corresponding DAML artifact versions have been bumped accordingly.

CIP-0058: https://github.com/global-synchronizer-foundation/cips/blob/main/cip-0058/cip-0058.md

Pull Request Checklist

Cluster Testing

  • If a cluster test is required, comment /cluster_test on this PR to request it, and ping someone with access to the DA-internal system to approve it. N/A
  • If a hard-migration test is required (from the latest release), comment /hdm_test on this PR to request it, and ping someone with access to the DA-internal system to approve it. N/A

PR Guidelines

  • Include any change that might be observable by our partners or affect their deployment in the release notes. N/A - will add it once the full functionality is implemented (Scala and UI is pending)
  • Specify fixed issues with Fixes #n, and mention issues worked on using #n N/A
  • Include a screenshot for frontend-related PRs - see README or use your favorite screenshot tool N/A

Merge Guidelines

  • Make the git commit message look sensible when squash-merging on GitHub (most likely: just copy your PR description).

beneficiary : Party -- ^ The owner of the `Amulet` to be minted
amount : Decimal -- ^ The amount of `Amulet` to be minted
reason : Text -- ^ A reason to mint the `Amulet`
where

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jose-velasco-ieu : nice work!

This is not a full review, but a question from a first view at the approach chosen. Let me know if there's other context that I should/could consume to learn about the answer.

Is there a particular reason that you decided to have the recipient deliver the UnclaimedReward contracts instead of having the dso party deliver them up-front when creating the AmuletMintOffer?

The latter option seems to have the following advantages:

  1. AmuletMintOffer become decoupled from UnclaimedReward contracts at the implementation level, which allows them to be used more widely if future changes should demand so.
  2. No explicit disclosure is required (and no related API endpoints), as the SV nodes acting in the name of the DSO party have visibility into the UnclaimedReward contracts.
  3. Every offer stands on its own, and locks the appropriate amount of minting rights.

The disadvantage might be that at the DsoRules level, another extra step might be required to decouple the voting from the selection of the UnclaimedReward contracts. That seems benign though, and follows the approach that we generally try to move complexity out of the user-facing code in splice-amulet to the governance code.

Further question: why does the offer never expire? How could it be retracted by the DSO?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The disadvantage might be that at the DsoRules level, another extra step might be required to decouple the voting from the selection of the UnclaimedReward contracts. That seems benign though, and follows the approach that we generally try to move complexity out of the user-facing code in splice-amulet to the governance code.

We considered that, but the extra indirection through an extra template and trigger seems more complex than exposing the unclaimed rewards through explicit disclosure. @jose-velasco-ieu will work on a design doc next which I think is a good place to have this discussion.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack. Thanks for the information. Looking forward to reading the doc.

Copy link
Author

@jose-velasco-ieu jose-velasco-ieu Jun 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further question: why does the offer never expire? How could it be retracted by the DSO?

I didn't consider expiration since the AmuletMintOffer is the result of a successful vote.
Should I add it? @moritzkiefer-da @meiersi-da

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, we should add expiration

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that matches my expectation

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be sure.
The thing is, the party initiating the vote is the beneficiary themselves (requester in DsoRules_RequestVote )
Is it okay for the beneficiary to set the expiration date?

-- This would be the choice requiring confirmation, which gets created by beneficiary using DsoRules_RequestVote (requester)

nonconsuming choice AmuletRules_CreateAmuletMintOffer : AmuletRules_CreateAmuletMintOfferResult
      with
        beneficiary : Party 
        amount : Decimal 
        reason : Text
        expiresAt : Time
      controller dso

@moritzkiefer-da @meiersi-da

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing is, the party initiating the vote is the beneficiary themselves (requester in DsoRules_RequestVote )

That's not the case. The party initiating the vote is an SV node operator, e.g., GSF. The beneficiary could be any party. For the concrete scenario you're working on here, it will still be an SV but that node may just be hosted on the GSF node but it is not an SV node operator.

So the vote creator and the beneficiary receiving CC are not the same. And even if they were, all the other SVs still must approve the vote so it's fine it the vote creator can chose the expiry.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for the clarification.
I was confused because of this statement in the CIP

Applicant is required to present a calculation for number of Canton Coin it should earn for meeting the requirements of the milestone

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd view this as separate off-ledger processes vs on-ledger processes:

  1. Off-ledger the applicant is the one that initiates the process.
  2. On-ledger an existing SV node operator is the one that creates the vote request.

@moritzkiefer-da moritzkiefer-da self-assigned this Jun 12, 2025
@moritzkiefer-da moritzkiefer-da marked this pull request as draft June 12, 2025 13:55
@jose-velasco-ieu
Copy link
Author

@moritzkiefer-da @simonletort-da
FYI: I’ll create a new one based on the eventual new design.

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

Successfully merging this pull request may close these issues.

3 participants