Basic payouts to delegators when the pool is empty and they receive 100% of the reward.
This commit is contained in:
parent
362a8c8fc5
commit
7d85e61cc5
@ -420,4 +420,7 @@ contract Staking is
|
||||
{
|
||||
rewardVault = IRewardVault(_rewardVault);
|
||||
}
|
||||
|
||||
///// CAN RECEIVE FUNDS /////
|
||||
function () external payable {}
|
||||
}
|
||||
|
@ -174,16 +174,27 @@ contract MixinStake is
|
||||
// update delegator's share of reward pool
|
||||
// note that this uses the snapshot parameters
|
||||
uint256 poolBalance = rewardVault.balanceOf(poolId);
|
||||
/*uint256 buyIn = _computeBuyInDenominatedInShadowAsset(
|
||||
uint256 buyIn = _computeBuyInDenominatedInShadowAsset(
|
||||
amount,
|
||||
_delegatedStakeByPoolId,
|
||||
shadowRewardsByPoolId[poolId],
|
||||
poolBalance
|
||||
);*/
|
||||
//shadowRewardsInPoolByOwner[owner][poolId] = _safeAdd(shadowRewardsInPoolByOwner[owner][poolId], buyIn);
|
||||
//shadowRewardsByPoolId[poolId] = _safeAdd(shadowRewardsByPoolId[poolId], buyIn);
|
||||
);
|
||||
if (buyIn > 0) {
|
||||
shadowRewardsInPoolByOwner[owner][poolId] = _safeAdd(shadowRewardsInPoolByOwner[owner][poolId], buyIn);
|
||||
shadowRewardsByPoolId[poolId] = _safeAdd(shadowRewardsByPoolId[poolId], buyIn);
|
||||
}
|
||||
}
|
||||
|
||||
event K(
|
||||
uint256 amountDelegatedByOwner,
|
||||
uint256 totalAmountDelegated,
|
||||
uint256 amountOfShadowAssetHeldByOwner,
|
||||
uint256 totalAmountOfShadowAsset,
|
||||
uint256 totalAmountOfRealAsset,
|
||||
uint256 payoutInRealAsset
|
||||
);
|
||||
|
||||
// question - should we then return the amount withdrawn?
|
||||
function _undelegateStake(address payable owner, bytes32 poolId, uint256 amount)
|
||||
private
|
||||
@ -203,6 +214,7 @@ contract MixinStake is
|
||||
delegatedStakeByPoolId[poolId] = _safeSub(_delegatedStakeByPoolId, amount);
|
||||
|
||||
// get payout
|
||||
// TODO -- not full balance, just balance that belongs to delegators.
|
||||
uint256 poolBalance = rewardVault.balanceOf(poolId);
|
||||
uint256 payoutInRealAsset;
|
||||
uint256 payoutInShadowAsset;
|
||||
@ -216,8 +228,17 @@ contract MixinStake is
|
||||
shadowRewardsByPoolId[poolId],
|
||||
poolBalance
|
||||
);
|
||||
emit K(
|
||||
amount,
|
||||
_delegatedStakeByPoolId,
|
||||
payoutInShadowAsset,
|
||||
shadowRewardsByPoolId[poolId],
|
||||
poolBalance,
|
||||
payoutInRealAsset
|
||||
);
|
||||
} else {
|
||||
// partial payout
|
||||
revert('no partial');
|
||||
(payoutInRealAsset, payoutInShadowAsset) = _computePartialPayout(
|
||||
amount,
|
||||
_delegatedStakeByOwner,
|
||||
@ -231,8 +252,10 @@ contract MixinStake is
|
||||
shadowRewardsByPoolId[poolId] = _safeSub(shadowRewardsByPoolId[poolId], payoutInShadowAsset);
|
||||
|
||||
// withdraw payout for delegator
|
||||
rewardVault.withdrawFor(poolId, payoutInRealAsset);
|
||||
owner.transfer(payoutInRealAsset);
|
||||
if (payoutInRealAsset > 0) {
|
||||
rewardVault.withdrawFor(poolId, payoutInRealAsset);
|
||||
owner.transfer(payoutInRealAsset);
|
||||
}
|
||||
}
|
||||
|
||||
// Epoch | lockedAt | total | pending | deactivated | timelock() | withdraw() | available()
|
||||
|
@ -31,6 +31,7 @@ contract LibRewards is SafeMath {
|
||||
uint256 totalAmountOfRealAsset
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (uint256)
|
||||
{
|
||||
return _safeSub(
|
||||
@ -54,6 +55,7 @@ contract LibRewards is SafeMath {
|
||||
uint256 totalAmountOfRealAsset
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (
|
||||
uint256 payoutInRealAsset,
|
||||
uint256 payoutInShadowAsset
|
||||
@ -77,6 +79,7 @@ contract LibRewards is SafeMath {
|
||||
uint256 totalAmountOfRealAsset
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (uint256)
|
||||
{
|
||||
if (totalAmountDelegated == 0) {
|
||||
|
@ -1090,7 +1090,42 @@ describe('Staking Core', () => {
|
||||
///// 8 CHECK PROFITS VIA STAKING CONTRACT /////
|
||||
///// 9 WITHDRAW PROFITS VIA STAKING CONTRACT /////
|
||||
|
||||
/////
|
||||
///// 10 CHECK DELEGATOR BY UNDELEGATING /////
|
||||
const ethBalancesByDelegatorInit = await Promise.all([
|
||||
stakingWrapper.getEthBalanceAsync(delegators[0]),
|
||||
stakingWrapper.getEthBalanceAsync(delegators[1]),
|
||||
stakingWrapper.getEthBalanceAsync(delegators[2]),
|
||||
]);
|
||||
await Promise.all([
|
||||
stakingWrapper.deactivateAndTimelockDelegatedStakeAsync(delegators[0], poolIds[2], stakeByDelegator[0]),
|
||||
stakingWrapper.deactivateAndTimelockDelegatedStakeAsync(delegators[1], poolIds[2], stakeByDelegator[1]),
|
||||
stakingWrapper.deactivateAndTimelockDelegatedStakeAsync(delegators[2], poolIds[2], stakeByDelegator[2]),
|
||||
]);
|
||||
const ethBalancesByDelegatorFinal = await Promise.all([
|
||||
stakingWrapper.getEthBalanceAsync(delegators[0]),
|
||||
stakingWrapper.getEthBalanceAsync(delegators[1]),
|
||||
stakingWrapper.getEthBalanceAsync(delegators[2]),
|
||||
]);
|
||||
const rewardByDelegator = [
|
||||
ethBalancesByDelegatorFinal[0].minus(ethBalancesByDelegatorInit[0]),
|
||||
ethBalancesByDelegatorFinal[1].minus(ethBalancesByDelegatorInit[1]),
|
||||
ethBalancesByDelegatorFinal[2].minus(ethBalancesByDelegatorInit[2]),
|
||||
];
|
||||
|
||||
// note that these may be slightly off due to rounding down on each entry
|
||||
// there is a carry over between calls, which we account for here.
|
||||
// if the last person to leave rounded down, then there is some trace amount left in the pool.
|
||||
// carry-over here is 00000000000000000002
|
||||
const expectedRewardByDelegator = [
|
||||
payoutByPoolOperator[2].times(stakeByDelegator[0]).dividedToIntegerBy(totalStakeByDelegators),
|
||||
payoutByPoolOperator[2].times(stakeByDelegator[1]).dividedToIntegerBy(totalStakeByDelegators),
|
||||
new BigNumber('13927564703644768540'), // computed by hand to account for carry-over
|
||||
];
|
||||
expect(rewardByDelegator[0]).to.be.bignumber.equal(expectedRewardByDelegator[0]);
|
||||
expect(rewardByDelegator[1]).to.be.bignumber.equal(expectedRewardByDelegator[1]);
|
||||
expect(rewardByDelegator[2]).to.be.bignumber.equal(expectedRewardByDelegator[2]);
|
||||
|
||||
///// 10 CHECK DELEGATOR BUY-IN ON A SUBSEQUENT EPOCH, WHEN AMOUNT IS NON-ZERO /////
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -122,12 +122,10 @@ export class StakingWrapper {
|
||||
to: this.getStakingProxyContract().address,
|
||||
data: calldata,
|
||||
gas: 3000000,
|
||||
gasPrice: 0,
|
||||
value
|
||||
}
|
||||
const txHash = await this._web3Wrapper.sendTransactionAsync(txData);
|
||||
if (includeLogs) {
|
||||
|
||||
}
|
||||
const txReceipt = await (includeLogs ? this._logDecoder.getTxWithDecodedLogsAsync(txHash) : this._web3Wrapper.awaitTransactionSuccessAsync(txHash));
|
||||
return txReceipt;
|
||||
}
|
||||
@ -141,6 +139,10 @@ export class StakingWrapper {
|
||||
const returnValue = await this._web3Wrapper.callAsync(txData);
|
||||
return returnValue;
|
||||
}
|
||||
public async getEthBalanceAsync(owner: string): Promise<BigNumber> {
|
||||
const balance = this._web3Wrapper.getBalanceInWeiAsync(owner);
|
||||
return balance;
|
||||
}
|
||||
///// STAKE /////
|
||||
public async depositAsync(owner: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const calldata = this.getStakingContract().deposit.getABIEncodedTransactionData(amount);
|
||||
@ -154,7 +156,8 @@ export class StakingWrapper {
|
||||
}
|
||||
public async depositAndDelegateAsync(owner: string, poolId: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const calldata = this.getStakingContract().depositAndDelegate.getABIEncodedTransactionData(poolId, amount);
|
||||
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
||||
const txReceipt = await this._executeTransactionAsync(calldata, owner);//, new BigNumber(0), true);
|
||||
//console.log(JSON.stringify(txReceipt, null, 4));
|
||||
return txReceipt;
|
||||
}
|
||||
public async activateStakeAsync(owner: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
@ -174,7 +177,8 @@ export class StakingWrapper {
|
||||
}
|
||||
public async deactivateAndTimelockDelegatedStakeAsync(owner: string, poolId: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const calldata = this.getStakingContract().deactivateAndTimelockDelegatedStake.getABIEncodedTransactionData(poolId, amount);
|
||||
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
||||
const txReceipt = await this._executeTransactionAsync(calldata, owner, new BigNumber(0), true);
|
||||
console.log(JSON.stringify(txReceipt, null, 4));
|
||||
return txReceipt;
|
||||
}
|
||||
public async withdrawAsync(owner: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user