ran prettier

This commit is contained in:
Greg Hysen 2019-06-28 18:48:00 -07:00
parent 9eb676fb46
commit cd14d1ef0f
13 changed files with 152 additions and 122 deletions

View File

@ -3,20 +3,21 @@
This package implements the stake-based liquidity incentives defined by [ZEIP-31](https://github.com/0xProject/ZEIPs/issues/31).
Functionality:
1. Stake your ZRX tokens to unlock their utility within the 0x ecosystem.
1. Stake your ZRX tokens to unlock their utility within the 0x ecosystem.
- Earn rebates on market making on the 0x protocol
- Participate in governance over the 0x protocol
2. Create staking pools to leverage the weight of other stakers.
2. Create staking pools to leverage the weight of other stakers.
- Increase your market making rebates.
- Increase your voting power.
3. Delegate your Zrx to staking pools to
3. Delegate your Zrx to staking pools to
- Earn a portion of the pool's market making rebates.
- Support a pool's mission sharing your voting power.
## Architecture
This system is composed of four deployed contracts:
1. Staking Contract, which is an upgradeable/stateless contract that implements staking logic.
2. Staking Contract Proxy, which stores staking state and delegates to the Staking Contract.
3. Zrx Vault, which securely holds staked Zrx Tokens.
@ -27,19 +28,21 @@ These contracts connect to each other and the broader 0x ecosystem like this:
![](images/architecture.png)
## Architecture (Catastrophic Failure Mode)
If a vulnerability is discovered in the staking contract.
1. The 0x Exchange contract stops charging protocol fees
2. The staking contract is set to read-only mode (clients may still query balances)
3. Vaults are detached from the staking contract
4. Users may withdraw their assets directly from vaults
5. If state is corrupted, the staking storage is detached from the logic contract and a new storage contract is deployed
Steps 1-3 are triggered immediately upon discovering a potential failure. Steps 4-5 are triggered if the internal staking state has been corrupted; in this worst-case scenario, the staking contract must be re-deployed — users withdraw their funds from the vaults and re-stake under a new staking contract.
If a vulnerability is discovered in the staking contract.
1. The 0x Exchange contract stops charging protocol fees
2. The staking contract is set to read-only mode (clients may still query balances)
3. Vaults are detached from the staking contract
4. Users may withdraw their assets directly from vaults
5. If state is corrupted, the staking storage is detached from the logic contract and a new storage contract is deployed
Steps 1-3 are triggered immediately upon discovering a potential failure. Steps 4-5 are triggered if the internal staking state has been corrupted; in this worst-case scenario, the staking contract must be re-deployed — users withdraw their funds from the vaults and re-stake under a new staking contract.
![](images/architecture_failure_mode.png)
## Contracts Directory Structure
The contracts can be found in `contracts/src`.
```
@ -59,7 +62,6 @@ The contracts can be found in `contracts/src`.
These contracts use an actor/simulation pattern. A simulation runs with a specified set of actors, initial state and expected output. Actors have a specific role and validate each call they make to the staking system; for example, there is a Staking Actor who stakes/unstakes their Zrx tokens and validates balances/events. Similarly, there could exist an actor who tries to steal funds.
## Installation
**Install**

View File

@ -1,6 +1,4 @@
import {
expectTransactionFailedAsync,
} from '@0x/contracts-test-utils';
import { expectTransactionFailedAsync } from '@0x/contracts-test-utils';
import { RevertReason } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
@ -26,7 +24,11 @@ export class DelegatorActor extends StakerActor {
const initZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVaultAsync();
const initDelegatorBalances = await this.getBalancesAsync([poolId]);
// deposit stake
const txReceiptPromise = this._stakingWrapper.depositZrxAndDelegateToStakingPoolAsync(this._owner, poolId, amount);
const txReceiptPromise = this._stakingWrapper.depositZrxAndDelegateToStakingPoolAsync(
this._owner,
poolId,
amount,
);
if (revertReason !== undefined) {
await expectTransactionFailedAsync(txReceiptPromise, revertReason);
return;

View File

@ -1,6 +1,4 @@
import {
expectTransactionFailedAsync,
} from '@0x/contracts-test-utils';
import { expectTransactionFailedAsync } from '@0x/contracts-test-utils';
import { RevertReason } from '@0x/types';
import * as chai from 'chai';
import * as _ from 'lodash';
@ -62,7 +60,11 @@ export class PoolOperatorActor extends BaseActor {
revertReason?: RevertReason,
): Promise<void> {
// remove maker
const txReceiptPromise = this._stakingWrapper.removeMakerFromStakingPoolAsync(poolId, makerAddress, this._owner);
const txReceiptPromise = this._stakingWrapper.removeMakerFromStakingPoolAsync(
poolId,
makerAddress,
this._owner,
);
if (revertReason !== undefined) {
await expectTransactionFailedAsync(txReceiptPromise, revertReason);
return;

View File

@ -1,6 +1,4 @@
import {
expectTransactionFailedAsync,
} from '@0x/contracts-test-utils';
import { expectTransactionFailedAsync } from '@0x/contracts-test-utils';
import { RevertReason } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
@ -81,7 +79,10 @@ export class StakerActor extends BaseActor {
expectedStakerBalances.deactivatedStakeBalance = initStakerBalances.deactivatedStakeBalance.plus(amount);
await this.assertBalancesAsync(expectedStakerBalances);
}
public async burnDeactivatedStakeAndWithdrawZrxAsync(amount: BigNumber, revertReason?: RevertReason): Promise<void> {
public async burnDeactivatedStakeAndWithdrawZrxAsync(
amount: BigNumber,
revertReason?: RevertReason,
): Promise<void> {
// query init balances
const initZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVaultAsync();
const initStakerBalances = await this.getBalancesAsync();

View File

@ -1,10 +1,6 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import {
chaiSetup,
provider,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { chaiSetup, provider, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';

View File

@ -1,11 +1,6 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import {
chaiSetup,
expectTransactionFailedAsync,
provider,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { chaiSetup, expectTransactionFailedAsync, provider, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { RevertReason } from '@0x/types';
import { BigNumber } from '@0x/utils';

View File

@ -1,10 +1,6 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import {
chaiSetup,
provider,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { chaiSetup, provider, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';

View File

@ -1,11 +1,6 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import {
chaiSetup,
expectTransactionFailedAsync,
provider,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { chaiSetup, expectTransactionFailedAsync, provider, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { RevertReason } from '@0x/types';
import { BigNumber } from '@0x/utils';
@ -151,7 +146,11 @@ describe('Staking Pool Management', () => {
const poolId = await poolOperator.createStakingPoolAsync(operatorShare);
expect(poolId).to.be.equal(stakingConstants.INITIAL_POOL_ID);
// remove non-existent maker from pool
await poolOperator.removeMakerFromStakingPoolAsync(poolId, makerAddress, RevertReason.MakerAddressNotRegistered);
await poolOperator.removeMakerFromStakingPoolAsync(
poolId,
makerAddress,
RevertReason.MakerAddressNotRegistered,
);
});
it('Should fail to add a maker who signed with the wrong private key', async () => {
// test parameters
@ -238,7 +237,12 @@ describe('Staking Pool Management', () => {
// add maker to pool
const makerApproval = maker.signApprovalForStakingPool(poolId);
await expectTransactionFailedAsync(
stakingWrapper.addMakerToStakingPoolAsync(poolId, makerAddress, makerApproval.signature, notOperatorAddress),
stakingWrapper.addMakerToStakingPoolAsync(
poolId,
makerAddress,
makerApproval.signature,
notOperatorAddress,
),
RevertReason.OnlyCallableByPoolOperator,
);
});

View File

@ -1,11 +1,6 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import {
chaiSetup,
expectTransactionFailedAsync,
provider,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { chaiSetup, expectTransactionFailedAsync, provider, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { RevertReason } from '@0x/types';
import { BigNumber } from '@0x/utils';

View File

@ -1,10 +1,6 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import {
chaiSetup,
provider,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { chaiSetup, provider, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { RevertReason } from '@0x/types';
import { BigNumber } from '@0x/utils';

View File

@ -59,7 +59,9 @@ export class Simulation {
// @TODO cleanup state and verify the staking contract is empty
}
private async _withdrawRewardForStakingPoolMemberForDelegatorsByUndelegatingAsync(p: SimulationParams): Promise<void> {
private async _withdrawRewardForStakingPoolMemberForDelegatorsByUndelegatingAsync(
p: SimulationParams,
): Promise<void> {
let delegatorIdx = 0;
let poolIdx = 0;
for (const numberOfDelegatorsInPool of p.numberOfDelegatorsPerPool) {
@ -73,10 +75,7 @@ export class Simulation {
await delegator.deactivateAndTimelockDelegatedStakeAsync(poolId, amountOfStakeDelegated);
const finalEthBalance = await this._stakingWrapper.getEthBalanceAsync(delegatorAddress);
const reward = finalEthBalance.minus(initEthBalance);
const rewardTrimmed = StakingWrapper.trimFloat(
StakingWrapper.toFloatingPoint(reward, 18),
5,
);
const rewardTrimmed = StakingWrapper.trimFloat(StakingWrapper.toFloatingPoint(reward, 18), 5);
const expectedReward = p.expectedPayoutByDelegator[delegatorIdx];
expect(
rewardTrimmed,
@ -101,10 +100,7 @@ export class Simulation {
await this._stakingWrapper.withdrawTotalRewardForStakingPoolMemberAsync(poolId, delegatorAddress);
const finalEthBalance = await this._stakingWrapper.getEthBalanceAsync(delegatorAddress);
const reward = finalEthBalance.minus(initEthBalance);
const rewardTrimmed = StakingWrapper.trimFloat(
StakingWrapper.toFloatingPoint(reward, 18),
5,
);
const rewardTrimmed = StakingWrapper.trimFloat(StakingWrapper.toFloatingPoint(reward, 18), 5);
const expectedReward = p.expectedPayoutByDelegator[delegatorIdx];
expect(
rewardTrimmed,
@ -228,7 +224,9 @@ export class Simulation {
`expected balance in vault for pool with id ${poolId}`,
).to.be.bignumber.equal(expectedRewardBalance);
// check operator's balance
const poolOperatorVaultBalance = await this._stakingWrapper.getRewardBalanceOfStakingPoolOperatorAsync(poolId);
const poolOperatorVaultBalance = await this._stakingWrapper.getRewardBalanceOfStakingPoolOperatorAsync(
poolId,
);
const poolOperatorVaultBalanceTrimmed = StakingWrapper.trimFloat(
StakingWrapper.toFloatingPoint(poolOperatorVaultBalance, 18),
5,

View File

@ -117,7 +117,7 @@ export class StakingWrapper {
);
// configure erc20 proxy to accept calls from zrx vault
await this._erc20ProxyContract.addAuthorizedAddress.awaitTransactionSuccessAsync(
(this._zrxVaultContractIfExists).address,
this._zrxVaultContractIfExists.address,
);
// deploy staking contract
this._stakingContractIfExists = await StakingContract.deployFrom0xArtifactAsync(
@ -130,39 +130,35 @@ export class StakingWrapper {
artifacts.StakingProxy,
this._provider,
txDefaults,
(this._stakingContractIfExists).address,
this._stakingContractIfExists.address,
);
// set staking proxy contract in zrx vault
await (this
._zrxVaultContractIfExists).setStakingContract.awaitTransactionSuccessAsync(
(this._stakingProxyContractIfExists).address,
await this._zrxVaultContractIfExists.setStakingContract.awaitTransactionSuccessAsync(
this._stakingProxyContractIfExists.address,
);
// set zrx vault in staking contract
const setZrxVaultCalldata = (this
._stakingContractIfExists).setZrxVault.getABIEncodedTransactionData(
(this._zrxVaultContractIfExists).address,
const setZrxVaultCalldata = this._stakingContractIfExists.setZrxVault.getABIEncodedTransactionData(
this._zrxVaultContractIfExists.address,
);
const setZrxVaultTxData = {
from: this._ownerAddress,
to: (this._stakingProxyContractIfExists).address,
to: this._stakingProxyContractIfExists.address,
data: setZrxVaultCalldata,
};
await this._web3Wrapper.awaitTransactionSuccessAsync(
await this._web3Wrapper.sendTransactionAsync(setZrxVaultTxData),
);
// set staking proxy contract in reward vault
await (this
._rewardVaultContractIfExists).setStakingContract.awaitTransactionSuccessAsync(
(this._stakingProxyContractIfExists).address,
await this._rewardVaultContractIfExists.setStakingContract.awaitTransactionSuccessAsync(
this._stakingProxyContractIfExists.address,
);
// set reward vault in staking contract
const setStakingPoolRewardVaultCalldata = (this
._stakingContractIfExists).setStakingPoolRewardVault.getABIEncodedTransactionData(
(this._rewardVaultContractIfExists).address,
const setStakingPoolRewardVaultCalldata = this._stakingContractIfExists.setStakingPoolRewardVault.getABIEncodedTransactionData(
this._rewardVaultContractIfExists.address,
);
const setStakingPoolRewardVaultTxData = {
from: this._ownerAddress,
to: (this._stakingProxyContractIfExists).address,
to: this._stakingProxyContractIfExists.address,
data: setStakingPoolRewardVaultCalldata,
};
await this._web3Wrapper.awaitTransactionSuccessAsync(
@ -180,12 +176,20 @@ export class StakingWrapper {
return balance;
}
///// STAKE /////
public async depositZrxAndMintDeactivatedStakeAsync(owner: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().depositZrxAndMintDeactivatedStake.getABIEncodedTransactionData(amount);
public async depositZrxAndMintDeactivatedStakeAsync(
owner: string,
amount: BigNumber,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().depositZrxAndMintDeactivatedStake.getABIEncodedTransactionData(
amount,
);
const txReceipt = await this._executeTransactionAsync(calldata, owner);
return txReceipt;
}
public async depositZrxAndMintActivatedStakeAsync(owner: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
public async depositZrxAndMintActivatedStakeAsync(
owner: string,
amount: BigNumber,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().depositZrxAndMintActivatedStake.getABIEncodedTransactionData(amount);
const txReceipt = await this._executeTransactionAsync(calldata, owner);
return txReceipt;
@ -195,7 +199,10 @@ export class StakingWrapper {
poolId: string,
amount: BigNumber,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().depositZrxAndDelegateToStakingPool.getABIEncodedTransactionData(poolId, amount);
const calldata = this.getStakingContract().depositZrxAndDelegateToStakingPool.getABIEncodedTransactionData(
poolId,
amount,
);
const txReceipt = await this._executeTransactionAsync(calldata, owner, new BigNumber(0), true);
return txReceipt;
}
@ -236,8 +243,13 @@ export class StakingWrapper {
const txReceipt = await this._executeTransactionAsync(calldata, owner, new BigNumber(0), true);
return txReceipt;
}
public async burnDeactivatedStakeAndWithdrawZrxAsync(owner: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().burnDeactivatedStakeAndWithdrawZrx.getABIEncodedTransactionData(amount);
public async burnDeactivatedStakeAndWithdrawZrxAsync(
owner: string,
amount: BigNumber,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().burnDeactivatedStakeAndWithdrawZrx.getABIEncodedTransactionData(
amount,
);
const txReceipt = await this._executeTransactionAsync(calldata, owner);
return txReceipt;
}
@ -408,9 +420,7 @@ export class StakingWrapper {
public async goToNextEpochAsync(): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().finalizeFees.getABIEncodedTransactionData();
const txReceipt = await this._executeTransactionAsync(calldata, undefined, new BigNumber(0), true);
logUtils.log(
`Finalization costed ${txReceipt.gasUsed} gas`,
);
logUtils.log(`Finalization costed ${txReceipt.gasUsed} gas`);
return txReceipt;
}
public async skipToNextEpochAsync(): Promise<TransactionReceiptWithDecodedLogs> {
@ -461,7 +471,9 @@ export class StakingWrapper {
public async getCurrentEpochEarliestEndTimeInSecondsAsync(): Promise<BigNumber> {
const calldata = this.getStakingContract().getCurrentEpochEarliestEndTimeInSeconds.getABIEncodedTransactionData();
const returnData = await this._callAsync(calldata);
const value = this.getStakingContract().getCurrentEpochEarliestEndTimeInSeconds.getABIDecodedReturnData(returnData);
const value = this.getStakingContract().getCurrentEpochEarliestEndTimeInSeconds.getABIDecodedReturnData(
returnData,
);
return value;
}
public async getCurrentTimelockPeriodEndEpochAsync(): Promise<BigNumber> {
@ -511,13 +523,19 @@ export class StakingWrapper {
const isValid = this.getStakingContract().isValidExchangeAddress.getABIDecodedReturnData(returnData);
return isValid;
}
public async addExchangeAddressAsync(exchangeAddress: string, ownerAddressIfExists?: string): Promise<TransactionReceiptWithDecodedLogs> {
public async addExchangeAddressAsync(
exchangeAddress: string,
ownerAddressIfExists?: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().addExchangeAddress.getABIEncodedTransactionData(exchangeAddress);
const ownerAddress = ownerAddressIfExists !== undefined ? ownerAddressIfExists : this._ownerAddress;
const txReceipt = await this._executeTransactionAsync(calldata, ownerAddress);
return txReceipt;
}
public async removeExchangeAddressAsync(exchangeAddress: string, ownerAddressIfExists?: string): Promise<TransactionReceiptWithDecodedLogs> {
public async removeExchangeAddressAsync(
exchangeAddress: string,
ownerAddressIfExists?: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().removeExchangeAddress.getABIEncodedTransactionData(exchangeAddress);
const ownerAddress = ownerAddressIfExists !== undefined ? ownerAddressIfExists : this._ownerAddress;
const txReceipt = await this._executeTransactionAsync(calldata, ownerAddress);
@ -525,31 +543,48 @@ export class StakingWrapper {
}
///// REWARDS /////
public async getTotalRewardBalanceOfStakingPoolAsync(poolId: string): Promise<BigNumber> {
const calldata = this.getStakingContract().getTotalRewardBalanceOfStakingPool.getABIEncodedTransactionData(poolId);
const calldata = this.getStakingContract().getTotalRewardBalanceOfStakingPool.getABIEncodedTransactionData(
poolId,
);
const returnData = await this._callAsync(calldata);
const value = this.getStakingContract().getTotalRewardBalanceOfStakingPool.getABIDecodedReturnData(returnData);
return value;
}
public async getRewardBalanceOfStakingPoolOperatorAsync(poolId: string): Promise<BigNumber> {
const calldata = this.getStakingContract().getRewardBalanceOfStakingPoolOperator.getABIEncodedTransactionData(poolId);
const calldata = this.getStakingContract().getRewardBalanceOfStakingPoolOperator.getABIEncodedTransactionData(
poolId,
);
const returnData = await this._callAsync(calldata);
const value = this.getStakingContract().getRewardBalanceOfStakingPoolOperator.getABIDecodedReturnData(returnData);
const value = this.getStakingContract().getRewardBalanceOfStakingPoolOperator.getABIDecodedReturnData(
returnData,
);
return value;
}
public async getRewardBalanceOfStakingPoolMembersAsync(poolId: string): Promise<BigNumber> {
const calldata = this.getStakingContract().getRewardBalanceOfStakingPoolMembers.getABIEncodedTransactionData(poolId);
const calldata = this.getStakingContract().getRewardBalanceOfStakingPoolMembers.getABIEncodedTransactionData(
poolId,
);
const returnData = await this._callAsync(calldata);
const value = this.getStakingContract().getRewardBalanceOfStakingPoolMembers.getABIDecodedReturnData(returnData);
const value = this.getStakingContract().getRewardBalanceOfStakingPoolMembers.getABIDecodedReturnData(
returnData,
);
return value;
}
public async computeRewardBalanceOfStakingPoolMemberAsync(poolId: string, owner: string): Promise<BigNumber> {
const calldata = this.getStakingContract().computeRewardBalanceOfStakingPoolMember.getABIEncodedTransactionData(poolId, owner);
const calldata = this.getStakingContract().computeRewardBalanceOfStakingPoolMember.getABIEncodedTransactionData(
poolId,
owner,
);
const returnData = await this._callAsync(calldata);
const value = this.getStakingContract().computeRewardBalanceOfStakingPoolMember.getABIDecodedReturnData(returnData);
const value = this.getStakingContract().computeRewardBalanceOfStakingPoolMember.getABIDecodedReturnData(
returnData,
);
return value;
}
public async getTotalShadowBalanceOfStakingPoolAsync(poolId: string): Promise<BigNumber> {
const calldata = this.getStakingContract().getTotalShadowBalanceOfStakingPool.getABIEncodedTransactionData(poolId);
const calldata = this.getStakingContract().getTotalShadowBalanceOfStakingPool.getABIEncodedTransactionData(
poolId,
);
const returnData = await this._callAsync(calldata);
const value = this.getStakingContract().getTotalShadowBalanceOfStakingPool.getABIDecodedReturnData(returnData);
return value;
@ -568,7 +603,10 @@ export class StakingWrapper {
amount: BigNumber,
operatorAddress: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().withdrawRewardForStakingPoolOperator.getABIEncodedTransactionData(poolId, amount);
const calldata = this.getStakingContract().withdrawRewardForStakingPoolOperator.getABIEncodedTransactionData(
poolId,
amount,
);
const txReceipt = await this._executeTransactionAsync(calldata, operatorAddress);
return txReceipt;
}
@ -577,7 +615,10 @@ export class StakingWrapper {
amount: BigNumber,
owner: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().withdrawRewardForStakingPoolMember.getABIEncodedTransactionData(poolId, amount);
const calldata = this.getStakingContract().withdrawRewardForStakingPoolMember.getABIEncodedTransactionData(
poolId,
amount,
);
const txReceipt = await this._executeTransactionAsync(calldata, owner);
return txReceipt;
}
@ -585,12 +626,19 @@ export class StakingWrapper {
poolId: string,
operatorAddress: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().withdrawTotalRewardForStakingPoolOperator.getABIEncodedTransactionData(poolId);
const calldata = this.getStakingContract().withdrawTotalRewardForStakingPoolOperator.getABIEncodedTransactionData(
poolId,
);
const txReceipt = await this._executeTransactionAsync(calldata, operatorAddress);
return txReceipt;
}
public async withdrawTotalRewardForStakingPoolMemberAsync(poolId: string, owner: string): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().withdrawTotalRewardForStakingPoolMember.getABIEncodedTransactionData(poolId);
public async withdrawTotalRewardForStakingPoolMemberAsync(
poolId: string,
owner: string,
): Promise<TransactionReceiptWithDecodedLogs> {
const calldata = this.getStakingContract().withdrawTotalRewardForStakingPoolMember.getABIEncodedTransactionData(
poolId,
);
const txReceipt = await this._executeTransactionAsync(calldata, owner);
return txReceipt;
}

View File

@ -1,11 +1,6 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import {
chaiSetup,
expectTransactionFailedAsync,
provider,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { chaiSetup, expectTransactionFailedAsync, provider, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { RevertReason } from '@0x/types';
import { BigNumber } from '@0x/utils';