Skip to content

Commit

Permalink
Merge pull request #1231 from NexusMutual/release-candidate
Browse files Browse the repository at this point in the history
feat: StakingPool fixes + batch NXM withdrawals v2.8.0
  • Loading branch information
rackstar authored Sep 4, 2024
2 parents facaada + e1768c2 commit fb7975b
Show file tree
Hide file tree
Showing 97 changed files with 3,808 additions and 1,407 deletions.
23 changes: 21 additions & 2 deletions contracts/interfaces/IAssessment.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ interface IAssessment {

function getVoteCountOfAssessor(address assessor) external view returns (uint);

function votesOf(address user, uint id) external view
function votesOf(address user, uint voteIndex) external view
returns (uint80 assessmentId, bool accepted, uint32 timestamp, uint96 stakedAmount);

function stakeOf(address user) external view
Expand All @@ -122,7 +122,7 @@ interface IAssessment {
uint8 silentEndingPeriodInDays
);

function hasAlreadyVotedOn(address voter, uint pollId) external view returns (bool);
function hasAlreadyVotedOn(address voter, uint assessmentId) external view returns (bool);


/* === MUTATIVE FUNCTIONS ==== */
Expand All @@ -131,6 +131,8 @@ interface IAssessment {

function unstake(uint96 amount, address to) external;

function unstakeAllFor(address staker) external;

function withdrawRewards(
address user,
uint104 batchSize
Expand Down Expand Up @@ -174,4 +176,21 @@ interface IAssessment {
event FraudProcessed(uint assessmentId, address assessor, Poll poll);
event FraudSubmitted(bytes32 root);

/* ========== ERRORS ========== */

error InvalidAmount(uint maxUnstakeAmount);
error StakeLockedForAssessment(uint lockupExpiry);
error StakeLockedForGovernance(uint lockupExpiry);
error NotMember(address nonMember);
error NoWithdrawableRewards();
error InvalidMerkleProof();
error OnlyTokenController();

// Votes
error AssessmentIdsVotesLengthMismatch();
error AssessmentIdsIpfsLengthMismatch();
error AlreadyVoted();
error StakeRequired();
error VotingClosed();
error AcceptVoteRequired();
}
3 changes: 3 additions & 0 deletions contracts/interfaces/ICover.sol
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,7 @@ interface ICover {
error CoverNotYetExpired(uint coverId);
error InsufficientCoverAmountAllocated();
error UnexpectedPoolId();

// TODO: remove me after the rewards update
error OnlySwapOperator();
}
19 changes: 15 additions & 4 deletions contracts/interfaces/IStakingPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,20 @@ interface IStakingPool {
uint128 rewardsShares;
}

struct WithdrawTrancheContext {
uint _firstActiveTrancheId;
uint _accNxmPerRewardsShare;
uint managerLockedInGovernanceUntil;
bool withdrawStake;
bool withdrawRewards;
address destination;
}

function initialize(
bool isPrivatePool,
uint initialPoolFee,
uint maxPoolFee,
uint _poolId,
string memory ipfsDescriptionHash
uint _poolId
) external;

function processExpirations(bool updateUntilCurrentTimestamp) external;
Expand Down Expand Up @@ -149,6 +157,11 @@ interface IStakingPool {
uint reductionRatio
) external view returns (uint[] memory trancheCapacities);

function updateRewardsShares(
uint trancheId,
uint[] calldata tokenIds
) external;

/* ========== EVENTS ========== */

event StakeDeposited(address indexed user, uint256 amount, uint256 trancheId, uint256 tokenId);
Expand All @@ -159,8 +172,6 @@ interface IStakingPool {

event PoolFeeChanged(address indexed manager, uint newFee);

event PoolDescriptionSet(string ipfsDescriptionHash);

event Withdraw(address indexed user, uint indexed tokenId, uint tranche, uint amountStakeWithdrawn, uint amountRewardsWithdrawn);

event StakeBurned(uint amount);
Expand Down
10 changes: 10 additions & 0 deletions contracts/interfaces/IStakingProducts.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ interface IStakingProducts {
uint bumpedPriceUpdateTime
);

function getPoolManager(uint poolId) external view returns (address);

/* ============= PRICING FUNCTIONS ============= */

function getPremium(
Expand Down Expand Up @@ -117,6 +119,12 @@ interface IStakingProducts {

function changeStakingPoolFactoryOperator(address newOperator) external;

function setPoolMetadata(uint poolId, string memory ipfsHash) external;

function getPoolMetadata(uint poolId) external view returns (string memory ipfsHash);

function setInitialMetadata(string[] calldata ipfsHashes) external;

/* ============= EVENTS ============= */

event ProductUpdated(uint productId, uint8 targetWeight, uint96 targetPrice);
Expand All @@ -143,4 +151,6 @@ interface IStakingProducts {
error InvalidProductType();
error TargetPriceBelowGlobalMinPriceRatio();

// IPFS
error IpfsHashRequired();
}
1 change: 1 addition & 0 deletions contracts/interfaces/IStakingViewer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface IStakingViewer {
uint maxPoolFee;
uint activeStake;
uint currentAPY;
string metadataIpfsHash;
}

struct StakingProduct {
Expand Down
28 changes: 27 additions & 1 deletion contracts/interfaces/ISwapOperator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
pragma solidity >=0.5.0;

import "../external/cow/GPv2Order.sol";
import "../interfaces/IPool.sol";
import "../external/enzyme/IEnzymeFundValueCalculatorRouter.sol";
import "./ICowSettlement.sol";
import "./INXMMaster.sol";
import "./IPool.sol";
import "./IWeth.sol";

interface ISwapOperator {

Expand All @@ -21,6 +25,28 @@ interface ISwapOperator {

function orderInProgress() external view returns (bool);

function currentOrderUID() external view returns (bytes memory);

/* ========== IMMUTABLES ========== */

function cowSettlement() external view returns (ICowSettlement);

function cowVaultRelayer() external view returns (address);

function master() external view returns (INXMMaster);

function swapController() external view returns (address);

function weth() external view returns (IWeth);

function domainSeparator() external view returns (bytes32);

function enzymeV4VaultProxyAddress() external view returns (address);

function enzymeFundValueCalculatorRouter() external view returns (IEnzymeFundValueCalculatorRouter);

function minPoolEth() external view returns (uint);

/* ==== MUTATIVE FUNCTIONS ==== */

function placeOrder(GPv2Order.Data calldata order, bytes calldata orderUID) external;
Expand Down
95 changes: 61 additions & 34 deletions contracts/interfaces/ITokenController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,74 @@ interface ITokenController {
uint96 deadline;
}

struct WithdrawAssessment {
bool stake;
bool rewards;
}

/// @notice The stake deposit / rewards in a staking pool that will be withdrawn.
/// @dev Call StakingViewer.getToken to get tokenId / trancheId information
/// @param tokenId The ID of the token stake deposit / rewards that will be withrawn.
/// @param trancheIds An array of tranche IDs representing the tranches where the stake was deposited.
struct StakingPoolDeposit {
uint tokenId;
uint[] trancheIds;
}

/// @notice Represents the rewards distributed to a staking pool manager.
/// @dev Call StakingViewer.getManagerTokenRewardsByAddr to get poolId / trancheId information
/// @param poolId The ID of the pool managed by the manager.
/// @param trancheIds An array of tranche IDs representing the tranches where the manager rewards were distributed.
struct StakingPoolManagerReward {
uint poolId;
uint[] trancheIds;
}

/* ========== VIEWS ========== */

function token() external view returns (INXMToken);

function coverInfo(uint id) external view returns (
uint16 claimCount,
bool hasOpenClaim,
bool hasAcceptedClaim,
uint96 requestedPayoutAmount
);

function getLockReasons(address _of) external view returns (bytes32[] memory reasons);

function totalSupply() external view returns (uint);

function totalBalanceOf(address _of) external view returns (uint amount);

function totalBalanceOfWithoutDelegations(address _of) external view returns (uint amount);

function getTokenPrice() external view returns (uint tokenPrice);

function getPendingRewards(address member) external view returns (uint);

function tokensLocked(address _of, bytes32 _reason) external view returns (uint256 amount);

function getWithdrawableCoverNotes(
address coverOwner
) external view returns (
uint[] memory coverIds,
bytes32[] memory lockReasons,
uint withdrawableAmount
);

function getStakingPoolManager(uint poolId) external view returns (address manager);

function getManagerStakingPools(address manager) external view returns (uint[] memory poolIds);

function isStakingPoolManager(address member) external view returns (bool);

function getStakingPoolOwnershipOffer(uint poolId) external view returns (address proposedManager, uint deadline);

function stakingPoolNXMBalances(uint poolId) external view returns (uint128 rewards, uint128 deposits);

/* ========== MUTATIVE FUNCTIONS ========== */

function withdrawCoverNote(
address _of,
uint[] calldata _coverIds,
Expand All @@ -53,26 +114,6 @@ interface ITokenController {

function withdrawClaimAssessmentTokens(address[] calldata users) external;

function getLockReasons(address _of) external view returns (bytes32[] memory reasons);

function totalSupply() external view returns (uint);

function totalBalanceOf(address _of) external view returns (uint amount);

function totalBalanceOfWithoutDelegations(address _of) external view returns (uint amount);

function getTokenPrice() external view returns (uint tokenPrice);

function token() external view returns (INXMToken);

function getStakingPoolManager(uint poolId) external view returns (address manager);

function getManagerStakingPools(address manager) external view returns (uint[] memory poolIds);

function isStakingPoolManager(address member) external view returns (bool);

function getStakingPoolOwnershipOffer(uint poolId) external view returns (address proposedManager, uint deadline);

function transferStakingPoolsOwnership(address from, address to) external;

function assignStakingPoolManager(uint poolId, address manager) external;
Expand All @@ -92,18 +133,4 @@ interface ITokenController {
function withdrawNXMStakeAndRewards(address to, uint stakeToWithdraw, uint rewardsToWithdraw, uint poolId) external;

function burnStakedNXM(uint amount, uint poolId) external;

function stakingPoolNXMBalances(uint poolId) external view returns(uint128 rewards, uint128 deposits);

function tokensLocked(address _of, bytes32 _reason) external view returns (uint256 amount);

function getWithdrawableCoverNotes(
address coverOwner
) external view returns (
uint[] memory coverIds,
bytes32[] memory lockReasons,
uint withdrawableAmount
);

function getPendingRewards(address member) external view returns (uint);
}
43 changes: 2 additions & 41 deletions contracts/mocks/SafeTracker/STMockSwapOperator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,8 @@

pragma solidity ^0.8.18;

import "../../interfaces/ISwapOperator.sol";
import "../generic/SwapOperatorGeneric.sol";

contract STMockSwapOperator is ISwapOperator {
contract STMockSwapOperator is SwapOperatorGeneric {

function requestAsset(address, uint) external virtual pure {
revert("Unsupported");
}

function transferRequestedAsset(address, uint) external virtual pure {
revert("Unsupported");
}

function getDigest(GPv2Order.Data calldata) external virtual view returns (bytes32) {
revert("Unsupported");
}

function getUID(GPv2Order.Data calldata) external virtual view returns (bytes memory) {
revert("Unsupported");
}

function orderInProgress() external virtual pure returns (bool) {
revert("Unsupported");
}

function placeOrder(GPv2Order.Data calldata, bytes calldata) external virtual {
revert("Unsupported");
}

function closeOrder(GPv2Order.Data calldata) external virtual {
revert("Unsupported");
}

function swapEnzymeVaultShareForETH(uint, uint) external virtual {
revert("Unsupported");
}

function swapETHForEnzymeVaultShare(uint, uint) external virtual {
revert("Unsupported");
}

function recoverAsset(address, address) external virtual {
revert("Unsupported");
}
}
11 changes: 9 additions & 2 deletions contracts/mocks/disposables/DisposableTokenController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@ contract DisposableTokenController is TokenController {
address quotationDataAddress,
address claimsRewardAddress,
address stakingPoolFactoryAddress,
address tokenAddress
) TokenController(quotationDataAddress, claimsRewardAddress, stakingPoolFactoryAddress, tokenAddress) {}
address tokenAddress,
address stakingNFTAddress
) TokenController(
quotationDataAddress,
claimsRewardAddress,
stakingPoolFactoryAddress,
tokenAddress,
stakingNFTAddress
) {}

function initialize(
address payable _masterAddress,
Expand Down
Loading

0 comments on commit fb7975b

Please sign in to comment.