ran prettier
This commit is contained in:
parent
9eb676fb46
commit
cd14d1ef0f
@ -3,20 +3,21 @@
|
|||||||
This package implements the stake-based liquidity incentives defined by [ZEIP-31](https://github.com/0xProject/ZEIPs/issues/31).
|
This package implements the stake-based liquidity incentives defined by [ZEIP-31](https://github.com/0xProject/ZEIPs/issues/31).
|
||||||
|
|
||||||
Functionality:
|
Functionality:
|
||||||
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.
|
|
||||||
- Increase your market making rebates.
|
|
||||||
- Increase your voting power.
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
- Increase your market making rebates.
|
||||||
|
- Increase your voting power.
|
||||||
|
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
|
## Architecture
|
||||||
|
|
||||||
This system is composed of four deployed contracts:
|
This system is composed of four deployed contracts:
|
||||||
|
|
||||||
1. Staking Contract, which is an upgradeable/stateless contract that implements staking logic.
|
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.
|
2. Staking Contract Proxy, which stores staking state and delegates to the Staking Contract.
|
||||||
3. Zrx Vault, which securely holds staked Zrx Tokens.
|
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:
|
|||||||

|

|
||||||
|
|
||||||
## Architecture (Catastrophic Failure Mode)
|
## 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.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Contracts Directory Structure
|
## Contracts Directory Structure
|
||||||
|
|
||||||
The contracts can be found in `contracts/src`.
|
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.
|
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
|
## Installation
|
||||||
|
|
||||||
**Install**
|
**Install**
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import {
|
import { expectTransactionFailedAsync } from '@0x/contracts-test-utils';
|
||||||
expectTransactionFailedAsync,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { RevertReason } from '@0x/types';
|
import { RevertReason } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
@ -26,7 +24,11 @@ export class DelegatorActor extends StakerActor {
|
|||||||
const initZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVaultAsync();
|
const initZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVaultAsync();
|
||||||
const initDelegatorBalances = await this.getBalancesAsync([poolId]);
|
const initDelegatorBalances = await this.getBalancesAsync([poolId]);
|
||||||
// deposit stake
|
// deposit stake
|
||||||
const txReceiptPromise = this._stakingWrapper.depositZrxAndDelegateToStakingPoolAsync(this._owner, poolId, amount);
|
const txReceiptPromise = this._stakingWrapper.depositZrxAndDelegateToStakingPoolAsync(
|
||||||
|
this._owner,
|
||||||
|
poolId,
|
||||||
|
amount,
|
||||||
|
);
|
||||||
if (revertReason !== undefined) {
|
if (revertReason !== undefined) {
|
||||||
await expectTransactionFailedAsync(txReceiptPromise, revertReason);
|
await expectTransactionFailedAsync(txReceiptPromise, revertReason);
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import {
|
import { expectTransactionFailedAsync } from '@0x/contracts-test-utils';
|
||||||
expectTransactionFailedAsync,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { RevertReason } from '@0x/types';
|
import { RevertReason } from '@0x/types';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
@ -62,7 +60,11 @@ export class PoolOperatorActor extends BaseActor {
|
|||||||
revertReason?: RevertReason,
|
revertReason?: RevertReason,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// remove maker
|
// remove maker
|
||||||
const txReceiptPromise = this._stakingWrapper.removeMakerFromStakingPoolAsync(poolId, makerAddress, this._owner);
|
const txReceiptPromise = this._stakingWrapper.removeMakerFromStakingPoolAsync(
|
||||||
|
poolId,
|
||||||
|
makerAddress,
|
||||||
|
this._owner,
|
||||||
|
);
|
||||||
if (revertReason !== undefined) {
|
if (revertReason !== undefined) {
|
||||||
await expectTransactionFailedAsync(txReceiptPromise, revertReason);
|
await expectTransactionFailedAsync(txReceiptPromise, revertReason);
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import {
|
import { expectTransactionFailedAsync } from '@0x/contracts-test-utils';
|
||||||
expectTransactionFailedAsync,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { RevertReason } from '@0x/types';
|
import { RevertReason } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
@ -81,7 +79,10 @@ export class StakerActor extends BaseActor {
|
|||||||
expectedStakerBalances.deactivatedStakeBalance = initStakerBalances.deactivatedStakeBalance.plus(amount);
|
expectedStakerBalances.deactivatedStakeBalance = initStakerBalances.deactivatedStakeBalance.plus(amount);
|
||||||
await this.assertBalancesAsync(expectedStakerBalances);
|
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
|
// query init balances
|
||||||
const initZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVaultAsync();
|
const initZrxBalanceOfVault = await this._stakingWrapper.getZrxTokenBalanceOfZrxVaultAsync();
|
||||||
const initStakerBalances = await this.getBalancesAsync();
|
const initStakerBalances = await this.getBalancesAsync();
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
||||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
import {
|
import { chaiSetup, provider, web3Wrapper } from '@0x/contracts-test-utils';
|
||||||
chaiSetup,
|
|
||||||
provider,
|
|
||||||
web3Wrapper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
||||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
import {
|
import { chaiSetup, expectTransactionFailedAsync, provider, web3Wrapper } from '@0x/contracts-test-utils';
|
||||||
chaiSetup,
|
|
||||||
expectTransactionFailedAsync,
|
|
||||||
provider,
|
|
||||||
web3Wrapper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { RevertReason } from '@0x/types';
|
import { RevertReason } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
||||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
import {
|
import { chaiSetup, provider, web3Wrapper } from '@0x/contracts-test-utils';
|
||||||
chaiSetup,
|
|
||||||
provider,
|
|
||||||
web3Wrapper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
||||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
import {
|
import { chaiSetup, expectTransactionFailedAsync, provider, web3Wrapper } from '@0x/contracts-test-utils';
|
||||||
chaiSetup,
|
|
||||||
expectTransactionFailedAsync,
|
|
||||||
provider,
|
|
||||||
web3Wrapper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { RevertReason } from '@0x/types';
|
import { RevertReason } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
@ -151,7 +146,11 @@ describe('Staking Pool Management', () => {
|
|||||||
const poolId = await poolOperator.createStakingPoolAsync(operatorShare);
|
const poolId = await poolOperator.createStakingPoolAsync(operatorShare);
|
||||||
expect(poolId).to.be.equal(stakingConstants.INITIAL_POOL_ID);
|
expect(poolId).to.be.equal(stakingConstants.INITIAL_POOL_ID);
|
||||||
// remove non-existent maker from pool
|
// 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 () => {
|
it('Should fail to add a maker who signed with the wrong private key', async () => {
|
||||||
// test parameters
|
// test parameters
|
||||||
@ -238,7 +237,12 @@ describe('Staking Pool Management', () => {
|
|||||||
// add maker to pool
|
// add maker to pool
|
||||||
const makerApproval = maker.signApprovalForStakingPool(poolId);
|
const makerApproval = maker.signApprovalForStakingPool(poolId);
|
||||||
await expectTransactionFailedAsync(
|
await expectTransactionFailedAsync(
|
||||||
stakingWrapper.addMakerToStakingPoolAsync(poolId, makerAddress, makerApproval.signature, notOperatorAddress),
|
stakingWrapper.addMakerToStakingPoolAsync(
|
||||||
|
poolId,
|
||||||
|
makerAddress,
|
||||||
|
makerApproval.signature,
|
||||||
|
notOperatorAddress,
|
||||||
|
),
|
||||||
RevertReason.OnlyCallableByPoolOperator,
|
RevertReason.OnlyCallableByPoolOperator,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
||||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
import {
|
import { chaiSetup, expectTransactionFailedAsync, provider, web3Wrapper } from '@0x/contracts-test-utils';
|
||||||
chaiSetup,
|
|
||||||
expectTransactionFailedAsync,
|
|
||||||
provider,
|
|
||||||
web3Wrapper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { RevertReason } from '@0x/types';
|
import { RevertReason } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
||||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
import {
|
import { chaiSetup, provider, web3Wrapper } from '@0x/contracts-test-utils';
|
||||||
chaiSetup,
|
|
||||||
provider,
|
|
||||||
web3Wrapper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { RevertReason } from '@0x/types';
|
import { RevertReason } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
|
@ -59,7 +59,9 @@ export class Simulation {
|
|||||||
// @TODO cleanup state and verify the staking contract is empty
|
// @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 delegatorIdx = 0;
|
||||||
let poolIdx = 0;
|
let poolIdx = 0;
|
||||||
for (const numberOfDelegatorsInPool of p.numberOfDelegatorsPerPool) {
|
for (const numberOfDelegatorsInPool of p.numberOfDelegatorsPerPool) {
|
||||||
@ -73,10 +75,7 @@ export class Simulation {
|
|||||||
await delegator.deactivateAndTimelockDelegatedStakeAsync(poolId, amountOfStakeDelegated);
|
await delegator.deactivateAndTimelockDelegatedStakeAsync(poolId, amountOfStakeDelegated);
|
||||||
const finalEthBalance = await this._stakingWrapper.getEthBalanceAsync(delegatorAddress);
|
const finalEthBalance = await this._stakingWrapper.getEthBalanceAsync(delegatorAddress);
|
||||||
const reward = finalEthBalance.minus(initEthBalance);
|
const reward = finalEthBalance.minus(initEthBalance);
|
||||||
const rewardTrimmed = StakingWrapper.trimFloat(
|
const rewardTrimmed = StakingWrapper.trimFloat(StakingWrapper.toFloatingPoint(reward, 18), 5);
|
||||||
StakingWrapper.toFloatingPoint(reward, 18),
|
|
||||||
5,
|
|
||||||
);
|
|
||||||
const expectedReward = p.expectedPayoutByDelegator[delegatorIdx];
|
const expectedReward = p.expectedPayoutByDelegator[delegatorIdx];
|
||||||
expect(
|
expect(
|
||||||
rewardTrimmed,
|
rewardTrimmed,
|
||||||
@ -101,10 +100,7 @@ export class Simulation {
|
|||||||
await this._stakingWrapper.withdrawTotalRewardForStakingPoolMemberAsync(poolId, delegatorAddress);
|
await this._stakingWrapper.withdrawTotalRewardForStakingPoolMemberAsync(poolId, delegatorAddress);
|
||||||
const finalEthBalance = await this._stakingWrapper.getEthBalanceAsync(delegatorAddress);
|
const finalEthBalance = await this._stakingWrapper.getEthBalanceAsync(delegatorAddress);
|
||||||
const reward = finalEthBalance.minus(initEthBalance);
|
const reward = finalEthBalance.minus(initEthBalance);
|
||||||
const rewardTrimmed = StakingWrapper.trimFloat(
|
const rewardTrimmed = StakingWrapper.trimFloat(StakingWrapper.toFloatingPoint(reward, 18), 5);
|
||||||
StakingWrapper.toFloatingPoint(reward, 18),
|
|
||||||
5,
|
|
||||||
);
|
|
||||||
const expectedReward = p.expectedPayoutByDelegator[delegatorIdx];
|
const expectedReward = p.expectedPayoutByDelegator[delegatorIdx];
|
||||||
expect(
|
expect(
|
||||||
rewardTrimmed,
|
rewardTrimmed,
|
||||||
@ -228,7 +224,9 @@ export class Simulation {
|
|||||||
`expected balance in vault for pool with id ${poolId}`,
|
`expected balance in vault for pool with id ${poolId}`,
|
||||||
).to.be.bignumber.equal(expectedRewardBalance);
|
).to.be.bignumber.equal(expectedRewardBalance);
|
||||||
// check operator's balance
|
// check operator's balance
|
||||||
const poolOperatorVaultBalance = await this._stakingWrapper.getRewardBalanceOfStakingPoolOperatorAsync(poolId);
|
const poolOperatorVaultBalance = await this._stakingWrapper.getRewardBalanceOfStakingPoolOperatorAsync(
|
||||||
|
poolId,
|
||||||
|
);
|
||||||
const poolOperatorVaultBalanceTrimmed = StakingWrapper.trimFloat(
|
const poolOperatorVaultBalanceTrimmed = StakingWrapper.trimFloat(
|
||||||
StakingWrapper.toFloatingPoint(poolOperatorVaultBalance, 18),
|
StakingWrapper.toFloatingPoint(poolOperatorVaultBalance, 18),
|
||||||
5,
|
5,
|
||||||
|
@ -117,7 +117,7 @@ export class StakingWrapper {
|
|||||||
);
|
);
|
||||||
// configure erc20 proxy to accept calls from zrx vault
|
// configure erc20 proxy to accept calls from zrx vault
|
||||||
await this._erc20ProxyContract.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
await this._erc20ProxyContract.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||||
(this._zrxVaultContractIfExists).address,
|
this._zrxVaultContractIfExists.address,
|
||||||
);
|
);
|
||||||
// deploy staking contract
|
// deploy staking contract
|
||||||
this._stakingContractIfExists = await StakingContract.deployFrom0xArtifactAsync(
|
this._stakingContractIfExists = await StakingContract.deployFrom0xArtifactAsync(
|
||||||
@ -130,39 +130,35 @@ export class StakingWrapper {
|
|||||||
artifacts.StakingProxy,
|
artifacts.StakingProxy,
|
||||||
this._provider,
|
this._provider,
|
||||||
txDefaults,
|
txDefaults,
|
||||||
(this._stakingContractIfExists).address,
|
this._stakingContractIfExists.address,
|
||||||
);
|
);
|
||||||
// set staking proxy contract in zrx vault
|
// set staking proxy contract in zrx vault
|
||||||
await (this
|
await this._zrxVaultContractIfExists.setStakingContract.awaitTransactionSuccessAsync(
|
||||||
._zrxVaultContractIfExists).setStakingContract.awaitTransactionSuccessAsync(
|
this._stakingProxyContractIfExists.address,
|
||||||
(this._stakingProxyContractIfExists).address,
|
|
||||||
);
|
);
|
||||||
// set zrx vault in staking contract
|
// set zrx vault in staking contract
|
||||||
const setZrxVaultCalldata = (this
|
const setZrxVaultCalldata = this._stakingContractIfExists.setZrxVault.getABIEncodedTransactionData(
|
||||||
._stakingContractIfExists).setZrxVault.getABIEncodedTransactionData(
|
this._zrxVaultContractIfExists.address,
|
||||||
(this._zrxVaultContractIfExists).address,
|
|
||||||
);
|
);
|
||||||
const setZrxVaultTxData = {
|
const setZrxVaultTxData = {
|
||||||
from: this._ownerAddress,
|
from: this._ownerAddress,
|
||||||
to: (this._stakingProxyContractIfExists).address,
|
to: this._stakingProxyContractIfExists.address,
|
||||||
data: setZrxVaultCalldata,
|
data: setZrxVaultCalldata,
|
||||||
};
|
};
|
||||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||||
await this._web3Wrapper.sendTransactionAsync(setZrxVaultTxData),
|
await this._web3Wrapper.sendTransactionAsync(setZrxVaultTxData),
|
||||||
);
|
);
|
||||||
// set staking proxy contract in reward vault
|
// set staking proxy contract in reward vault
|
||||||
await (this
|
await this._rewardVaultContractIfExists.setStakingContract.awaitTransactionSuccessAsync(
|
||||||
._rewardVaultContractIfExists).setStakingContract.awaitTransactionSuccessAsync(
|
this._stakingProxyContractIfExists.address,
|
||||||
(this._stakingProxyContractIfExists).address,
|
|
||||||
);
|
);
|
||||||
// set reward vault in staking contract
|
// set reward vault in staking contract
|
||||||
const setStakingPoolRewardVaultCalldata = (this
|
const setStakingPoolRewardVaultCalldata = this._stakingContractIfExists.setStakingPoolRewardVault.getABIEncodedTransactionData(
|
||||||
._stakingContractIfExists).setStakingPoolRewardVault.getABIEncodedTransactionData(
|
this._rewardVaultContractIfExists.address,
|
||||||
(this._rewardVaultContractIfExists).address,
|
|
||||||
);
|
);
|
||||||
const setStakingPoolRewardVaultTxData = {
|
const setStakingPoolRewardVaultTxData = {
|
||||||
from: this._ownerAddress,
|
from: this._ownerAddress,
|
||||||
to: (this._stakingProxyContractIfExists).address,
|
to: this._stakingProxyContractIfExists.address,
|
||||||
data: setStakingPoolRewardVaultCalldata,
|
data: setStakingPoolRewardVaultCalldata,
|
||||||
};
|
};
|
||||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||||
@ -180,12 +176,20 @@ export class StakingWrapper {
|
|||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
///// STAKE /////
|
///// STAKE /////
|
||||||
public async depositZrxAndMintDeactivatedStakeAsync(owner: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
|
public async depositZrxAndMintDeactivatedStakeAsync(
|
||||||
const calldata = this.getStakingContract().depositZrxAndMintDeactivatedStake.getABIEncodedTransactionData(amount);
|
owner: string,
|
||||||
|
amount: BigNumber,
|
||||||
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
|
const calldata = this.getStakingContract().depositZrxAndMintDeactivatedStake.getABIEncodedTransactionData(
|
||||||
|
amount,
|
||||||
|
);
|
||||||
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
||||||
return txReceipt;
|
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 calldata = this.getStakingContract().depositZrxAndMintActivatedStake.getABIEncodedTransactionData(amount);
|
||||||
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
||||||
return txReceipt;
|
return txReceipt;
|
||||||
@ -195,7 +199,10 @@ export class StakingWrapper {
|
|||||||
poolId: string,
|
poolId: string,
|
||||||
amount: BigNumber,
|
amount: BigNumber,
|
||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): 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);
|
const txReceipt = await this._executeTransactionAsync(calldata, owner, new BigNumber(0), true);
|
||||||
return txReceipt;
|
return txReceipt;
|
||||||
}
|
}
|
||||||
@ -236,8 +243,13 @@ export class StakingWrapper {
|
|||||||
const txReceipt = await this._executeTransactionAsync(calldata, owner, new BigNumber(0), true);
|
const txReceipt = await this._executeTransactionAsync(calldata, owner, new BigNumber(0), true);
|
||||||
return txReceipt;
|
return txReceipt;
|
||||||
}
|
}
|
||||||
public async burnDeactivatedStakeAndWithdrawZrxAsync(owner: string, amount: BigNumber): Promise<TransactionReceiptWithDecodedLogs> {
|
public async burnDeactivatedStakeAndWithdrawZrxAsync(
|
||||||
const calldata = this.getStakingContract().burnDeactivatedStakeAndWithdrawZrx.getABIEncodedTransactionData(amount);
|
owner: string,
|
||||||
|
amount: BigNumber,
|
||||||
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
|
const calldata = this.getStakingContract().burnDeactivatedStakeAndWithdrawZrx.getABIEncodedTransactionData(
|
||||||
|
amount,
|
||||||
|
);
|
||||||
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
||||||
return txReceipt;
|
return txReceipt;
|
||||||
}
|
}
|
||||||
@ -408,9 +420,7 @@ export class StakingWrapper {
|
|||||||
public async goToNextEpochAsync(): Promise<TransactionReceiptWithDecodedLogs> {
|
public async goToNextEpochAsync(): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
const calldata = this.getStakingContract().finalizeFees.getABIEncodedTransactionData();
|
const calldata = this.getStakingContract().finalizeFees.getABIEncodedTransactionData();
|
||||||
const txReceipt = await this._executeTransactionAsync(calldata, undefined, new BigNumber(0), true);
|
const txReceipt = await this._executeTransactionAsync(calldata, undefined, new BigNumber(0), true);
|
||||||
logUtils.log(
|
logUtils.log(`Finalization costed ${txReceipt.gasUsed} gas`);
|
||||||
`Finalization costed ${txReceipt.gasUsed} gas`,
|
|
||||||
);
|
|
||||||
return txReceipt;
|
return txReceipt;
|
||||||
}
|
}
|
||||||
public async skipToNextEpochAsync(): Promise<TransactionReceiptWithDecodedLogs> {
|
public async skipToNextEpochAsync(): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
@ -461,7 +471,9 @@ export class StakingWrapper {
|
|||||||
public async getCurrentEpochEarliestEndTimeInSecondsAsync(): Promise<BigNumber> {
|
public async getCurrentEpochEarliestEndTimeInSecondsAsync(): Promise<BigNumber> {
|
||||||
const calldata = this.getStakingContract().getCurrentEpochEarliestEndTimeInSeconds.getABIEncodedTransactionData();
|
const calldata = this.getStakingContract().getCurrentEpochEarliestEndTimeInSeconds.getABIEncodedTransactionData();
|
||||||
const returnData = await this._callAsync(calldata);
|
const returnData = await this._callAsync(calldata);
|
||||||
const value = this.getStakingContract().getCurrentEpochEarliestEndTimeInSeconds.getABIDecodedReturnData(returnData);
|
const value = this.getStakingContract().getCurrentEpochEarliestEndTimeInSeconds.getABIDecodedReturnData(
|
||||||
|
returnData,
|
||||||
|
);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
public async getCurrentTimelockPeriodEndEpochAsync(): Promise<BigNumber> {
|
public async getCurrentTimelockPeriodEndEpochAsync(): Promise<BigNumber> {
|
||||||
@ -511,13 +523,19 @@ export class StakingWrapper {
|
|||||||
const isValid = this.getStakingContract().isValidExchangeAddress.getABIDecodedReturnData(returnData);
|
const isValid = this.getStakingContract().isValidExchangeAddress.getABIDecodedReturnData(returnData);
|
||||||
return isValid;
|
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 calldata = this.getStakingContract().addExchangeAddress.getABIEncodedTransactionData(exchangeAddress);
|
||||||
const ownerAddress = ownerAddressIfExists !== undefined ? ownerAddressIfExists : this._ownerAddress;
|
const ownerAddress = ownerAddressIfExists !== undefined ? ownerAddressIfExists : this._ownerAddress;
|
||||||
const txReceipt = await this._executeTransactionAsync(calldata, ownerAddress);
|
const txReceipt = await this._executeTransactionAsync(calldata, ownerAddress);
|
||||||
return txReceipt;
|
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 calldata = this.getStakingContract().removeExchangeAddress.getABIEncodedTransactionData(exchangeAddress);
|
||||||
const ownerAddress = ownerAddressIfExists !== undefined ? ownerAddressIfExists : this._ownerAddress;
|
const ownerAddress = ownerAddressIfExists !== undefined ? ownerAddressIfExists : this._ownerAddress;
|
||||||
const txReceipt = await this._executeTransactionAsync(calldata, ownerAddress);
|
const txReceipt = await this._executeTransactionAsync(calldata, ownerAddress);
|
||||||
@ -525,31 +543,48 @@ export class StakingWrapper {
|
|||||||
}
|
}
|
||||||
///// REWARDS /////
|
///// REWARDS /////
|
||||||
public async getTotalRewardBalanceOfStakingPoolAsync(poolId: string): Promise<BigNumber> {
|
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 returnData = await this._callAsync(calldata);
|
||||||
const value = this.getStakingContract().getTotalRewardBalanceOfStakingPool.getABIDecodedReturnData(returnData);
|
const value = this.getStakingContract().getTotalRewardBalanceOfStakingPool.getABIDecodedReturnData(returnData);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
public async getRewardBalanceOfStakingPoolOperatorAsync(poolId: string): Promise<BigNumber> {
|
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 returnData = await this._callAsync(calldata);
|
||||||
const value = this.getStakingContract().getRewardBalanceOfStakingPoolOperator.getABIDecodedReturnData(returnData);
|
const value = this.getStakingContract().getRewardBalanceOfStakingPoolOperator.getABIDecodedReturnData(
|
||||||
|
returnData,
|
||||||
|
);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
public async getRewardBalanceOfStakingPoolMembersAsync(poolId: string): Promise<BigNumber> {
|
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 returnData = await this._callAsync(calldata);
|
||||||
const value = this.getStakingContract().getRewardBalanceOfStakingPoolMembers.getABIDecodedReturnData(returnData);
|
const value = this.getStakingContract().getRewardBalanceOfStakingPoolMembers.getABIDecodedReturnData(
|
||||||
|
returnData,
|
||||||
|
);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
public async computeRewardBalanceOfStakingPoolMemberAsync(poolId: string, owner: string): Promise<BigNumber> {
|
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 returnData = await this._callAsync(calldata);
|
||||||
const value = this.getStakingContract().computeRewardBalanceOfStakingPoolMember.getABIDecodedReturnData(returnData);
|
const value = this.getStakingContract().computeRewardBalanceOfStakingPoolMember.getABIDecodedReturnData(
|
||||||
|
returnData,
|
||||||
|
);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
public async getTotalShadowBalanceOfStakingPoolAsync(poolId: string): Promise<BigNumber> {
|
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 returnData = await this._callAsync(calldata);
|
||||||
const value = this.getStakingContract().getTotalShadowBalanceOfStakingPool.getABIDecodedReturnData(returnData);
|
const value = this.getStakingContract().getTotalShadowBalanceOfStakingPool.getABIDecodedReturnData(returnData);
|
||||||
return value;
|
return value;
|
||||||
@ -568,7 +603,10 @@ export class StakingWrapper {
|
|||||||
amount: BigNumber,
|
amount: BigNumber,
|
||||||
operatorAddress: string,
|
operatorAddress: string,
|
||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): 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);
|
const txReceipt = await this._executeTransactionAsync(calldata, operatorAddress);
|
||||||
return txReceipt;
|
return txReceipt;
|
||||||
}
|
}
|
||||||
@ -577,7 +615,10 @@ export class StakingWrapper {
|
|||||||
amount: BigNumber,
|
amount: BigNumber,
|
||||||
owner: string,
|
owner: string,
|
||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): 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);
|
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
||||||
return txReceipt;
|
return txReceipt;
|
||||||
}
|
}
|
||||||
@ -585,12 +626,19 @@ export class StakingWrapper {
|
|||||||
poolId: string,
|
poolId: string,
|
||||||
operatorAddress: string,
|
operatorAddress: string,
|
||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
const calldata = this.getStakingContract().withdrawTotalRewardForStakingPoolOperator.getABIEncodedTransactionData(poolId);
|
const calldata = this.getStakingContract().withdrawTotalRewardForStakingPoolOperator.getABIEncodedTransactionData(
|
||||||
|
poolId,
|
||||||
|
);
|
||||||
const txReceipt = await this._executeTransactionAsync(calldata, operatorAddress);
|
const txReceipt = await this._executeTransactionAsync(calldata, operatorAddress);
|
||||||
return txReceipt;
|
return txReceipt;
|
||||||
}
|
}
|
||||||
public async withdrawTotalRewardForStakingPoolMemberAsync(poolId: string, owner: string): Promise<TransactionReceiptWithDecodedLogs> {
|
public async withdrawTotalRewardForStakingPoolMemberAsync(
|
||||||
const calldata = this.getStakingContract().withdrawTotalRewardForStakingPoolMember.getABIEncodedTransactionData(poolId);
|
poolId: string,
|
||||||
|
owner: string,
|
||||||
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
|
const calldata = this.getStakingContract().withdrawTotalRewardForStakingPoolMember.getABIEncodedTransactionData(
|
||||||
|
poolId,
|
||||||
|
);
|
||||||
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
||||||
return txReceipt;
|
return txReceipt;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
|
||||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||||
import {
|
import { chaiSetup, expectTransactionFailedAsync, provider, web3Wrapper } from '@0x/contracts-test-utils';
|
||||||
chaiSetup,
|
|
||||||
expectTransactionFailedAsync,
|
|
||||||
provider,
|
|
||||||
web3Wrapper,
|
|
||||||
} from '@0x/contracts-test-utils';
|
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { RevertReason } from '@0x/types';
|
import { RevertReason } from '@0x/types';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber } from '@0x/utils';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user