Skip to content

Top-up allocations Take 2 - #14

Draft
dbzguy56 wants to merge 7 commits into
cip-0105-custom-templatesfrom
cip-0105-topup-allocs-v2
Draft

Top-up allocations Take 2#14
dbzguy56 wants to merge 7 commits into
cip-0105-custom-templatesfrom
cip-0105-topup-allocs-v2

Conversation

@dbzguy56

Copy link
Copy Markdown

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.
  • If an upgrade test is required, comment /upgrade_test on this PR to request it, and ping someone with access to the DA-internal system to approve it.
  • 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.
  • If a logical synchronizer upgrade test is required (from canton-3.5), comment /lsu_test on this PR to request it, and ping someone with access to the DA-internal system to approve it.

PR Guidelines

  • Include any change that might be observable by our partners or affect their deployment in the release notes.
  • Specify fixed issues with Fixes #n, and mention issues worked on using #n
  • Include a screenshot for frontend-related PRs - see README or use your favorite screenshot tool

Merge Guidelines

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

@dbzguy56 dbzguy56 changed the title Initial top-up allocations commit ontop of cip-0105-custom-templates Top-up allocations v2 Aug 25, 2026
unlockedAmuletCid <- unlockAmulet (ForOwner with dso; owner) holding
unlockedAmulet <- fetchChecked @Amulet (ForOwner with dso; owner) unlockedAmuletCid

-- TODO: Should change holding here always be none? Like if we want to topup,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Either we should assert that it's None, if that's indeed the case, or it should be part of the result of the operation probably.

unlockedAmulet <- fetchChecked @Amulet (ForOwner with dso; owner) unlockedAmuletCid

-- TODO: Should change holding here always be none? Like if we want to topup,
-- we want to do the full amount we're asked of?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I expect that change can be non-None here, they don't have to make a new Amulet just to control how much they top up by. It's not change relative to the amount we're asked, it's the change from breaking down the input holdings into the amount we're adding to the lock and the change we get back.


-- TODO: Should change holding here always be none? Like if we want to topup,
-- we want to do the full amount we're asked of?
([newHolding], changeHolding) <- lockAmulet

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'd like this to be a helper below for "add this amount from these holdings to this LockedAmulet", not just unlockAmulet. It can take the amount to increase as well, rather than the amount of the new lock.

I'd be inclined to make it have "cannot net unlock Amulet" as a checked invariant as well, but we could also plausibly relax those invariants and merge it and partialUnlock.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I think I have what was asked here in the first paragraph. I'm a little lost on the second, but I can ask you about that tomorrow.

governanceLock : Optional (ContractId GovernanceLock)
deriving (Eq, Show, Serializable)

data GovernanceLock_TopUpResult

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This should also have the change output, I think that enables chaining a few operations together with their "change" outputs and it's just sensible to report the new holdings.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added

actors : [Party]
controller owner
do
require "Only the owner may Top Up on an GovernanceLock" $ actors == [owner] -- TODO: custom controllers

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Definitely also need to know that the amount is positive, so this isn't also "unlock without vesting".

@meiersi-da meiersi-da left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks. Looks like straight top-ups are simple. Thanks for adding the test and catching the bug in your implementation.

Comment on lines +148 to +151
inputs <- fmap fst <$> queryInterface @Holding owner
(Some governanceLock) <- queryContractId @GovernanceLock owner cid
-- We want to make sure that we don't include the governanceLock holding as an input
let inputs' : [ContractId Holding] = deleteBy (==) (toInterfaceContractId @Holding governanceLock.holding) inputs

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Comment on lines +116 to +117
actors : [Party]
controller owner

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This doesn't make sense: don't accept actors when you set a fixed controller.

Suggested change
actors : [Party]
controller owner
controller owner

actors : [Party]
controller owner
do
require "Only the owner may Top Up on a GovernanceLock" $ actors == [owner] -- TODO: custom controllers

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
require "Only the owner may Top Up on a GovernanceLock" $ actors == [owner] -- TODO: custom controllers

unlockedAmulet <- fetchChecked @Amulet forOwner unlockedAmuletCid
lockAmulet
forOwner
[unlockedAmulet.amount.initialAmount + amount]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@jonored : I remember you wanted to change GovernanceLock to store its own amount directly, correct? That should also be pulled through to the code here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This is true, I have now merged in the latest code from Jonathan's branch


choice GovernanceLock_TopUp : GovernanceLock_TopUpResult
with
amount : Decimal

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
amount : Decimal
topupAmount : Decimal -- ^ Amount by which the locked amount should be increased.

@dbzguy56 dbzguy56 changed the title Top-up allocations v2 Top-up allocations Take 2 Aug 26, 2026

@meiersi-da meiersi-da left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks. Looks good to me assuming you address the suggestions I've added.

pure holdingView.amount

addAmountToLockedAmulet : ContractId LockedAmulet -> ForOwner -> ExternalPartyTransferContext -> [ContractId Holding] -> Decimal -> Update ([ContractId LockedAmulet], Optional (ContractId Amulet))
addAmountToLockedAmulet lockedAmulet forOwner context inputHoldingCids amount = do

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
addAmountToLockedAmulet lockedAmulet forOwner context inputHoldingCids amount = do
changeLockedAmuletAmount lockedAmulet forOwner context inputHoldingCids amount = do

as you are not doing an add, but a change.

Comment on lines +111 to +112

([newHolding], changeHolding) <- addAmountToLockedAmulet lockedAmulet (ForOwner with dso; owner) context inputs (amount + topupAmount)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
([newHolding], changeHolding) <- addAmountToLockedAmulet lockedAmulet (ForOwner with dso; owner) context inputs (amount + topupAmount)
let newAmount = amount + topupAmount
([newHolding], changeHolding) <- addAmountToLockedAmulet lockedAmulet (ForOwner with dso; owner) context inputs newAmount

this way you can reuse it below, and are guaranteed the amounts are in sync

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.

4 participants