Skip to content

Conversation

@Spagero763
Copy link

Description

Describe the changes that were made in this pull request. When possible start with the motivations behind the change.

@Spagero763 Spagero763 requested a review from a team as a code owner January 21, 2026 17:04
Copilot AI review requested due to automatic review settings January 21, 2026 17:04
@CLAassistant
Copy link

CLAassistant commented Jan 21, 2026

CLA assistant check
All committers have signed the CLA.

Added an overview section to the Dual Stacking Smart Contract documentation.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request removes the entire content of the Dual Stacking Smart Contract documentation file (660 lines of comprehensive documentation) and replaces it with a single title line: "# Dual Stacking Smart Contract - 2026 Edition". The PR title indicates an update, but no description is provided to explain the rationale for this massive content deletion.

Changes:

  • Deletion of all Dual Stacking Smart Contract documentation including overview, architecture, formulas, workflow, and function references
  • Replacement with a single title line referencing "2026 Edition"

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 2 to 3

## Overview
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The entire documentation content (660 lines) has been removed and replaced with only a title. This appears to be an unintentional deletion that removes all detailed information about the Dual Stacking Smart Contract, including its overview, cycle structure, formulas, workflow, and all public/private function documentation. If this deletion is intentional, it should be explained in the PR description. Otherwise, this change should be reverted to preserve the comprehensive documentation.

Suggested change
## Overview
This document describes the design and behavior of the Dual Stacking Smart Contract.
It is intended for protocol contributors, auditors, and integrators who need a clear
understanding of how dual stacking works at a conceptual and API level.
> **Note:** This is documentation only; it does not define protocol rules. If there is
> any discrepancy between this document and the deployed contract code, the code is
> authoritative.
## Overview
Dual stacking allows a user to lock a base asset in a way that participates in **two**
concurrent reward streams (for example, protocol-native staking rewards and an
additional incentive program) without duplicating the underlying principal.
At a high level:
- Users deposit a supported asset into the Dual Stacking contract.
- The contract tracks the deposit in **cycles**, with each cycle having:
- A start and end block/timestamp.
- A reward budget for each of the two reward streams.
- Within each cycle, rewards are distributed proportionally to each user’s effective
stake (adjusted for time and any multipliers).
- Users can:
- Stake / increase stake.
- Unstake / withdraw (optionally subject to cooldowns or penalties).
- Claim accumulated rewards from one or both reward streams.
The contract is designed to:
- Prevent double-counting of stake across the two reward streams.
- Allow predictable, cycle-based reward accounting.
- Support upgrades to reward parameters (rates, caps, cycle length) via governance.
## Cycle Structure
Dual stacking operates in discrete **cycles**. A cycle is the primary accounting unit
for rewards. Each cycle is identified by a monotonically increasing `cycleId`.
Typical fields tracked per cycle include:
- `cycleId`: Unique identifier for the cycle.
- `startTime` / `endTime` (or `startBlock` / `endBlock`):
- Defines the active window for reward accrual.
- `totalBaseStaked`:
- Total base asset effectively staked during the cycle across all users.
- `rewardPoolA` and `rewardPoolB`:
- Total reward amounts allocated to reward stream A and reward stream B.
- `emissionRateA` and `emissionRateB` (optional, if rewards are rate-based).
- `isFinalized`:
- Whether the cycle’s reward data is sealed (no further parameter changes allowed).
Cycle progression:
1. **Initialization:** governance or an authorized role creates a new cycle with
defined parameters (duration, reward amounts, etc.).
2. **Active:** during the active window, user stake changes affect their share of the
cycle’s rewards.
3. **Finalization:** when the cycle ends, reward totals and accounting are frozen,
and users can claim rewards for that cycle at any time thereafter.
## Reward Formulas
The contract defines deterministic formulas to calculate:
- Effective stake per user.
- Per-cycle reward share for each reward stream.
- Penalties for early exit (if applicable).
In the simplest proportional model:
- Let:
- `S_u` be the user’s effective stake in a given cycle.
- `S_total` be the total effective stake for the cycle.
- `R_A` be the total reward pool for reward stream A in that cycle.
- `R_B` be the total reward pool for reward stream B in that cycle.
Then the user’s rewards for cycle `c` are:
- `rewardA_u(c) = (S_u / S_total) * R_A`
- `rewardB_u(c) = (S_u / S_total) * R_B`
Time-weighted variants:
- If stake can change mid-cycle, an *effective stake* can be computed via:
- `S_u = ∑ (amount_u,i * duration_u,i) / cycleDuration`
where `amount_u,i` is a stake level held for `duration_u,i` time.
Caps and floors:
- Implementations may define:
- Per-user max rewards per cycle.
- Global caps for each reward stream.
- Minimum stake thresholds for participation.
Any such constraints must be enforced consistently in the reward computation
functions and clearly expressed in the contract’s events and revert messages.
## Workflow
This section describes the typical lifecycle for a user interacting with the
Dual Stacking Smart Contract.
### 1. Staking / Depositing
1. User approves the Dual Stacking contract to transfer their base asset
(for ERC-20-style assets).
2. User calls `stake` (or an equivalent method) with:
- The amount to stake.
- Optionally, a minimum cycle or lockup preference.
3. The contract:
- Transfers the asset from the user to itself.
- Updates the user’s stake record.
- Updates the active cycle’s `totalBaseStaked`.
- Emits a `Staked` event.
### 2. Accruing Rewards
- While the user is staked during an active cycle:
- Their effective stake contributes to both reward streams.
- Accounting is updated such that later calls to `claimRewards` can compute the
correct reward amount.
### 3. Claiming Rewards
- Users can claim rewards by:
- Calling `claimRewards()` to claim all due rewards, or
- Calling `claimRewardsForCycles(cycleIds[])` to specify cycles.
- The contract:
- Calculates unclaimed rewards for the user for each selected cycle.
- Updates claimed amounts to prevent double-claims.
- Transfers the appropriate reward tokens to the user.
- Emits a `RewardsClaimed` event.
### 4. Unstaking / Withdrawing
- Users can reduce stake via:
- `unstake(amount)` or `withdraw(amount)`.
- Depending on configuration:
- There may be a cooldown delay between request and withdrawal.
- Early exits may incur a penalty that:
- Burns a portion of stake, or
- Redirects it to a treasury / insurance fund.
- The contract emits an `Unstaked` (or `Withdrawn`) event.
### 5. Administrative Actions
- Governance or an authorized admin can:
- Create or finalize cycles.
- Adjust reward pool sizes for upcoming cycles.
- Pause or unpause key operations if a security issue is discovered.
## Public Interface
This section lists the typical public (externally callable) functions exposed by a
Dual Stacking Smart Contract. Exact names and signatures may vary slightly between
deployments, but the semantics should be equivalent.
### Staking and Unstaking
- `stake(amount)`
Stake the base asset into the contract.
**Effects:**
- Transfers `amount` of the base asset from `msg.sender` to the contract.
- Increases the sender’s recorded stake.
- Updates cycle-level totals.
- Emits `Staked(sender, amount, cycleId)`.
- `unstake(amount)` / `withdraw(amount)`
Request withdrawal of previously staked assets.
**Effects:**
- Reduces the sender’s recorded stake (subject to bounds checks).
- Transfers `amount` back to the sender (or registers a pending withdrawal).
- May apply penalties or cooldown logic.
- Emits `Unstaked(sender, amount, cycleId)` or equivalent.
### Rewards
- `claimRewards()`
Claim all unclaimed rewards for both streams across all claimable cycles.
**Effects:**
- Computes claimant’s pending rewards.
- Updates internal storage so those rewards cannot be claimed again.
- Transfers reward tokens to the claimant.
- Emits `RewardsClaimed(sender, rewardA, rewardB, fromCycleId, toCycleId)`.
- `claimRewardsForCycles(cycleIds[])`
Claim rewards for a specific set of cycles.
**Effects and constraints:**
- Similar to `claimRewards()` but limited to specified cycles.
- Reverts if any cycle is not yet finalized or otherwise ineligible.
### View / Read-Only Functions
- `getUserStake(address user)``uint256`
Returns the current effective stake of `user`.
- `getPendingRewards(address user)``(uint256 rewardA, uint256 rewardB)`
Computes unclaimed rewards for `user` across all finalized cycles.
- `getCycle(uint256 cycleId)``(Cycle memory)`
Returns the metadata for the given cycle.
- `getCurrentCycleId()``uint256`
Returns the identifier of the active cycle (if any).
- `getConfig()``(Config memory)`
Returns the current configuration (reward tokens, addresses, flags).
### Administrative / Governance Functions
- `createCycle(params)`
Initializes a new cycle with specified parameters.
- `finalizeCycle(uint256 cycleId)`
Marks a cycle as finalized and seals its reward parameters.
- `setRewardPools(uint256 cycleId, uint256 rewardA, uint256 rewardB)`
Sets or updates the reward pools for a *future* or *current but not finalized* cycle.
- `pause()` / `unpause()`
Enables or disables sensitive operations (staking, unstaking, claiming) in
case of emergencies.
- `setConfig(Config newConfig)`
Updates configuration fields controlled by governance.
All admin functions should:
- Be restricted to a governance or admin role.
- Emit informative events on state changes.
- Avoid retroactive changes to finalized cycles.
## Internal / Private Logic
While external callers cannot invoke internal/private functions directly, they
are critical for understanding how the contract maintains correctness. The typical
categories are:
- **Accounting helpers**
- `updateUserRewards(address user)`:
- Updates a user’s stored reward state based on latest cycle data.
- `updateGlobalStakeTotals()`:
- Keeps per-cycle totals in sync with user-level stake changes.
- **Cycle management**
- `_createCycleInternal(params)`:
- Common logic for initializing a cycle used by `createCycle`.
- `_finalizeCycleInternal(cycleId)`:
- Seals reward pools and prevents further changes for the given cycle.
- **Validation / guard checks**
- `_onlyGovernance()`:
- Restricts certain calls to the governance address.
- `_ensureCycleActiveOrUpcoming(cycleId)`:
- Ensures that operations are applied only to valid cycles.
These internal functions should:
- Keep state transitions atomic and well-documented via events.
- Enforce all necessary invariants (no negative balances, no double-claims, etc.).
- Reuse code across multiple public functions to avoid inconsistencies.
## Events
Typical events emitted by the Dual Stacking contract include:
- `event Staked(address indexed user, uint256 amount, uint256 cycleId);`
- `event Unstaked(address indexed user, uint256 amount, uint256 cycleId);`
- `event RewardsClaimed(address indexed user, uint256 rewardA, uint256 rewardB, uint256 fromCycleId, uint256 toCycleId);`
- `event CycleCreated(uint256 indexed cycleId, uint256 startTime, uint256 endTime, uint256 rewardA, uint256 rewardB);`
- `event CycleFinalized(uint256 indexed cycleId);`
- `event RewardPoolsUpdated(uint256 indexed cycleId, uint256 rewardA, uint256 rewardB);`
- `event Paused(address indexed account);`
- `event Unpaused(address indexed account);`
- `event ConfigUpdated(address indexed updater);`
Events are essential for:
- Off-chain indexers and UIs to reconstruct user positions and rewards.
- Auditors to inspect protocol behavior over time.
- Debugging and incident response.
## Security Considerations
When reviewing or modifying the Dual Stacking Smart Contract implementation,
particular attention should be paid to:
- **Reentrancy**:
- External token transfers (base asset, reward tokens) should be ordered
after state updates and guarded by a reentrancy lock if necessary.
- **Access control**:
- All admin and governance functions must be restricted to the appropriate
role(s) and tested with negative test cases.
- **Reward exhaustion**:
- Ensure reward pools cannot be over-distributed due to rounding or race
conditions when cycles are finalized.
- **Precision and rounding**:
- Reward calculations should be carefully audited to avoid systemic bias in
favor of either small or large stakers.
- **Upgradeability** (if used):
- Clearly define upgrade paths and any initialization routines.
- Avoid storage layout collisions.
## Integration Guidelines
For frontends and integrators:
- Use **view** functions to present:
- Current cycle information.
- User’s current stake and pending rewards.
- Always:
- Listen to events to keep off-chain state synchronized.
- Consider gas costs when batching multiple user actions.
- Clearly display:
- Lockup periods.
- Potential penalties for early unstaking.
- Any special conditions required to receive rewards from both streams.
## Appendix: Terminology
- **Base asset**: The token users stake (e.g., a governance or utility token).
- **Reward stream A / B**: Two logically separate reward flows associated with
a single staked position.
- **Cycle**: A discrete time or block interval over which rewards are accrued
and later claimable.
- **Effective stake**: Stake adjusted for time and any weighting rules used in
reward computation.
This document replaces earlier, more fragmented descriptions of the Dual Stacking
Smart Contract and is intended to serve as the single reference for its behavior
at a high level.

Copilot uses AI. Check for mistakes.
Added current version information for the dual stacking contract.
Added link to the live dual stacking contract on mainnet.
Copy link
Author

@Spagero763 Spagero763 left a comment

Choose a reason for hiding this comment

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

d

Added details about the v2.0.2 upgrade features for the dual stacking smart contract.
Added details about decentralized architecture features including permissionless operations, on-chain data usage, competitive ratio discovery, transparent execution, and self-service enrollment.
Copy link
Author

@Spagero763 Spagero763 left a comment

Choose a reason for hiding this comment

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

d

Added a stepper section to the dual-stacking smart contract documentation.
Added details about user enrollment and participation options.
Added note about enrollment status display in the web app dashboard.
Added a section on Snapshots and Cycles to the dual-stacking smart contract documentation.
Added a new section on Ratio Computation.
Added a new section on weight calculation after ratio computation.
Added information about participant weight calculations and boost.
Copy link
Author

@Spagero763 Spagero763 left a comment

Choose a reason for hiding this comment

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

g

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.

2 participants