# Create a proposal

## What's a proposal?

A proposal is a set of instructions that, if approved, will be executed by the governance contracts on the Chancey smart contracts. Anyone can submit a proposal—to change ticket prices, adjust fees, or modify the source code. Please review this document carefully before submitting or voting on a proposal.

## Chancey Smart Contracts

Chancey runs on four smart contracts, each of which can be modified through a proposal.

* **Chancey 649** - Handles the game logic and rewards system.
* **Chancey Token** - Implements the ERC20 interface for Chancey Points.
* **Governor** - An OpenZeppelin-based governance contract that accepts proposals and votes.
* **Timelock** - Executes successful proposals.

Each proposal must target one of these smart contracts and specify a function selector with the appropriate parameters. The following section describes the available selectors for each contract.

## Chancey 649

### Configure raffle prizes

```json
configureGuaranteedPrize(uint256 ticketsLot, uint256 rate)
```

Use this selector to configure a new or existing raffle prize by setting the odds and payout. Chancey determines raffle winners based on the number of tickets sold. For example, you can configure a raffle prize for every 1,000 tickets sold. The prize is calculated as a percentage of the total pot.

**Parameters:**

* `ticketsLot` - Specifies how many tickets must be sold before selecting a raffle ticket (e.g., `100` means one raffle ticket is chosen per **100** tickets sold).
* `rate`- Defines the percentage of the pot shared among all raffle winners from the selected lot (e.g., `2` represents **2%** of the pot).

### Smart contract upgrades

```json
diamondCut((address, uint8, bytes4[])[] _diamondCut, address _init, bytes _calldata)
```

Chancey 649 is built using the [EIP-2535 Diamond pattern](https://eips.ethereum.org/EIPS/eip-2535),  where the core contract manages the on-chain storage while modular contracts, known as Facets, execute game logic. This architecture enables flexibility, allowing new features to be integrated or existing ones to be modified without disrupting the system.

At launch, the game was deployed with all necessary Facets, but this selector provides the ability to add new ones or remove existing ones as needed. Before using this selector to create a proposal, it's important to understand EIP-2535 and its impact on contract upgrades to ensure smooth integration and security.

**Parameters:**

* `_diamondCut` an array of EIP-2535 diamond cuts to add, remove or replace a facet.
* `_init` an optional contract address to initialize the diamond cut with (can be set to zero address)
* `_calldata` call data bytes to run the optional initialization with (can be set to an empty byte array)

### Grant role

```json
grantRole(bytes32 _role, address _account)
```

Chancey 649 grants specific privileges to registered addresses, allowing them to perform administrative tasks. The currently supported roles are:

* `PAUSE_ROLE` – Allows an address to temporarily halt the game when necessary for smart contract upgrades. By default, this privilege is granted only to the Timelock contract, requiring community consensus to pause the game.
* `FEE_ADMIN_ROLE` – Allows an address to manage the portion of ticket sales allocated as protocol fees. By default, this privilege is also granted only to the Timelock contract, ensuring fee adjustments require community consensus.

**Parameters:**

* `_role` A kecca256 hash of the role name as bytes (e.g. `keccak256(toBytes("PAUSE_ROLE"))` ).
* `_account`  The address of the new role beneficiary.

### Pause game

```json
pauseGame()
```

Submit a proposal to pause the game for a predetermined interval (default: 3 days). While the game is paused, only calls from the Timelock contract are allowed, as well as pausing and unpausing calls.

**Parameters: None**

### Remove raffle prize

```json
removeGuaranteedPrize(uint256 _ticketsLot)
```

Previously configured raffle prizes can be removed with this selector.

**Parameters:**

* `_ticketsLot` Specifies how many tickets must be sold before selecting a raffle ticket (e.g., `100` means one raffle ticket is chosen per 100 tickets sold). NOTE: This specifies which lot to remove from the game.&#x20;

See also: [Configure raffle prizes](#configure-raffle-prizes)

### Retry current draw

```json
retryCurrentDraw(bool _nativePayment)
```

If there is a hiccup with random number generation (e.g., insufficient oracle funding), this selector can be used to retry the current draw after it has been triggered.

**Parameters:**

* `_nativePayment` If set to `true`, the oracle fee for random number generation will be paid in ETH; otherwise, it will be paid in LINK. Be sure to check the game configuration to confirm the current payment setting.

### Revoke role

Previously granted roles can be easily removed using this selector.

**Parameters:**

* `_role` A kecca256 hash of the role name as bytes (e.g. `keccak256(toBytes("PAUSE_ROLE"))` ).
* `_account` The address of the current beneficiary

See also: [Grant role](#grant-admin-roles)

### Carryover tickets

```json
setCarryoverTickets(bool _carryover)
```

By default, any non-winning tickets in a draw are discarded. If the community wants to keep tickets in play for future draws, this selector allows for that change. Keep in mind, this will have a significant impact on the game economy, so ensure you have strong community support before proposing it.

**Parameters:**

* `_carryover`  If set to `false`(default) non winning tickets are discarded, otherwise, any non winning tickets will be eligible for the future draws until it becomes a winning ticket.

### Draw interval

```json
setDrawInterval(uint256 _interval)
```

To allow the pot to grow before a draw is triggered, Chancey imposes a delay. By default, this delay is set to **7 days** (expressed in seconds) at deployment. Use this selector to modify the delay period.

**Parameters:**

* `_interval`The number of seconds to wait before a new draw can be triggered.

### Free tickets exchange rate

```json
setFreeTicketExchangeRate(uint256 _rate)
```

Players can burn their Chancey Points in exchange for free tickets. By default, burning 10 Chancey Points grants one free ticket. Use this selector to modify the exchange rate.

**Parameters:**

* `_rate` The number of points required for a free ticket. This value must be greater than `5`, otherwise the proposal will be reverted.

### Free tickets to sold tickets ratio

```json
setFreeTicketsToSoldRate(uint8 _rate)
```

Free tickets have the same chance of winning prizes but do not contribute to the pot’s growth. To maintain balance, the number of free tickets issued is limited. This limit is proportional to the number of sold tickets, with the default configuration capping free tickets at **10%** of total tickets sold in a draw. Use this selector to change that ratio.

**Parameters:**

* `_rate` The new ratio of free tickets vis-a-vis total tickets sold in a draw. This value must be greater than `10`

### Game fees

```json
setGameFeeRate(bytes32 _fee, uint8 _rate)
```

A portion of each ticket sale is collected as fees to cover operational costs and the incentives program. These fees include:

* `ADMIN_FEE` - Covers the cost of running Chancey (e.g., VRF, hosting, and licensing fees).
* `STAKE_REWARDS_FEE`- Funds the staking rewards program.

Use this selector to adjust the collected fees as needed.

**Parameters:**

* `_fee` A kecca256 hash of the fee name as bytes (e.g. `keccak256(toBytes("ADMIN_FEE"))` ).
* `_rate`The percentage of the ticket sale going towards this fee.

### Minimum tickets

```json
setMinTickets(uint256 _min)
```

To ensure the pot grows before a draw is triggered, Chancey requires a minimum number of tickets to be sold. By default, this is set to 10 tickets. Use this selector to adjust this requirement.

**Parameters:**

* `_min`The new required minimum.

### Pot reserve rate

```json
setNextPotReserveRate(uint8 _rate)
```

A portion of every ticket sale is set aside for the next draw to account for the possibility that someone wins the jackpot in the current draw and empties the pot. This ensures that every draw will have a prize pool. Use this selector to configure the reserve rate.

**Parameters:**

* `_rate`The percentage from ticket sales going towards the next draw.

### Pause interval

```json
setPauseInterval(uint256 _interval)
```

Chancey can be paused at any time, either through governance or by accounts with the necessary privilege. To prevent the game from being paused indefinitely, it will automatically unpause after a set interval (default: 3 days). Use this selector to configure the pause limit.

**Parameters:**

* `_interval` The maximum number of seconds the game will remained in the paused state.

### Pot burn cool rate

```json
setPotBurnCoolRate(uint8 _rate)
```

Points can be redeemed for a portion of the total pot value at any time and the account doing so will be rewarded with a small portion of the game’s total pot. The reward amount depends on the current total supply of points (TS), the total pot value (PV), the number of points burned (TB) and a cool off rate (CR, default value set to 2). The formula is described by the following equation:

```
Payout = Floor((PV * TB)/(CR * TS))
```

You can use this selector to adjust the cool rate (CR)

**Parameters:**

* `_rate`The new cool rate.

### Random source

```json
setRandomSource(uint8 _source)
```

During development, various sources of randomness were tested. While the final implementation uses Chainlink's VRF, this selector remains available in case new sources of randomness are introduced in the future.

**Parameters:**

* `_source`The new source identifier.

### Rewards boost factor

```json
setRewardsBoostFactor(uint8 _boostFactor)
```

The [formula](#rewards-buckets) for calculating the number of Chancey Points minted per ticket sale includes a boost factor to amplify or reduce rewards. Use this selector to adjust the boost factor.

**Parameters:**

* `_boostFactor` The new reward boost factor

### Rewards buckets

```json
setRewardsBuckets(uint8 _buckets)
```

The formula for minting points during ticket sales is logarithmic and depends on the total pot value (PV), the target pot value (TV), which defaults to 100 ETH, the number of distribution buckets (BC), and the boost factor (BF). It is described by the following equation:

```
MintAmount = BF * 2^(BC-Floor((PV*BC)/TV))
```

**Parameters:**

* `_buckets`The new number of distribution buckets.

### Pot lift target

```json
setRewardsPotLiftTarget(uint256 _target)
```

To incentivize pot growth, Chancey Points are minted in exchange for ticket sales until the pot reaches a set target. This target is initially set to 100 ETH at deployment and can be adjusted using this selector. Once the pot reaches the target, only one Chancey Point is minted per ticket sale.

**Parameters:**

* `_target` The new target in ETH

### Ticket price

```json
setTicketPrice(uint256 _ticketPrice)
```

Use this selector to set a new ticket price

**Parameters:**

* `_ticketPrice`The new ticket price in wei. For example, to set the ticket price to `0.001` ETH, you must set this parameter to `1000000000000000`

### VRF coordinator

```json
setVrfCoordinator(address _vrfCoordinator)
```

Chancey relies on [Chainlink's VRF](https://docs.chain.link/vrf) to generate random numbers for draws. The coordinator address is set during deployment and generally remains unchanged, as Chainlink operates a single instance per network. However, this selector is available in case Chainlink updates its infrastructure in the future.

**Parameters:**

* `_vrfCoordinator` The address of the new coordinator.

### VRF callback gas limit

```json
setVrfCallbackGasLimit(uint32 _limit)
```

Use this selector to set the maximum gas limit that the VRF coordinator can use when calling Chancey with random numbers. This value is unlikely to change unless the Chancey source code is modified, in which case it must be recalculated by the developer implementing the change.

**Parameters:**

* `_limit`The new gas limit

### VRF key hash

```json
setVrfKeyHash(bytes32 _keyHash)
```

This value is set during deployment and is unlikely to change. You can learn more about it in Chainlink's [developer guide](https://docs.chain.link/vrf/v2-5/supported-networks).

**Parameters:**

* `_keyHash`The new key hash if Chainlink decides to change it.

### VRF subscription ID

```json
setVrfSuscriptionId(uint256 _subId)
```

In order to fetch random numbers from Chainlink a funded subscription must be configured. Use this selector if you wish to change the subscription in the future. NOTE: you can keep funding the existing subscription without changing it.

**Parameters:**

* `_subId` The new subscription ID.

### Transfer fee balance

```json
transferGameFeeBalance(bytes32 _fee, address _to)
```

Use this selector to transfer the accumulated balance of the accumulated fee to a specific address.

See also: [Game fees](#game-fees)

**Parameters:**

* `_fee`  The fee to transfer, e.g. `keccak256(toBytes("ADMIN_FEE"))`
* `_to`The beneficiary address

### Transfer ownership

```json
transferOwnership(address _newOwner)
```

Chancey is owned by the [Timelock](#chancey-smart-contracts) smart contract. Use this selector to transfer the ownership to a new instance of the Timelock contract.

{% hint style="info" %}
**CAUTION:** Misconfiguring the new owner with this selector could completely break the project!
{% endhint %}

**Parameters:**

* `_newOwner` The address of the new Timelock contract.

### Unpause Game

```json
unpauseGame()
```

A selector to resume a paused game before the pause timer expires.

**Parameters: None**

### User agreement

```json
updateUserAgreement(string _documentUri)
```

Every player must agree to the Chancey terms of service before engaging with the game. This selector is used to set the URI of the latest terms of service document the users can read.

**Parameters:**

* `_documentUri` The URI of the latest terms of service document.

## Chancey Token

### Smart contract upgrades

```json
diamondCut((address, uint8, bytes4[])[] _diamondCut, address _init, bytes _calldata)
```

The Chancey Token (Chancey Points) smart contract implements the ERC-20 standard and is built using the [EIP-2535 Diamond pattern](https://eips.ethereum.org/EIPS/eip-2535),  where the core contract manages the on-chain storage while modular contracts, known as Facets, execute ERC-20 logic. This architecture enables flexibility, allowing new features to be integrated or existing ones to be modified without disrupting the system.

At launch, the token was deployed with all necessary Facets, but this selector provides the ability to add new ones or remove existing ones as needed. Before using this selector to create a proposal, it's important to understand EIP-2535 and its impact on contract upgrades to ensure smooth integration and security.

**Parameters:**

* `_diamondCut` an array of EIP-2535 diamond cuts to add, remove or replace a facet.
* `_init` an optional contract address to initialize the diamond cut with (can be set to zero address)
* `_calldata` call data bytes to run the optional initialization with (can be set to an empty byte array)

### Grant role

```json
grantRole(bytes32 _role, address _account)
```

The Chancey Token supports one role only — `MINTER_ROLE` and it is granted to the Chancey649 contract during deployment. This selector can be used to grant the `MINTER_ROLE` to another address.

**Parameters:**

* `_role` A kecca256 hash of the role name as bytes (e.g. `keccak256(toBytes("MINTER_ROLE"))` ).
* `_account`  The address of the new role beneficiary.

### Revoke role

```json
revokeRole(bytes32 _role, address _account)
```

Previously granted roles can be easily removed using this selector.

**Parameters:**

* `_role` A kecca256 hash of the role name as bytes (e.g. `keccak256(toBytes("MINTER_ROLE"))` ).
* `_account` The address of the current beneficiary

See also: [Grant role](#grant-role)

### Transfer ownership

```json
transferOwnership(address _newOwner)
```

The Chancey Token is owned by the [Timelock](#chancey-smart-contracts) smart contract. Use this selector to transfer the ownership to a new instance of the Timelock contract.

{% hint style="info" %}
**CAUTION:** Misconfiguring the new owner with this selector could completely break the project!
{% endhint %}

**Parameters:**

* `_newOwner` The address of the new Timelock contract.

## Governor

### Grant role

```json
grantRole(bytes32 _role, address _account)
```

Grant a new role to a new account. Supported roles:

* `PROPOSAL_CANCELER_ROLE` - Allows cancelling roles that are not queued for execution (role assigned to account deploying the contract)
* `DEFAULT_ADMIN_ROLE` - Grants ownership over the contract (role not assigned by default)

**Parameters:**

* `_role` A kecca256 hash of the role name as bytes (e.g. `keccak256(toBytes("PROPOSAL_CANCELER_ROLE"))` ).
* `_account`  The address of the new role beneficiary.

### Revoke role

```json
revokeRole(bytes32 _role, address _account)
```

Previously granted roles can be easily removed using this selector.

**Parameters:**

* `_role` A kecca256 hash of the role name as bytes (e.g. `keccak256(toBytes("PROPOSAL_CANCELER_ROLE"))` ).
* `_account` The address of the current beneficiary

### Proposal threshold

```json
setProposalThreshold(uint256 newProposalThreshold)
```

This selector sets the minimum number of votes and address is required to have to submit a proposal. The number of votes is derived from the number of Chancy Points an address has delegated. The threshold is set to zero during deployment.

**Parameters:**

* `newProposalThreshold` The new threshold

### Voting delay

```json
setVotingDelay(uint256 newVotingDelay)
```

To give the community time to review proposals, the Governor contract enforces a delay before voting begins. This delay is initially set to 6,570 blocks at deployment and can be adjusted using this selector.

**Parameters:**

* `newVotingDelay`The new number of blocks the proposal will remain in review before voting can begin.

### Voting period

```json
setVotingPeriod(uint256 newVotingPeriod)
```

To ensure sufficient time for participation, the Governor contract defines a voting period during which proposals remain open for voting. This period is initially set to 45992 blocks at deployment and can be adjusted using this selector.

**Parameters:**

* `newVotingPeriod` The new number of blocks the voting will remain open.

## Timelock

### Grant role

```json
grantRole(bytes32 _role, address _account)
```

Grant a new role to a new account. Supported roles:

* `CANCELER_ROLE`- Allows cancelling of proposals scheduled for execution (assigned to the account deploying the contract)
* `EXECUTOR_ROLE`- Gives other accounts the ability to execute proposals before the waiting period (role not assigned) &#x20;

**Parameters:**

* `_role` A kecca256 hash of the role name as bytes (e.g. `keccak256(toBytes("CANCELER_ROLE"))` ).
* `_account`  The address of the new role beneficiary.

### Revoke role

```json
revokeRole(bytes32 _role, address _account)
```

Previously granted roles can be easily removed using this selector.

**Parameters:**

* `_role` A kecca256 hash of the role name as bytes (e.g. `keccak256(toBytes("CANCELER_ROLE"))` ).
* `_account` The address of the current beneficiary

### Execution Delay

```json
updateDelay(uint256 newDelay)
```

Successful proposals are placed in a waiting queue for a set duration (default 86400 seconds, or one day), allowing for a final review before execution. This selector enables adjustments to the waiting period.

**Parameters:**

* `newDelay`The number of seconds the proposals must wait in the queue before it can be executed.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://chancey.gitbook.io/chancey/help/create-a-proposal.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
