Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Commit

Permalink
new: independent shares exits
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Ermolin committed Dec 28, 2020
1 parent 39825c2 commit 464be11
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 11 deletions.
8 changes: 5 additions & 3 deletions contracts/staking/StakingInfo.sol
Expand Up @@ -155,7 +155,8 @@ contract StakingInfo is Ownable {
uint256 indexed validatorId,
address indexed user,
uint256 indexed amount,
uint256 tokens
uint256 tokens,
uint256 burnId
);
event DelegatorClaimedRewards(
uint256 indexed validatorId,
Expand Down Expand Up @@ -466,9 +467,10 @@ contract StakingInfo is Ownable {
uint256 validatorId,
address user,
uint256 amount,
uint256 tokens
uint256 tokens,
uint256 burnId
) public onlyValidatorContract(validatorId) {
emit ShareBurned(validatorId, user, amount, tokens);
emit ShareBurned(validatorId, user, amount, tokens, burnId);
}

function logDelegatorClaimRewards(
Expand Down
66 changes: 58 additions & 8 deletions contracts/staking/validatorShare/ValidatorShare.sol
Expand Up @@ -7,13 +7,9 @@ import {OwnableLockable} from "../../common/mixin/OwnableLockable.sol";
import {IStakeManager} from "../stakeManager/IStakeManager.sol";
import {IValidatorShare} from "./IValidatorShare.sol";
import {Initializable} from "../../common/mixin/Initializable.sol";
import {ValidatorShareStorageExtension} from "./ValidatorShareStorageExtension.sol";

contract ValidatorShare is IValidatorShare, ERC20NonTransferable, OwnableLockable, Initializable {
struct DelegatorUnbond {
uint256 shares;
uint256 withdrawEpoch;
}

contract ValidatorShare is IValidatorShare, ERC20NonTransferable, OwnableLockable, Initializable, ValidatorShareStorageExtension {
uint256 constant EXCHANGE_RATE_PRECISION = 100;
// maximum matic possible, even if rate will be 1 and all matic will be staken in one go, it will result in 10 ^ 58 shares
uint256 constant EXCHANGE_RATE_HIGH_PRECISION = 10**29;
Expand Down Expand Up @@ -153,7 +149,7 @@ contract ValidatorShare is IValidatorShare, ERC20NonTransferable, OwnableLockabl
unbonds[msg.sender] = unbond;

StakingInfo logger = stakingLogger;
logger.logShareBurned(validatorId, msg.sender, claimAmount, shares);
logger.logShareBurned(validatorId, msg.sender, claimAmount, shares, 0);
logger.logStakeUpdate(validatorId);
}

Expand All @@ -173,7 +169,7 @@ contract ValidatorShare is IValidatorShare, ERC20NonTransferable, OwnableLockabl

stakeManager.updateValidatorState(validatorId, -int256(amount));

stakingLogger.logShareBurned(validatorId, user, amount, shares);
stakingLogger.logShareBurned(validatorId, user, amount, shares, 0);
stakingLogger.logStakeUpdate(validatorId);
stakingLogger.logDelegatorUnstaked(validatorId, user, amount);
}
Expand Down Expand Up @@ -236,6 +232,60 @@ contract ValidatorShare is IValidatorShare, ERC20NonTransferable, OwnableLockabl
}
}

/**
New shares exit API
*/

function sellVoucher_new(uint256 claimAmount, uint256 maximumSharesToBurn) public {
// first get how much staked in total and compare to target unstake amount
(uint256 totalStaked, uint256 rate) = getTotalStake(msg.sender);
require(totalStaked > 0 && totalStaked >= claimAmount, "Too much requested");

// convert requested amount back to shares
uint256 precision = _getRatePrecision();
uint256 shares = claimAmount.mul(precision).div(rate);
require(shares <= maximumSharesToBurn, "too much slippage");

_withdrawAndTransferReward(msg.sender);

_burn(msg.sender, shares);
stakeManager.updateValidatorState(validatorId, -int256(claimAmount));

uint256 _withdrawPoolShare = claimAmount.mul(precision).div(withdrawExchangeRate());
withdrawPool = withdrawPool.add(claimAmount);
withdrawShares = withdrawShares.add(_withdrawPoolShare);

uint256 unbondNonce = unbondNonces[msg.sender].add(1);

DelegatorUnbond memory unbond = DelegatorUnbond({
shares: _withdrawPoolShare,
withdrawEpoch: stakeManager.epoch()
});
unbonds_new[msg.sender][unbondNonce] = unbond;
unbondNonces[msg.sender] = unbondNonce;

StakingInfo logger = stakingLogger;
logger.logShareBurned(validatorId, msg.sender, claimAmount, shares, unbondNonce);
logger.logStakeUpdate(validatorId);
}

function unstakeClaimTokens_new(uint256 unbondNonce) public {
DelegatorUnbond memory unbond = unbonds_new[msg.sender][unbondNonce];
uint256 shares = unbond.shares;
require(
unbond.withdrawEpoch.add(stakeManager.withdrawalDelay()) <= stakeManager.epoch() && shares > 0,
"Incomplete withdrawal period"
);

uint256 _amount = withdrawExchangeRate().mul(shares).div(_getRatePrecision());
withdrawShares = withdrawShares.sub(shares);
withdrawPool = withdrawPool.sub(_amount);

require(stakeManager.transferFunds(validatorId, _amount, msg.sender), "Insufficent rewards");
stakingLogger.logDelegatorUnstaked(validatorId, msg.sender, _amount);
delete unbonds_new[msg.sender][unbondNonce];
}

/**
Private Methods
*/
Expand Down
@@ -0,0 +1,11 @@
pragma solidity 0.5.17;

contract ValidatorShareStorageExtension {
struct DelegatorUnbond {
uint256 shares;
uint256 withdrawEpoch;
}

mapping(address => uint256) public unbondNonces;
mapping(address => mapping(uint256 => DelegatorUnbond)) public unbonds_new;
}

0 comments on commit 464be11

Please sign in to comment.