Skip to content

Conversation

stwiname
Copy link

@stwiname stwiname commented Oct 2, 2025

Implements a Delegation Pool contract

Overview

A Delegation Pool contract that allows aggregation of SQT to be pooled together and used to delegate to indexers.
Delegation should behave the same as if the user had delegated directly to an indexer. There is a manager (owner) of the pool
that determines the delegation strategy to indexers.

Details

Delegation

Users delegate their SQT to the pool and receive pool shares (ERC20 tokens) representing their stake in the pool. The pool manager can then
allocate those funds to the indexers they choose to optimise rewards.

Undelegation

Users can then trigger undelegation which will burn their shares and
start a withdrawal process that then allows the user to withdraw their SQT after the lock period which is the same duration as if they had
directly delegated.

Withdrawls

After the lock period, users can withdraw their SQT and rewards from the pool, minus and pool and unbonding fees.

Managers

The pool manager is responsible for making sure the available assets in the pool are delegated to indexers to earn rewards.
The manager can do all the same functionality as delegating directly to an indexer such as delegate, undelegate, redelegate and claim rewards.
The manager can also trigger auto-compounding of rewards which claims rewards from all indexers as well as set a reward fee.

@ianhe8x ianhe8x requested review from Copilot and ianhe8x October 10, 2025 04:38
Copy link

@Copilot 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 PR implements a comprehensive Delegation Pool contract that allows users to pool their SQT tokens for delegation to indexers, with automated reward management and fee collection. The pool manager can allocate funds to indexers to optimize rewards while users receive ERC20 shares representing their stake.

Key changes:

  • Adds a new DelegationPool contract with delegation, undelegation, and withdrawal functionality
  • Implements era-based share pricing to prevent reward manipulation attacks
  • Provides comprehensive test coverage with 1,340 test lines and mock contracts

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
contracts/DelegationPool.sol Main delegation pool contract implementing ERC20 shares, manager functions, and auto-compounding
test/DelegationPool.test.ts Comprehensive test suite covering all functionality with edge cases and integration tests
contracts/mocks/MockStakingManager.sol Mock contract for testing auto-compound functionality with simulated rewards
contracts/interfaces/IStakingManager.sol Extended interface with delegation and reward management functions
publish/revertcode.json Added error codes (DP001-DP015) for delegation pool specific errors
contracts/RewardsPool.sol Minor type consistency fixes (uint to uint256)
contracts/RewardsBooster.sol Minor type consistency fix (uint to uint256)
CLAUDE.md Added development documentation for AI assistance

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@ianhe8x
Copy link
Contributor

ianhe8x commented Oct 10, 2025

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting

Comment on lines 485 to 520
/**
* @dev Automatic compound rewards for all active delegations
*/
function autoCompound() external {
require(activeIndexers.length > 0, 'DP013');

// Update share price for new era BEFORE claiming rewards
// This ensures any new deposits use the old price (no reward benefit)
_updateSharePriceIfNeeded();

IStakingManager stakingManager = IStakingManager(
settings.getContractAddress(SQContracts.StakingManager)
);
IERC20 sqToken = IERC20(settings.getContractAddress(SQContracts.SQToken));

uint256 rewardsBefore = sqToken.balanceOf(address(this));
stakingManager.batchStakeReward(activeIndexers);
uint256 rewardsAfter = sqToken.balanceOf(address(this));

uint256 totalRewards = rewardsAfter - rewardsBefore;

if (totalRewards == 0) {
return; // No rewards to compound
}

// Calculate and deduct fees from rewards
uint256 feeAmount = 0;
if (feePerMill > 0) {
feeAmount = (totalRewards * feePerMill) / PER_MILL;
accumulatedFees += feeAmount;
emit FeesDeducted(totalRewards, feeAmount);
}

// Add remaining rewards to available assets for compounding
uint256 compoundAmount = totalRewards - feeAmount;
availableAssets += compoundAmount;

Choose a reason for hiding this comment

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

P1 Badge Recompute share price after autoCompound adds rewards

In autoCompound the contract locks the era share price via _updateSharePriceIfNeeded() before calling batchStakeReward and never updates it again once availableAssets increases (lines 488‑520). Deposits executed later in the same era continue minting shares with the stale currentEraSharePrice, so newcomers can buy shares at the pre‑reward rate and capture a portion of the freshly compounded rewards they didn’t contribute. The share price should be recalculated after rewards are added (or rewards should mint new shares) so asset-per-share stays accurate within the era.

Useful? React with 👍 / 👎.

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