Original code: https://github.com/paritytech/substrate/blob/master/frame/lottery/src/lib.rs
Previous discussion: https://kusama.polkassembly.io/post/242
The Lottery Pallet is part of an effort aiming to increase participation in Kusama's governance design and should be understood in this context. The pallet interacts with Democracy, Collective, Staking and Elections-phragmen modules, by including the extrinsics within these as a mechanism to purchase a ticket for a lottery, upon certain conditions.
The pallet can be linked to any calls in Kusama and Polkadot, but initially it is intended to be used in validators election, council nomination and democracy referendum vote. Although this might not be a suitable mechanism to incentivise Council participation by Council Members, it might be an indirect way to commit them to participate on behalf of their passive stakeholders.
A disadvantage of the pallet is its vulnerability to Sybil attacks. However, this can be reduced by increasing the cost of participation in comparison to the cost of an attack.
A collective on Kusama (most likely the Council, at least on the initial phase) will open a lottery and decide on the calls to be included for participation. The Council starts a lottery by voting a motion that executes start_lottery
. In the motion design, the Council also votes on the included calls (set_calls
), by adding the call indices to the proposal, or programs the valid calls directly into the runtime (which is what we might want to do in order to have strong control over valid calls). The motion also includes the price of the ticket (an estimation for the initial phase is to set this up at 0.1KSM), the lottery length (initially 1 month has been discussed), the delay length (allowing the mechanism to be resistant to malicious actors) and if the lottery will repeat or not after end block is created.
Once the motion passes, the lottery is opened, including an index
for identification and an address, similar to the Society pot and the Kusama treasury. The lottery will have its own address and a positive balance, funded by lottery ticket payments by users when purchasing one and any other discretional donations to the mechanism.
Some considerations when purchasing a ticket:
A ticket can be purchased by executing any call included as validCall
in the proposal. An address can purchase one ticket per valid call: this means that, if three calls are included in the design of the lottery, an address can purchase 3 tickets. The pallet includes a mechanism that checks for address participation before confirming purchase (AlreadyParticipating
).
There can only be one lottery per period, but the design includes the option to repeat the same lottery (this option needs to be approved by the Council when voting on the proposal). The Council can also cancel any repetition or create a new lottery with different parameters. We mentioned a 0.1 KSM price per ticket: this price is not fixed and can be adjusted whenever a new lottery starts, but only at that granularity: to change the price, the Council would need to cancel the repeating lottery and start a new one at the new price.
New calls can be added dynamically if storage is used to do call validation. In order for a ticket purchase to happen based upon certain conditions (i.e: only democracy votes of a certain value qualify to purchase a ticket) this would require a runtime configuration and therefore an upgrade of the network.
In order to make it easier for the user to interact with the pallet, some changes in the UI are needed: a "Buy Lottery Ticket" button (enabled when a lottery is active and the call is valid) should appear on the extrinsic approval screen for users to have the option to participate.
Once the lottery is open, users can purchase tickets by signing those calls included as valid
. In an hypothetical lottery in which the validCalls
are:
Democracy > vote(ref_index, vote)
- vote in a referendumElectionsPhragmen > vote (votes, value)
- Vote for a set of candidates for the upcoming round of validators election or council members
any user signing these calls will have the opportunity to purchase a ticket for the period of the lottery and can only do this once per call. When the ticket is purchased, users become lottery participants and need to wait until the lottery ends to know who the winner is.
The length of the lottery is defined by block numbers: once the end block is created, the lottery will go to a delay period, to be defined in the proposal. After, randomness in the "payout" block will be used to determine the winner, meaning the system will randomly choose a winner from among the total number of participants.
Does the pallet limit address participation so an address can only participate once? Can an address participate in a lottery more than once by calling different valid calls? or is this limited by AlreadyParticipating
as well?
Users can buy 1 ticket per valid call. So if there are 3 calls, they can get up to 3 tickets for a single lottery.
Does the lottery have the ability to schedule a repeat?
Yes: lottery can be repeating, and that is configurable. Not very granular, but good enough for "monthly lottery".
Can the price per ticket be adjusted dynamically: what is a reasonable price for a lottery including council nomination, validators election and democracy vote as valid calls? Can we adjust this taken into account token price volatility?
Price can be adjusted whenever a new lottery starts, but only at that granularity. For now, something like 0.1 KSM. This would not be dynamic enough to take in price volatility: We would need to wait until the next lottery and adjust the price again. We do not have an oracle for price at the moment.
If more calls need to be added as validCalls
, do we need to start a new lottery or can this be added to an ongoing one?
New calls can be added dynamically if we use storage to do the call validation. If we want to do more fancy stuff like make it so that only democracy votes of a certain value qualify to participate for example, this would involve a runtime config and would require a runtime upgrade to modify the calls.
What is the reasoning behind using a delay at the end of the lottery?
Delay at the end of the lottery allows the design to be more resistant to the random number generation by a malicious actor. It may not be necessary in the short term, but it is good to have.
How does the pot work? Is it similar to the Society pallet? Does it have its own address?
Yes: it has its own address and works like the two treasuries currently on Kusama and Polkadot networks.
Do we need a tab on Apps to show ongoing lotteries and statuses? Does the pallet allow only one lottery per period? Is the period 28 days on polkadot and 7 on Kusama (spendingPeriod
)?
Yes: only 1 lottery per period is allowed. Some basic work to the Apps UI would be needed, for example making it easy to buy a ticket. You can configure how long the lottery is when opening it.
When a user calls a valid call: should a button be added on the 'Authorize Transaction' window to allow a user to purchase a ticket? If not, how do we envision a user purchasing a ticket without using the extrinsics tab?
Yes, that is generally what we envision, adding an extra "buy ticket" button on the extrinsic approval screen.
managerOrigin
(in charge of opening new lotteries) is not yet defined in the pallet: which collective will be in charge of opening new lotteries?
Initially, the Council should manage this - this can be modified with a runtime upgrade.
Full document can be found here. Please leave your questions and comments!