Completed: ICDevs.org - Bounty #17 - A DAO for Cycles - $10,000 - ht: cycle_dao

Hello, long time no see, I am coming back with another round of questions :slight_smile:

Concerning the token standards to interface with, I added the link I found to each of them. Could you confirm it’s the right ones? Also I have some remarks on some of them.

DIP20: GitHub - Psychedelic/DIP20: DIP20: A fungible token standard for the DFINITY Internet Computer.
→ The single standard implemented so far

EXT (fungible and non-fungible): extendable-token/ext-core.mo at main · Toniq-Labs/extendable-token · GitHub
→ There is a mintNFT function in the ERC721 (non-fungible) interface, but for the standard fungible interface I could not find any mint function. I am not sure what how am I supposed to mint then.

DIP721: GitHub - Psychedelic/DIP721 at main
→ Looks allright

nft-origyn: OGY Ledger Candid Interface · GitHub
→ I could just find the interface, so I won’t be able to test by creating a nft-origyn canister on my side. Other than that looks allright.

ledger: ic/ledger.did at master · dfinity/ic · GitHub and example here: examples/main.mo at master · dfinity/examples · GitHub
→ The problem I think I will have is that only the internet computer gov canister can mint ICP? With my current design one needs to give the ownership of the minting canister to the CyclesDAO canister to mint the tokens which is impossible here. So I think there is probably something off with my design.

Maybe instead of giving the ownership of the token canister to the CyclesDAO canister it shall still belong to the governance canister, and the CyclesDAO shall (periodically or when it does not have anymore tokens?) ask the governance canister to refill it ? Or is there a possibility to give authorization to mint to another canister? (but looking at each token standard, it does not seem possible)

Hey…Origyn just uses the NNS/SNS ledger standard for the OGY token. There are a couple extra dfx calls, but nothing that should be relevant. Here is the current branch: ic/rs/rosetta-api/ledger_canister at dip-20-passthrough · ORIGYN-SA/ic · GitHub

The NFT standard is not published in full yet but the first test canisters are coming out this week and you’ll be able to preview the API.

1 Like

I don’t think that this canister is going to be able to run with ICP. Like you say, it needs to be the minting canister to be able to mint. You don’t need to integrate it with the ICP ledger specifically. Since the SNS will use that interface it will be good to have the interface working so those tokens can set the minting canister to the DAO canister. Maybe something in the SNS would preclude this, we can ask @lara.

Hi all! just read through the thread a bit and keen to try to help, but I don’t think I understand the concrete question you have just now.
Can you maybe try to reformulate the question that I might be able to help with?

Do I understand correctly that in your setting there are the following canisters: governance, ledger / token canister, and cyclesDAO canister (that trades cycles for governance tokens)?
I currently don’t fully understand whether you imagine to use the SNS canisters for governance / ledger?
Is the question whether for some of them you could use the SNS cansiters and be compatible? Or how the control / minting cansiters are set in the SNS design?

1 Like

I think the question is: Will the SNS be its own minting canister, or can we have a configurable one?

If it is configurable then this CycleDao canister could be used as a minting canister and set on the SNS ledger as the minting canister

1 Like

Got it, thanks for clarifying!

If you just want to use the SNS canisters as a basis but implement you own additions, you should be able to set the minting account to anything when you deploy the ledger canister. If you chose any canister other than the governance canister it might however be trickier to implement voting rewards (if you want them to consist of freshly minted tokens).

If you want to use the SNS “out of the box”, then by the Carbon milestone it will have a first simple version of a reward scheme, where the SNS governance canister will indeed be set as the minting account (minting canister). The design is however still in the discussion phase (see here). This is just a first version however, so it might be possible to make this configurable later (e.g., for SNSs that don’t want voting rewards, with voting rewards that are minted this would be harder).

We will also have a community conversation about SNS rewards next week if you are interested! It will be held by @bjoernek who leads the work on the SNS reward scheme.
(Bjoern, please also feel free to add details that I might have missed here).

Hope that helps, please let me know if you have further questions!

1 Like

Thanks for the reply! Maybe it makes sense in the future to have multiple minting accounts if you have different functions that you want to mint tokens for. Example: A network that rewards for 1. Voting 2. Sending cycles to the network 3.

1 Like

Thank you both for your answers! So for now I am gonna do as you suggest lara, put the minting account to the CyclesDAO when I deploy it.

I think we would have to carefully consider the consequences, also together with the ledger team that has maybe already thoughts on that.

So are you planning to use the SNS canisters for your project? And will you anyway use the code that we provided but not necessarily follow all the upgrade paths that we will establish for the Carbon deadline?
If so, I think just setting the account on initialization is a good solution.

I think we defintly would like to be able to do that.

We should be able to use the SNS governance canister from the Carbon milestone (the one that sets itself as the minting canister). The only thing is that we won’t be able to set the governance canister and the CyclesDAO to mint the same token.

But I think this problematic is not inherent to the SNS. @skilesare Correct me if I’m wrong, but we assumed with the design of the CyclesDAO that it would be possible to have two canisters (the CyclesDAO and the governance ones) that could mint the same token, but right now the token standards don’t support to have more than one minting address. I think at the end the choices are:

  • accept CyclesDAO canister and governance canister can only mint different tokens
  • have a mint function on the governance canister, and the governance would keep a list of principals that are allowed to mint tokens through it
  • have this logic in an intermediate “access control” canister that manages the minting rights, and governance and CyclesDAO would interact with this intermediate instead of the ledger/token
  • push to update the token standards to be able to have multiple principals that could mint the token

Thanks for the clarifications!
Just to make sure we are in agreement, let me comment on the proposed solutions:

  • accept CyclesDAO canister and governance canister can only mint different tokens

I think this would work with the SNS as it is planned (although to be honest I am still not sure I fully understand what the required functionality of the system is and thus if having two tokens is something that makes sense). Probably this would mean that one has a SNS ledger and on top of this another ledger cansiter that is just also controlled by the SNS?

  • have a mint function on the governance canister, and the governance would keep a list of principals that are allowed to mint tokens through it

This will not exist for the SNS from Carbon deadline and is not explicitly planned. It would require a change in the SNS governance canister that should be considered carefully. If not done right this opens the SNS up to dangerous attacks. Especially, I assume these principals would all have to be SNS controlled, so this might have to be enforced.
What could be done with the SNS currently is to add a new proposal type that is allowed to mint tokens on the ledger when the proposal is adopted, but I assume this is not what you are looking for.

  • have this logic in an intermediate “access control” canister that manages the minting rights, and governance and CyclesDAO would interact with this intermediate instead of the ledger/token

As long as this new special canister is set to be the minting canister, this might work with the SNS canisters. However, it might not work with the “out of the box”-SNS that is planned for Carbon where SNS governance might be set to the minting canister (as mentioned, the reward design is under way and will be discussed with the community next week). In any case, I want to reiterate that this would have to be designed extremely carefully to ensure that the minting of tokens is controlled in a decetralized way and that the end-users also have to possibility to verify this fact.

  • push to update the token standards to be able to have multiple principals that could mint the token

As you say, this would require changing the SNS ledger. Again, we would have to carefully assess whether this is actually secure and advisable.

These are just my spontaneous thoughts on how I think the different solutions relate to what is currently planned on the roadmap. Hope that helps a bit!

1 Like

I am a bit lost on what function does what. Can the function wallet_receive only mint the fungible tokens in exchange of the received cycles ? If not, how do I know which NFT(s) to mint in exchange of the cycles ?

On ConfigureDAOCommand(#DistributeBalance), shall the CyclesDAO transfer or mint the token?

In my current implementation, I assumed:

  • Only DIP20, EXT(fungible), Ledger standards can be set and then used to exchange cycles in exchange of freshly minted tokens (no NFT)
  • ConfigureDAOCommand(#DistributeBalance) performs a transfer of the given token (one of the six possible, NFTs included)

The idea here is that if you contribute cycles you will get some dao tokens. Perhaps you could set this up to lint nfts, but that wasn’t the original intent.

This is only needed if the dao ends up with a balance somehow. Maybe the main token wants to take .5% of every transaction and send it to the dao so the dao can distribute it to developers. Just an example.

1 Like

Ok thanks, I think I’m doing the right thing then.

I think I have finished with the development besides:

  • some minor blockings/notes: everything is written in the readme. I am waiting on your feedback to work on these.
  • the implementation of the NFT_ORYGIN standard: last time I checked I could not find the candid/wasm files for the NFT token, but I’m gonna ask on the forum.
  • a phylosophical question: currently the cycles DAO can be configured with any principal as governance, which can be a single individual or an actual DAO. IMO it’s nice to have a separation of responsabilities per canister, and it allows a broader usage of the CyclesDAO. The drawback is that the frontend does not allow to add proposals, or to see their states - it only shows accepted proposal (i.e. actual configure calls). Also that makes the name CyclesDAO a bit misleading, because it’s possible to involve no DAO at all.

I would like to discuss two points:

  • one limitation of the current architecture is that the DAO cannot mint the same token as the CyclesDAO. IMO if we make the “CyclesDAO” configurable with any DAO, it’s a bummer to have this limitation. I think it could be solved with this architecture:

CycleSDAO

The CyclesDispenser canister is basically be the current CyclesDAO canister but instead of directly doing the mint it calls MintAccessController.mint().

The MintAccessController is a simple canister that is configured with a token to mint. On configureToken, it verifies if it owns the token. It keeps a list of authorized minters that can be added by the admin only. On mint(), it checks if the caller is authorized, if yes it mints the configured token.

The DAO can be any DAO that has the capacity to execute proposals as canister calls (like the BasicDAO from the examples). It can be used to call functions on the CyclesDispenser, the MintAccessController, or anything else. Which brings to my second point:

  • if we keep the CyclesDAO configurable with any DAO, IMO it does not make a lot of sense to have a function configure(#Distribute) because the DAO could directly submit a proposal to distribute some token itself, it does not need to call another canister to do that.
  • In walletReceive, there is no absolute guarentee that after the cycles have been accepted, the minting of the token cannot fail. In this case the loses his cycles and receive no token in exchange (see main.mo:143)

Maybe we should wait to accept the cycles until after the mint? In addition, the mint may have a cost and we might want to subtract the mint cost from the cycles? Might be a good use of the cycle calculation API?(ok to wait to another phase for this).

  • In distributeCycles, if one call to fillWithCycles function traps, it will prevent other allowed canisters from receiving cycles. (see main.mo:232)

Possible solution: When this is called have deque that is checked…if it is empty, fill it with items from the triemap. Cycle through the deqeue and before you call the item, move it to the back. If it is successful, remove it entirely. This way if there is a trap and the function fails, the committed items will be removed and you can just pick it up again on the next call. You’ll have to handle an permenatly failing item…maybe with a time-out? If the queue is over 5 minutes old it gets blown away? May need to think through this a bit more, but perhaps something along those lines?

nft_origyn

I’m finalizing it right now…I’ll try to get it to you asap…should be straight forward.

  • a phylosophical question: currently the cycles DAO can be configured with any principal as governance, which can be a single individual or an actual DAO. IMO it’s nice to have a separation of responsabilities per canister, and it allows a broader usage of the CyclesDAO. The drawback is that the frontend does not allow to add proposals, or to see their states - it only shows accepted proposal (i.e. actual configure calls). Also that makes the name CyclesDAO a bit misleading, because it’s possible to involve no DAO at all.

I’m not totally sure I follow. Why can’t the front end add proposals? Because it isn’t the governance principal?

100% agree on this principle. If you want to work up a simple controller it would be great. At Origyn we have minting_canister that acts in this way so it is likely a good pattern to at least describe in the read me for people that want to implement it. It can basically be a relay.

I can do that, it’s probably safer this way, but now there is a small risk that the amount of accepted cycles returned from ExperimentalCycles.accept is different than the amount passed as argument. According to the doc, it can happen if “less is available or the canister balance limit is reached”. If less is available, I guess that should never happen if we deduce the amount from ExperimentalCycles.available. If the canister limit is reached: this I don’t know where that limit is defined, but we should make sure that we cannot set a cycles exchange config that goes over that limit, otherwise once the limit is reached it’s free mint of tokens for everybody that call walletReceive.

Yes! I’m not sure to understand the timing thing though. But having an intermediate deque to monitor with which canisters to resume if the previous call to distributeCycles ever traps could work on its own.

Well I’m not sure what final product you expect. Do you prefer:

  1. a frontend specific to the CyclesDispenser canister. This frontend does not do anything DAO specific, it’s pretty much readonly (but maybe allow to call walletReceive, using plug or stoic ? is this something you want ?).
  2. same as 1. + another frontend specific to the BasicDAO (that btw I’m gonna have to fork and modify, I just realized that it needs to use a real token :clown_face:). So if the user ever decides to use another DAO that the BasicDAO, it still can access the CyclesDispenser frontend.
  3. a single unified frontend that uses both the cyclesDispenser and BasicDAO canisters, but if you decide to use your own DAO instead of the BasicDAO, the frontend wouldn’t work.

Cool! Then I know what to continue with :slight_smile: