Skip to content

Commit

Permalink
Implement Matic to POL unstaking flow
Browse files Browse the repository at this point in the history
  • Loading branch information
evercoinx committed Sep 18, 2024
1 parent 32e5bfa commit 8829142
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 556 deletions.
105 changes: 40 additions & 65 deletions contracts/MaticX.sol
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ contract MaticX is

/// @notice Sends Matic tokens to the current contract and mints MaticX
/// shares to the sender. Requires that the sender has a preliminary
/// approved _amount of Matic to this contract.
/// approved amount of Matic to this contract.
/// @custom:deprecated
/// @param _amount - Amount of Matic tokens sent to this contract
/// @return Amount of generated MaticX shares
function submit(
Expand All @@ -143,8 +144,8 @@ contract MaticX is
}

/// @notice Sends POL tokens to the current contract and mints MaticX shares
/// to the sender. Requires that the sender has a preliminary approved
/// _amount of POL to this contract.
/// to the sender. It requires that the sender has a preliminary approved
/// amount of POL to this contract.
/// @param _amount - Amount of POL tokens sent to this contract
/// @return Amount of generated MaticX shares
function submitPOL(
Expand All @@ -154,8 +155,8 @@ contract MaticX is
}

/// @dev Sends stake tokens to the current contract and mints MaticX shares
/// shares to the sender. Requires that the sender has a preliminary
/// approved _amount of stake tokens to this contract.
/// shares to the sender. It requires that the sender has a preliminary
/// approved amount of stake tokens to this contract.
/// @param depositSender - Address of the sender who is depositing
/// @param _amount - Amount of stake tokens sent to this contract
/// @param _pol - If the POL flow must be used
Expand All @@ -165,7 +166,7 @@ contract MaticX is
address depositSender,
uint256 _amount,
bool _pol
) internal returns (uint256) {
) private returns (uint256) {
require(_amount > 0, "Invalid amount");

address token = _getToken(_pol);
Expand Down Expand Up @@ -204,27 +205,18 @@ contract MaticX is
return mintedAmount;
}

/// @notice Registers a user's request to withdraw Matic tokens.
/// @param _amount - Amount of Matic tokens to be withdrawn
function requestWithdraw(
uint256 _amount
) external override nonReentrant whenNotPaused {
_requestWithdraw(_amount, false);
}

/// @notice Registers a user's request to withdraw POL tokens.
/// @param _amount - Amount of POL tokens to be withdrawn
function requestWithdrawPOL(
function requestWithdraw(
uint256 _amount
) external override nonReentrant whenNotPaused {
_requestWithdraw(_amount, true);
_requestWithdraw(msg.sender, _amount);
}

/// @dev Registers a user's request to withdraw stake tokens.
/// @param _amount - Amount of stake tokens to be withdrawn
/// @param _pol - If the POL flow must be used
/// @dev Registers a user's request to withdraw POL tokens.
/// @param _amount - Amount of POL tokens to be withdrawn
// slither-disable-next-line reentrancy-no-eth
function _requestWithdraw(uint256 _amount, bool _pol) internal {
function _requestWithdraw(address claimer, uint256 _amount) private {
require(_amount > 0, "Invalid amount");

(
Expand All @@ -233,7 +225,7 @@ contract MaticX is
uint256 totalPooledStakeTokens
) = _convertMaticXToStakeToken(_amount);

_burn(msg.sender, _amount);
_burn(claimer, _amount);

uint256 leftAmountToWithdraw = totalAmountToWithdrawInStakeToken;
uint256 totalDelegated = getTotalStakeAcrossAllValidators();
Expand All @@ -250,7 +242,7 @@ contract MaticX is

uint256 currentIdx = 0;
uint256 validatorIdCount = validatorIds.length;
uint256 totalValidatorRequests = validatorIdCount;
uint256 totalAttempts = validatorIdCount;

for (; currentIdx < validatorIdCount; ) {
if (preferredValidatorId == validatorIds[currentIdx]) {
Expand All @@ -261,7 +253,7 @@ contract MaticX is
}
}

while (totalValidatorRequests > 0 && leftAmountToWithdraw > 0) {
while (leftAmountToWithdraw > 0 && totalAttempts > 0) {
uint256 validatorId = validatorIds[currentIdx];
address validatorShare = IStakeManager(stakeManager)
.getValidatorContract(validatorId);
Expand All @@ -275,31 +267,28 @@ contract MaticX is
: leftAmountToWithdraw;

if (amountToWithdrawFromValidator > 0) {
_pol
? IValidatorShare(validatorShare).sellVoucher_newPOL(
amountToWithdrawFromValidator,
type(uint256).max
)
: IValidatorShare(validatorShare).sellVoucher_new(
amountToWithdrawFromValidator,
type(uint256).max
);
IValidatorShare(validatorShare).sellVoucher_newPOL(
amountToWithdrawFromValidator,
type(uint256).max
);

uint256 validatorNonce = IValidatorShare(validatorShare)
.unbondNonces(address(this));
uint256 requestEpoch = IStakeManager(stakeManager).epoch() +
IStakeManager(stakeManager).withdrawalDelay();

userWithdrawalRequests[msg.sender].push(
WithdrawalRequest(
IValidatorShare(validatorShare).unbondNonces(
address(this)
),
IStakeManager(stakeManager).epoch() +
IStakeManager(stakeManager).withdrawalDelay(),
validatorNonce,
requestEpoch,
validatorShare
)
);

leftAmountToWithdraw -= amountToWithdrawFromValidator;
}

--totalValidatorRequests;
--totalAttempts;
currentIdx = currentIdx + 1 < validatorIdCount ? currentIdx + 1 : 0;
}

Expand All @@ -316,38 +305,26 @@ contract MaticX is
);

emit RequestWithdraw(
msg.sender,
claimer,
_amount,
totalAmountToWithdrawInStakeToken
);
}

/// @notice Claims Matic tokens from a validator share and sends them to the
/// user.
/// @param _idx - Array index of the user's withdrawal request
function claimWithdrawal(
uint256 _idx
) external override nonReentrant whenNotPaused {
_claimWithdrawal(msg.sender, _idx, false);
}

/// @notice Claims POL tokens from a validator share and sends them to the
/// user.
/// @param _idx - Array index of the user's withdrawal request
function claimWithdrawalPOL(
function claimWithdrawal(
uint256 _idx
) external override nonReentrant whenNotPaused {
_claimWithdrawal(msg.sender, _idx, true);
_claimWithdrawal(msg.sender, _idx);
}

/// @dev Claims stake tokens from a validator share and sends them to the
/// user.
/// @dev Claims POL tokens from a validator share and sends them to the user.
/// @param _to - Address of the user
/// @param _idx - Array index of the user's withdrawal request
/// @param _pol - If the POL flow must be used
function _claimWithdrawal(address _to, uint256 _idx, bool _pol) internal {
address token = _getToken(_pol);
uint256 balanceBeforeClaim = IERC20Upgradeable(token).balanceOf(
function _claimWithdrawal(address _to, uint256 _idx) private {
uint256 balanceBeforeClaim = IERC20Upgradeable(polToken).balanceOf(
address(this)
);

Expand All @@ -360,21 +337,19 @@ contract MaticX is
"Not able to claim yet"
);

_pol
? IValidatorShare(userRequest.validatorAddress)
.unstakeClaimTokens_newPOL(userRequest.validatorNonce)
: IValidatorShare(userRequest.validatorAddress)
.unstakeClaimTokens_new(userRequest.validatorNonce);
IValidatorShare(userRequest.validatorAddress).unstakeClaimTokens_newPOL(
userRequest.validatorNonce
);

// swap with the last item and pop it.
userRequests[_idx] = userRequests[userRequests.length - 1];
userRequests.pop();

uint256 amountToClaim = IERC20Upgradeable(token).balanceOf(
uint256 amountToClaim = IERC20Upgradeable(polToken).balanceOf(
address(this)
) - balanceBeforeClaim;

IERC20Upgradeable(token).safeTransfer(_to, amountToClaim);
IERC20Upgradeable(polToken).safeTransfer(_to, amountToClaim);

emit ClaimWithdrawal(_to, _idx, amountToClaim);
}
Expand Down Expand Up @@ -418,7 +393,7 @@ contract MaticX is
function _withdrawRewards(
uint256 _validatorId,
bool _pol
) internal returns (uint256) {
) private returns (uint256) {
address validatorShare = IStakeManager(stakeManager)
.getValidatorContract(_validatorId);

Expand Down Expand Up @@ -460,7 +435,7 @@ contract MaticX is
function _stakeRewardsAndDistributeFees(
uint256 _validatorId,
bool _pol
) internal {
) private {
require(
IValidatorRegistry(validatorRegistry).validatorIdExists(
_validatorId
Expand Down
20 changes: 6 additions & 14 deletions contracts/interfaces/IMaticX.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,37 +99,29 @@ interface IMaticX is IERC20Upgradeable {
event SetPOLToken(address _address);

/// @notice Sends Matic tokens to the current contract and mints MaticX
/// shares to the sender. Requires that the sender has a preliminary
/// approved _amount of Matic to this contract.
/// shares to the sender. It requires that the sender has a preliminary
/// approved amount of Matic to this contract.
/// @custom:deprecated
/// @param _amount - Amount of Matic tokens sent to this contract
/// @return Amount of generated MaticX shares
function submit(uint256 _amount) external returns (uint256);

/// @notice Sends POL tokens to the current contract and mints MaticX shares
/// to the sender. Requires that the sender has a preliminary approved
/// to the sender. It requires that the sender has a preliminary approved
/// _amount of POL to this contract.
/// @param _amount - Amount of POL tokens sent to this contract
/// @return Amount of generated MaticX shares
function submitPOL(uint256 _amount) external returns (uint256);

/// @notice Registers a user's request to withdraw Matic tokens.
/// @param _amount - Amount of Matic tokens to be withdrawn
/// @notice Registers a user's request to withdraw pol tokens.
/// @param _amount - Amount of stake tokens to be withdrawn
function requestWithdraw(uint256 _amount) external;

/// @notice Registers a user's request to withdraw POL tokens.
/// @param _amount - Amount of POL tokens to be withdrawn
function requestWithdrawPOL(uint256 _amount) external;

/// @notice Claims Matic tokens from a validator share and sends them to the
/// user.
/// @param _idx - Array index of the user's withdrawal request
function claimWithdrawal(uint256 _idx) external;

/// @notice Claims POL tokens from a validator share and sends them to the
/// user.
/// @param _idx - Array index of the user's withdrawal request
function claimWithdrawalPOL(uint256 _idx) external;

/// @notice Withdraws Matic rewards from a given validator.
/// @custom:deprecated
/// @param _validatorId - Validator id to withdraw Matic rewards
Expand Down
Loading

0 comments on commit 8829142

Please sign in to comment.