DeFi Rewards Smart Contract
General
The DeFi Rewards contract is designed to integrate with the Yield contract and synchronize with its cycle and snapshot data. The contract handles state management, snapshot balance computations, and rewards distribution. It is structured to initialize the contract, manage snapshots, and compute balances, as well as distribute rewards to participants in all the DeFi pools under a DeFi protocol.
Diagram of the Complete Flow

Overview
The DEX Rewards smart contract enables participants in DEX pools to claim proportional rewards based on their sBTC holdings across all pools under a DEX protocol. Key operations include:
Initialization: The contract is initialized by the administrator, syncing with the Yield Smart Contract for consistent data and accurate reward timing.
Snapshots and Cycles: Periodic snapshots and cycles track participants' in-pool balances for each Yield cycle and snapshot.
Rewards: Rewards are distributed at the end of each cycle, based on the participants' in-pool holdings.
Cycle Workflow
The DEX Rewards contract operates in cycles, each consisting of multiple snapshots, ensuring accurate reward distribution. The DEX Rewards cycle and snapshot indexes are the same with the Yield ones from the beginning, when the Rewards contract is initialized. The process for each cycle is as follows:
Compute Balances: Calculate the balances of the DEX pools participants after each snapshot using
compute-current-snapshot-balances
.Transition to Next Snapshot: Move to the next snapshot with
head-to-next-snapshot
.Conclude Cycle Snapshots: Finalize the data for the last snapshot of the cycle with
conclude-cycle-snapshots
.Enable Rewards Distribution: Allow rewards distribution by calling
set-can-distribute-rewards
.Distribute Rewards: Distribute rewards to participants based on their weight in the DEX protocol using
distribute-rewards
.Move to Next Cycle: Finalize the current cycle and transition to the next with
head-to-next-cycle
.
Public Functions
1. Contract Initialization
initialize-contract
initialize-contract
This function initializes the DEX contract by syncing with the Yield contract. It retrieves the current cycle and snapshot data, resets the state for the new cycle, and activates the contract.
Outputs: Returns
ok true
if successful.Effect:
Syncs with the Yield contract's cycle and snapshot data.
Resets contract state for the new cycle.
Sets the contract as active.
Throws errors if the contract is already active or the caller is not the admin.
2. Snapshots and Cycles
set-snapshot-participants-count
set-snapshot-participants-count
Sets the number of participants for the current snapshot. This function must be called by the admin before computing the snapshot balances.
Parameters:
count
(the number of participants in the snapshot).Outputs: Returns
ok
if successful.Constraints:
Ensures the contract is active.
Ensures the caller is the admin.
Effect:
Verifies that the participants count has not already been set.
Updates the participants count for the current snapshot.
compute-current-snapshot-balances
compute-current-snapshot-balances
Computes the balances of all participants for the current snapshot. The function aggregates balances from all users and updates the snapshot state.
Parameters:
principals
(a list of participant addresses).Outputs: Returns the total balance computed for the current snapshot.
Constraints:
Ensures that the participants count is set.
Effect:
Calls
compute-and-update-balances-one-user
for each participant to aggregate their balances.Updates the snapshot totals and tracks the participants.
head-to-next-snapshot
head-to-next-snapshot
Advances to the next snapshot in the current cycle. This function should be called after the snapshot balances have been computed.
Outputs: Returns
ok
if successful.Constraints:
Ensures all participants have been snapshotted.
Effect:
Updates the cycle totals.
Moves to the next snapshot and updates the snapshot block height.
conclude-cycle-snapshots
conclude-cycle-snapshots
Finalizes the snapshots for the current cycle. This function should be called after the last snapshot has been computed and ensures the cycle is concluded.
Outputs: Returns
ok true
if successful.Constraints:
Ensures that all snapshots have been processed.
Effect:
Aggregates the total from all snapshots for the current cycle.
Marks the cycle as concluded.
head-to-next-cycle
head-to-next-cycle
Advances the contract to the next cycle after all rewards have been distributed.
Outputs: Returns
ok true
if successful.Constraints:
Ensures that all rewards have been distributed.
Effect:
Resets the contract state for the new cycle.
Updates the cycle and snapshot data.
3. Rewards Distribution
set-can-distribute-rewards
set-can-distribute-rewards
Prepares the contract to distribute rewards for the current cycle. This function must be called by the admin.
Outputs: Returns the amount of rewards to be distributed in the current cycle.
Constraints:
Ensures that all snapshots have been concluded.
Effect:
Retrieves the total rewards amount for the current cycle from the Yield contract.
Sets the contract as ready to distribute rewards.
distribute-rewards
distribute-rewards
Distributes rewards to the participants who have been rewarded during the current cycle. The rewards are allocated based on the participant's share of the DEX protocol cycle total.
Parameters:
principals
(a list of participant addresses to distribute rewards to).Outputs: Returns a list of responses, each indicating if rewards were distributed to the specific address in the argument list.
Constraints:
Ensures that rewards distribution is allowed.
Effect:
Distributes the rewards to each participant by calling
distribute-reward-user
for each one.
Private Functions
reset-state-for-cycle
reset-state-for-cycle
Resets the state for a new cycle:
Clears cycle-related variables (like rewards, participants, totals).
Syncs cycle rules with the Yield contract based on the current block.
update-snapshot-for-new-cycle
update-snapshot-for-new-cycle
Resets snapshot-related data for a new cycle:
Clears snapshot participant count, index, and block height.
Initializes the snapshot state with default values.
distribute-reward-user
distribute-reward-user
Helper function that distributes the reward to a single user.
Parameters:
user
(the participant's address).Outputs: Returns
ok true
if successful.Effect:
Checks if the participant is eligible for rewards.
Transfers the computed reward to the participant’s address.
Marks the participant as rewarded.
compute-and-update-balances-one-user
compute-and-update-balances-one-user
Helper function that computes and updates the balance for one participant.
Parameters:
address
(the participant’s address),current-total
(the current total balance).Outputs: Returns the updated total balance after adding the participant’s balance.
Effect:
Fetches the participant’s balance.
Checks if the participant was already snapshotted in the current cycle.
If not, updates the snapshot and cycle state with the new participant's balance.
Read-Only Functions
get-is-yield-active
get-is-yield-active
Checks if the Yield contract is active.
Outputs: Returns a boolean indicating if the Yield contract is active.
yield-contract-current-cycle-stacks-block-height
yield-contract-current-cycle-stacks-block-height
Gets the current cycle's Stacks block height from the Yield contract.
Outputs: Returns the current cycle’s first Stacks block height.
yield-contract-cycle-id
yield-contract-cycle-id
Gets the current cycle ID from the Yield contract.
Outputs: Returns the current cycle ID.
yield-contract-snapshot-index
yield-contract-snapshot-index
Gets the current snapshot index from the Yield contract.
Outputs: Returns the current snapshot index.
get-admin
get-admin
Returns the address of the contract's admin.
Outputs: Returns the admin’s principal.
get-is-contract-active
get-is-contract-active
Checks if the contract is active.
Outputs: Returns a boolean indicating if the contract is active.
Last updated