Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[M01] Complicated state updates #539

Merged
merged 5 commits into from Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
171 changes: 116 additions & 55 deletions eth-contracts/contracts/DelegateManager.sol
Expand Up @@ -143,22 +143,23 @@ contract DelegateManager is InitializableV2 {
);
}

// Update total delegated for SP
spDelegateInfo[_targetSP].totalDelegatedStake = (
spDelegateInfo[_targetSP].totalDelegatedStake.add(_amount)
// Update following values in storage through helper
// totalServiceProviderDelegatedStake = current sp total + new amount,
// totalStakedForSpFromDelegator = current delegator total for sp + new amount,
// totalDelegatorStake = current delegator total + new amount
_updateDelegatorStake(
delegator,
_targetSP,
spDelegateInfo[_targetSP].totalDelegatedStake.add(_amount),
delegateInfo[delegator][_targetSP].add(_amount),
delegatorStakeTotal[delegator].add(_amount)
);

// Update amount staked from this delegator to targeted service provider
delegateInfo[delegator][_targetSP] = delegateInfo[delegator][_targetSP].add(_amount);

// Update total delegated stake
delegatorStakeTotal[delegator] = delegatorStakeTotal[delegator].add(_amount);

require(
delegatorStakeTotal[delegator] >= minDelegationAmount,
"Minimum delegation amount"
);


// Validate balance
ServiceProviderFactory(
serviceProviderFactoryAddress
Expand Down Expand Up @@ -202,14 +203,16 @@ contract DelegateManager is InitializableV2 {
_amount <= currentlyDelegatedToSP,
"Cannot decrease greater than currently staked for this ServiceProvider");

undelegateRequests[delegator] = UndelegateStakeRequest({
lockupExpiryBlock: block.number.add(undelegateLockupDuration),
amount: _amount,
serviceProvider: _target
});

// Update total locked for this service provider
spDelegateInfo[_target].totalLockedUpStake = (
// Submit updated request for sender, with target sp, undelegate amount, target expiry block
_updateUndelegateStakeRequest(
delegator,
_target,
_amount,
block.number.add(undelegateLockupDuration)
);
// Update total locked for this service provider, increasing by unstake amount
_updateServiceProviderLockupAmount(
_target,
spDelegateInfo[_target].totalLockedUpStake.add(_amount)
);

Expand All @@ -224,19 +227,15 @@ contract DelegateManager is InitializableV2 {
address delegator = msg.sender;
// Confirm pending delegation request
require(_undelegateRequestIsPending(delegator), "Pending lockup expected");

// Reset locked up stake
uint unstakeAmount = undelegateRequests[delegator].amount;
address unlockFundsSP = undelegateRequests[delegator].serviceProvider;
spDelegateInfo[unlockFundsSP].totalLockedUpStake = (
spDelegateInfo[unlockFundsSP].totalLockedUpStake.sub(undelegateRequests[delegator].amount)
// Update total locked for this service provider, decreasing by unstake amount
_updateServiceProviderLockupAmount(
unlockFundsSP,
spDelegateInfo[unlockFundsSP].totalLockedUpStake.sub(unstakeAmount)
);

// Remove pending request
undelegateRequests[delegator] = UndelegateStakeRequest({
lockupExpiryBlock: 0,
amount: 0,
serviceProvider: address(0)
});
_resetUndelegateStakeRequest(delegator);
}

/**
Expand Down Expand Up @@ -270,24 +269,24 @@ contract DelegateManager is InitializableV2 {
unstakeAmount
);

// Update amount staked from this delegator to targeted service provider
delegateInfo[delegator][serviceProvider] = (
delegateInfo[delegator][serviceProvider].sub(unstakeAmount)
// Update total delegated for SP
// totalServiceProviderDelegatedStake - total amount delegated to service provider
// totalStakedForSpFromDelegator - amount staked from this delegator to targeted service provider
// totalDelegatorStake - total delegator stake
_updateDelegatorStake(
delegator,
serviceProvider,
spDelegateInfo[serviceProvider].totalDelegatedStake.sub(unstakeAmount),
delegateInfo[delegator][serviceProvider].sub(unstakeAmount),
delegatorStakeTotal[delegator].sub(unstakeAmount)
);

// Update total delegated stake
delegatorStakeTotal[delegator] = delegatorStakeTotal[delegator].sub(unstakeAmount);
require(
(delegatorStakeTotal[delegator] >= minDelegationAmount ||
delegatorStakeTotal[delegator] == 0),
"Minimum delegation amount"
);

// Update total delegated for SP
spDelegateInfo[serviceProvider].totalDelegatedStake = (
spDelegateInfo[serviceProvider].totalDelegatedStake.sub(unstakeAmount)
);

// Remove from delegators list if no delegated stake remaining
if (delegateInfo[delegator][serviceProvider] == 0) {
for (uint i = 0; i < spDelegateInfo[serviceProvider].delegators.length; i++) {
Expand All @@ -300,17 +299,13 @@ contract DelegateManager is InitializableV2 {
}
}

// Update total locked for this service provider
spDelegateInfo[serviceProvider].totalLockedUpStake = (
// Update total locked for this service provider, decreasing by unstake amount
_updateServiceProviderLockupAmount(
serviceProvider,
spDelegateInfo[serviceProvider].totalLockedUpStake.sub(unstakeAmount)
);

// Reset lockup information
undelegateRequests[delegator] = UndelegateStakeRequest({
lockupExpiryBlock: 0,
amount: 0,
serviceProvider: address(0)
});
// Reset undelegate request
_resetUndelegateStakeRequest(delegator);

// Validate balance
ServiceProviderFactory(
Expand Down Expand Up @@ -496,16 +491,12 @@ contract DelegateManager is InitializableV2 {
if (undelegateRequests[delegator].amount != 0) {
address unstakeSP = undelegateRequests[delegator].serviceProvider;
uint unstakeAmount = undelegateRequests[delegator].amount;
// Reset total locked up stake
spDelegateInfo[unstakeSP].totalLockedUpStake = (
// Remove pending request
_updateServiceProviderLockupAmount(
unstakeSP,
spDelegateInfo[unstakeSP].totalLockedUpStake.sub(unstakeAmount)
);
// Remove pending request
undelegateRequests[delegator] = UndelegateStakeRequest({
lockupExpiryBlock: 0,
amount: 0,
serviceProvider: address(0)
});
_resetUndelegateStakeRequest(delegator);
}
}

Expand Down Expand Up @@ -757,6 +748,76 @@ contract DelegateManager is InitializableV2 {
);
}

/**
* @notice Perform state updates when a delegate stake has changed
* @param _delegator - address of delegator
* @param _serviceProvider - address of service provider
* @param _totalServiceProviderDelegatedStake - total delegated to this service provider
* @param _totalStakedForSpFromDelegator - total delegated to this service provider by delegator
* @param _totalDelegatorStake - total delegator stake across all service providers
*/
function _updateDelegatorStake(
address _delegator,
address _serviceProvider,
uint _totalServiceProviderDelegatedStake,
uint _totalStakedForSpFromDelegator,
uint _totalDelegatorStake
) internal
{
// Update total delegated for SP
spDelegateInfo[_serviceProvider].totalDelegatedStake = _totalServiceProviderDelegatedStake;

// Update amount staked from this delegator to targeted service provider
delegateInfo[_delegator][_serviceProvider] = _totalStakedForSpFromDelegator;

// Update total delegated stake
delegatorStakeTotal[_delegator] = _totalDelegatorStake;
}

/**
* @notice Reset pending undelegate stake request
* @param _delegator - address of delegator
*/
function _resetUndelegateStakeRequest(address _delegator) internal
{
_updateUndelegateStakeRequest(_delegator, address(0), 0, 0);
}

/**
* @notice Perform updates when undelegate request state has changed
* @param _delegator - address of delegator
* @param _serviceProvider - address of service provider
* @param _amount - amount being undelegated
* @param _lockupExpiryBlock - block at which stake can be undelegated
*/
function _updateUndelegateStakeRequest(
address _delegator,
address _serviceProvider,
uint _amount,
uint _lockupExpiryBlock
) internal
{
// Update lockup information
undelegateRequests[_delegator] = UndelegateStakeRequest({
lockupExpiryBlock: _lockupExpiryBlock,
amount: _amount,
serviceProvider: _serviceProvider
});
}

/**
* @notice Update amount currently locked up for this service provider
* @param _serviceProvider - address of service provider
* @param _updatedLockupAmount - updated lock up amount
*/
function _updateServiceProviderLockupAmount(
address _serviceProvider,
uint _updatedLockupAmount
) internal
{
spDelegateInfo[_serviceProvider].totalLockedUpStake = _updatedLockupAmount;
}

/**
* @notice Returns if delegator has delegated to a service provider
* @param _delegator - address of delegator
Expand Down
52 changes: 34 additions & 18 deletions eth-contracts/contracts/Governance.sol
Expand Up @@ -270,32 +270,24 @@ contract Governance is InitializableV2 {
// New voter (Vote enum defaults to 0)
if (previousVote == Vote.None) {
if (_vote == Vote.Yes) {
proposals[_proposalId].voteMagnitudeYes = (
proposals[_proposalId].voteMagnitudeYes.add(voterStake)
);
_increaseVoteMagnitudeYes(_proposalId, voterStake);
} else {
proposals[_proposalId].voteMagnitudeNo = (
proposals[_proposalId].voteMagnitudeNo.add(voterStake)
);
_increaseVoteMagnitudeNo(_proposalId, voterStake);
}
// New voter -> increase numVotes
proposals[_proposalId].numVotes = proposals[_proposalId].numVotes.add(1);
} else { // Repeat voter
if (previousVote == Vote.Yes && _vote == Vote.No) {
proposals[_proposalId].voteMagnitudeYes = (
proposals[_proposalId].voteMagnitudeYes.sub(voterStake)
);
proposals[_proposalId].voteMagnitudeNo = (
proposals[_proposalId].voteMagnitudeNo.add(voterStake)
);
_decreaseVoteMagnitudeYes(_proposalId, voterStake);
_increaseVoteMagnitudeNo(_proposalId, voterStake);
} else if (previousVote == Vote.No && _vote == Vote.Yes) {
proposals[_proposalId].voteMagnitudeYes = (
proposals[_proposalId].voteMagnitudeYes.add(voterStake)
);
proposals[_proposalId].voteMagnitudeNo = (
proposals[_proposalId].voteMagnitudeNo.sub(voterStake)
);
_decreaseVoteMagnitudeNo(_proposalId, voterStake);
_increaseVoteMagnitudeYes(_proposalId, voterStake);
}

// If _vote == previousVote, no changes needed to vote magnitudes.

// Repeat voter -> numVotes unchanged
}

emit ProposalVoteSubmitted(
Expand Down Expand Up @@ -675,4 +667,28 @@ contract Governance is InitializableV2 {

return (success, returnData);
}

function _increaseVoteMagnitudeYes(uint256 _proposalId, uint256 _voterStake) internal {
proposals[_proposalId].voteMagnitudeYes = (
proposals[_proposalId].voteMagnitudeYes.add(_voterStake)
);
}

function _increaseVoteMagnitudeNo(uint256 _proposalId, uint256 _voterStake) internal {
proposals[_proposalId].voteMagnitudeNo = (
proposals[_proposalId].voteMagnitudeNo.add(_voterStake)
);
}

function _decreaseVoteMagnitudeYes(uint256 _proposalId, uint256 _voterStake) internal {
proposals[_proposalId].voteMagnitudeYes = (
proposals[_proposalId].voteMagnitudeYes.sub(_voterStake)
);
}

function _decreaseVoteMagnitudeNo(uint256 _proposalId, uint256 _voterStake) internal {
proposals[_proposalId].voteMagnitudeNo = (
proposals[_proposalId].voteMagnitudeNo.sub(_voterStake)
);
}
}