@0x/contracts-staking: Got the solidity compiling.

This commit is contained in:
Lawrence Forman
2019-09-12 17:36:17 -04:00
committed by Lawrence Forman
parent b57c0a2ebb
commit 294be37afc
9 changed files with 172 additions and 258 deletions

View File

@@ -19,7 +19,6 @@
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "../libs/LibStakingRichErrors.sol";
@@ -90,20 +89,20 @@ contract MixinExchangeFees is
// because we only need to remember state in the current epoch and the
// epoch prior.
uint256 currentEpoch = getCurrentEpoch();
mapping (bytes32 => IStructs.ActivePool) activePoolsThisEpoch =
mapping (bytes32 => IStructs.ActivePool) storage activePoolsThisEpoch =
activePoolsByEpoch[currentEpoch % 2];
IStructs.ActivePool memory pool = activePoolsThisEpoch[poolId]
IStructs.ActivePool memory pool = activePoolsThisEpoch[poolId];
// If the pool was previously inactive in this epoch, initialize it.
if (pool.feesCollected) {
if (pool.feesCollected == 0) {
// Compute weighted stake.
uint256 operatorStake = getStakeDelegatedToPoolByOwner(
rewardVault.operatorOf(poolId),
poolId
).currentEpochBalance;
pool.weightedStake = operatorStake.safeAdd(
totalStakeDelegatedToPool
poolStake
.safeSub(operatorStake)
.safeMul(delegatedStakeWeight)
.safeMul(rewardDelegatedStakeWeight)
.safeDiv(PPM_DENOMINATOR)
);
// Compute delegated (non-operator) stake.
@@ -127,45 +126,38 @@ contract MixinExchangeFees is
activePoolsThisEpoch[poolId] = pool;
}
/// @dev Pays the rebates for to market making pool that was active this epoch,
/// then updates the epoch and other time-based periods via the scheduler
/// (see MixinScheduler). This is intentionally permissionless, and may be called by anyone.
function finalizeFees()
external
{
// distribute fees to market maker pools as a reward
(uint256 totalActivePools,
uint256 totalFeesCollected,
uint256 totalWeightedStake,
uint256 totalRewardsPaid,
uint256 initialContractBalance,
uint256 finalContractBalance) = _distributeFeesAmongMakerPools();
emit RewardsPaid(
totalActivePools,
totalFeesCollected,
totalWeightedStake,
totalRewardsPaid,
initialContractBalance,
finalContractBalance
);
_goToNextEpoch();
}
/// @dev Returns the total amount of fees collected thus far, in the current epoch.
/// @return Amount of fees.
/// @return _totalFeesCollectedThisEpoch Total fees collected this epoch.
function getTotalProtocolFeesThisEpoch()
external
view
returns (uint256)
returns (uint256 _totalFeesCollectedThisEpoch)
{
uint256 wethBalance = IEtherToken(WETH_ADDRESS).balanceOf(address(this));
return address(this).balance.safeAdd(wethBalance);
_totalFeesCollectedThisEpoch = totalFeesCollectedThisEpoch;
}
/// @dev Returns the amount of fees attributed to the input pool this epoch.
/// @param poolId Pool Id to query.
/// @return feesCollectedByPool Amount of fees collected by the pool this epoch.
function getProtocolFeesThisEpochByPool(bytes32 poolId)
external
view
returns (uint256 feesCollected)
{
uint256 currentEpoch = getCurrentEpoch();
// Look up the pool for this epoch. The epoch index is `currentEpoch % 2`
// because we only need to remember state in the current epoch and the
// epoch prior.
IStructs.ActivePool memory pool = activePoolsByEpoch[getCurrentEpoch() % 2][poolId];
feesCollected = pool.feesCollected;
}
/// @dev Checks that the protocol fee passed into `payProtocolFee()` is valid.
/// @param protocolFeePaid The `protocolFeePaid` parameter to `payProtocolFee.`
function _assertValidProtocolFee(uint256 protocolFeePaid) private view {
function _assertValidProtocolFee(uint256 protocolFeePaid)
private
view
{
if (protocolFeePaid == 0 || (msg.value != protocolFeePaid && msg.value != 0)) {
LibRichErrors.rrevert(LibStakingRichErrors.InvalidProtocolFeePaymentError(
protocolFeePaid == 0 ?
@@ -176,143 +168,4 @@ contract MixinExchangeFees is
));
}
}
/// @dev Pays rewards to market making pools that were active this epoch.
/// Each pool receives a portion of the fees generated this epoch (see LibCobbDouglas) that is
/// proportional to (i) the fee volume attributed to their pool over the epoch, and
/// (ii) the amount of stake provided by the maker and their delegators. Rebates are paid
/// into the Reward Vault where they can be withdraw by makers and
/// the members of their pool. There will be a small amount of ETH leftover in this contract
/// after paying out the rebates; at present, this rolls over into the next epoch. Eventually,
/// we plan to deposit this leftover into a DAO managed by the 0x community.
/// @return totalActivePools Total active pools this epoch.
/// @return totalFeesCollected Total fees collected this epoch, across all active pools.
/// @return totalWeightedStake Total weighted stake attributed to each pool. Delegated stake is weighted less.
/// @return totalRewardsPaid Total rewards paid out across all active pools.
/// @return initialContractBalance Balance of this contract before paying rewards.
/// @return finalContractBalance Balance of this contract after paying rewards.
function _distributeFeesAmongMakerPools()
internal
returns (
uint256 totalActivePools,
uint256 totalFeesCollected,
uint256 totalWeightedStake,
uint256 totalRewardsPaid,
uint256 initialContractBalance,
uint256 finalContractBalance
)
{
// step 1/4 - withdraw the entire wrapped ether balance into this contract. WETH
// is unwrapped here to keep `payProtocolFee()` calls relatively cheap,
// and WETH is only withdrawn if this contract's WETH balance is nonzero.
_unwrapWETH();
// Initialize initial values
totalActivePools = activePoolsThisEpoch.length;
totalFeesCollected = 0;
totalWeightedStake = 0;
totalRewardsPaid = 0;
initialContractBalance = address(this).balance;
finalContractBalance = initialContractBalance;
// sanity check - is there a balance to payout and were there any active pools?
if (initialContractBalance == 0 || totalActivePools == 0) {
return (
totalActivePools,
totalFeesCollected,
totalWeightedStake,
totalRewardsPaid,
initialContractBalance,
finalContractBalance
);
}
// step 2/4 - compute stats for active maker pools
IStructs.ActivePool[] memory activePools = new IStructs.ActivePool[](totalActivePools);
uint32 delegatedStakeWeight = rewardDelegatedStakeWeight;
for (uint256 i = 0; i != totalActivePools; i++) {
bytes32 poolId = activePoolsThisEpoch[i];
// compute weighted stake
uint256 totalStakeDelegatedToPool = getTotalStakeDelegatedToPool(poolId).currentEpochBalance;
uint256 stakeHeldByPoolOperator = getStakeDelegatedToPoolByOwner(poolById[poolId].operator, poolId).currentEpochBalance;
uint256 weightedStake = stakeHeldByPoolOperator.safeAdd(
totalStakeDelegatedToPool
.safeSub(stakeHeldByPoolOperator)
.safeMul(delegatedStakeWeight)
.safeDiv(PPM_DENOMINATOR)
);
// store pool stats
activePools[i].poolId = poolId;
activePools[i].feesCollected = protocolFeesThisEpochByPool[poolId];
activePools[i].weightedStake = weightedStake;
activePools[i].delegatedStake = totalStakeDelegatedToPool;
// update cumulative amounts
totalFeesCollected = totalFeesCollected.safeAdd(activePools[i].feesCollected);
totalWeightedStake = totalWeightedStake.safeAdd(activePools[i].weightedStake);
}
// sanity check - this is a gas optimization that can be used because we assume a non-zero
// split between stake and fees generated in the cobb-douglas computation (see below).
if (totalFeesCollected == 0) {
return (
totalActivePools,
totalFeesCollected,
totalWeightedStake,
totalRewardsPaid,
initialContractBalance,
finalContractBalance
);
}
// step 3/4 - record reward for each pool
for (uint256 i = 0; i != totalActivePools; i++) {
// compute reward using cobb-douglas formula
uint256 reward = LibCobbDouglas.cobbDouglas(
initialContractBalance,
activePools[i].feesCollected,
totalFeesCollected,
totalWeightedStake != 0 ? activePools[i].weightedStake : 1, // only rewards are accounted for if no one has staked
totalWeightedStake != 0 ? totalWeightedStake : 1, // this is to avoid divide-by-zero in cobb douglas
cobbDouglasAlphaNumerator,
cobbDouglasAlphaDenominator
);
// pay reward to pool
_handleStakingPoolReward(
activePools[i].poolId,
reward,
activePools[i].delegatedStake,
currentEpoch
);
// clear state for gas refunds
protocolFeesThisEpochByPool[activePools[i].poolId] = 0;
activePoolsThisEpoch[i] = 0;
}
activePoolsThisEpoch.length = 0;
// step 4/4 send total payout to vault
// Sanity check rewards calculation
if (totalRewardsPaid > initialContractBalance) {
LibRichErrors.rrevert(LibStakingRichErrors.MiscalculatedRewardsError(
totalRewardsPaid,
initialContractBalance
));
}
finalContractBalance = address(this).balance;
return (
totalActivePools,
totalFeesCollected,
totalWeightedStake,
totalRewardsPaid,
initialContractBalance,
finalContractBalance
);
}
}

View File

@@ -117,6 +117,8 @@ contract MixinStorage is
// Rebate Vault (stores rewards for pools before they are moved to the eth vault on a per-user basis)
IStakingPoolRewardVault public rewardVault;
/* Tweakable parameters */
// Minimum seconds between epochs.
uint256 public epochDurationInSeconds;
@@ -139,26 +141,34 @@ contract MixinStorage is
/// @dev The total fees collected in the current epoch, built up iteratively
/// in `payProtocolFee()`.
uint256 totalFeesCollectedThisEpoch;
uint256 internal totalFeesCollectedThisEpoch;
/// @dev The total weighted stake in the current epoch, built up iteratively
/// in `payProtocolFee()`.
uint256 totalWeightedStakeThisEpoch;
uint256 internal totalWeightedStakeThisEpoch;
/// @dev State information for each active pool in an epoch.
/// In practice, we only store state for `currentEpoch % 2`.
mapping(uint256 => mapping(bytes32 => IStructs.ActivePool)) activePoolsByEpoch;
mapping(uint256 => mapping(bytes32 => IStructs.ActivePool)) internal activePoolsByEpoch;
/// @dev Number of pools activated in the current epoch.
uint256 numActivePoolsThisEpoch;
uint256 internal numActivePoolsThisEpoch;
/// @dev Rewards (ETH) available to the epoch being finalized (the previous
/// epoch). This is simply the balance of the contract at the end of
/// the epoch.
uint256 unfinalizedRewardsAvailable;
uint256 internal unfinalizedRewardsAvailable;
/// @dev The number of active pools in the last epoch that have yet to be
/// finalized through `finalizePools()`.
uint256 unfinalizedPoolsRemaining;
uint256 internal unfinalizedPoolsRemaining;
/// @dev The total fees collected for the epoch being finalized.
uint256 unfinalizedTotalFeesCollected;
uint256 internal unfinalizedTotalFeesCollected;
/// @dev The total fees collected for the epoch being finalized.
uint256 unfinalizedTotalWeightedStake;
uint256 internal unfinalizedTotalWeightedStake;
/// @dev How many rewards were paid at the end of finalization.
uint256 totalRewardsPaidLastEpoch;

View File

@@ -62,8 +62,8 @@ interface IStakingEvents {
uint256 epoch,
uint256 numActivePools,
uint256 rewardsAvailable,
uint256 totalWeightedStake,
uint256 totalFeesCollected
uint256 totalFeesCollected,
uint256 totalWeightedStake
);
/// @dev Emitted by MixinFinalizer when an epoch is fully finalized.
@@ -81,9 +81,9 @@ interface IStakingEvents {
/// @param poolId The pool's ID.
/// @param reward Amount of reward paid.
event RewardsPaid(
uint255 epoch,
uint256 epoch,
bytes32 poolId,
uint255 reward
uint256 reward
);
/// @dev Emitted whenever staking parameters are changed via the `setParams()` function.

View File

@@ -162,6 +162,10 @@ library LibStakingRichErrors {
bytes4 internal constant CUMULATIVE_REWARD_INTERVAL_ERROR_SELECTOR =
0x1f806d55;
// bytes4(keccak256("PreviousEpochNotFinalizedError(uint256,uint256)"))
bytes4 internal constant PREVIOUS_EPOCH_NOT_FINALIZED_ERROR_SELECTOR =
0x614b800a;
// solhint-disable func-name-mixedcase
function MiscalculatedRewardsError(
uint256 totalRewardsPaid,
@@ -491,4 +495,19 @@ library LibStakingRichErrors {
endEpoch
);
}
function PreviousEpochNotFinalizedError(
uint256 unfinalizedEpoch,
uint256 unfinalizedPoolsRemaining
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
PREVIOUS_EPOCH_NOT_FINALIZED_ERROR_SELECTOR,
unfinalizedEpoch,
unfinalizedPoolsRemaining
);
}
}

View File

@@ -19,19 +19,20 @@
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "../libs/LibStakingRichErrors.sol";
import "../libs/LibFixedMath.sol";
import "../immutable/MixinStorage.sol";
import "../immutable/MixinConstants.sol";
import "../immutable/MixinDeploymentConstants.sol";
import "../interfaces/IStakingEvents.sol";
import "../interfaces/IStructs.sol";
import "../stake/MixinStakeBalances.sol";
import "../sys/MixinScheduler.sol";
import "../staking_pools/MixinStakingPool.sol";
import "../staking_pools/MixinStakingPoolRewardVault.sol";
import "./MixinExchangeManager.sol";
import "./MixinScheduler.sol";
/// @dev This mixin contains functions related to finalizing epochs.
@@ -42,6 +43,7 @@ import "./MixinExchangeManager.sol";
contract MixinFinalizer is
IStakingEvents,
MixinConstants,
MixinDeploymentConstants,
Ownable,
MixinStorage,
MixinStakingPoolRewardVault,
@@ -65,7 +67,7 @@ contract MixinFinalizer is
uint256 closingEpoch = getCurrentEpoch();
// Make sure the previous epoch has been fully finalized.
if (unfinalizedPoolsRemaining != 0) {
LibRichErrors.rrevert(LibStakingRichErrors.PreviousEpochNotFinalized(
LibRichErrors.rrevert(LibStakingRichErrors.PreviousEpochNotFinalizedError(
closingEpoch.safeSub(1),
unfinalizedPoolsRemaining
));
@@ -75,20 +77,20 @@ contract MixinFinalizer is
// Populate finalization state.
unfinalizedPoolsRemaining = numActivePoolsThisEpoch;
unfinalizedRewardsAvailable = address(this).balance;
unfinalizedTotalFeesCollected = totalFeesCollected;
unfinalizedTotalWeightedStake = totalWeightedStake;
totalRewardsPaid = 0;
unfinalizedTotalFeesCollected = totalFeesCollectedThisEpoch;
unfinalizedTotalWeightedStake = totalWeightedStakeThisEpoch;
totalRewardsPaidLastEpoch = 0;
// Emit an event.
emit EpochEnded(
closingEpoch,
numActivePoolsThisEpoch,
rewardsAvailable,
totalWeightedStake,
totalFeesCollected
unfinalizedRewardsAvailable,
unfinalizedTotalFeesCollected,
unfinalizedTotalWeightedStake
);
// Reset current epoch state.
totalFeesCollected = 0;
totalWeightedStake = 0;
totalFeesCollectedThisEpoch = 0;
totalWeightedStakeThisEpoch = 0;
numActivePoolsThisEpoch = 0;
// Advance the epoch. This will revert if not enough time has passed.
_goToNextEpoch();
@@ -109,18 +111,19 @@ contract MixinFinalizer is
/// @param poolIds List of active pool IDs to finalize.
/// @return rewardsPaid Total rewards paid to the pools passed in.
/// @return _unfinalizedPoolsRemaining The number of unfinalized pools left.
function finalizePools(bytes32[] memory poolIds)
function finalizePools(bytes32[] calldata poolIds)
external
returns (uint256 rewardsPaid, uint256 _unfinalizedPoolsRemaining)
{
uint256 epoch = getCurrentEpoch().safeSub(1);
uint256 epoch = getCurrentEpoch();
uint256 priorEpoch = epoch.safeSub(1);
uint256 poolsRemaining = unfinalizedPoolsRemaining;
uint256 numPoolIds = poolIds.length;
uint256 rewardsPaid = 0;
// Pointer to the active pools in the last epoch.
// We use `(currentEpoch - 1) % 2` as the index to reuse state.
mapping(bytes32 => IStructs.ActivePool) storage activePools =
activePoolsByEpoch[epoch % 2];
activePoolsByEpoch[priorEpoch % 2];
for (uint256 i = 0; i < numPoolIds && poolsRemaining != 0; i++) {
bytes32 poolId = poolIds[i];
IStructs.ActivePool memory pool = activePools[poolId];
@@ -128,7 +131,10 @@ contract MixinFinalizer is
if (pool.feesCollected != 0) {
// Credit the pool with rewards.
// We will transfer the total rewards to the vault at the end.
rewardsPaid = rewardsPaid.safeAdd(_creditRewardsToPool(poolId, pool));
// Note that we credit the pool the rewards at the current epoch
// even though they were earned in the prior epoch.
uint256 reward = _creditRewardToPool(epoch, poolId, pool);
rewardsPaid = rewardsPaid.safeAdd(reward);
// Clear the pool state so we don't finalize it again,
// and to recoup some gas.
activePools[poolId] = IStructs.ActivePool(0, 0, 0);
@@ -147,62 +153,13 @@ contract MixinFinalizer is
// finalized.
if (poolsRemaining == 0) {
emit EpochFinalized(
epoch,
priorEpoch,
totalRewardsPaidLastEpoch,
unfinalizedRewardsAvailable.safeSub(totalRewardsPaidLastEpoch)
);
}
}
/// @dev Computes the rewards owned for a pool during finalization and
/// credits it in the RewardVault.
/// @param The epoch being finalized.
/// @param poolId The pool's ID.
/// @param pool The pool.
/// @return rewards Amount of rewards for this pool.
function _creditRewardsToPool(
uint256 epoch,
bytes32 poolId,
IStructs.ActivePool memory pool
)
internal
returns (uint256 rewards)
{
// Use the cobb-douglas function to compute the reward.
reward = _cobbDouglas(
unfinalizedRewardsAvailable,
pool.feesCollected,
unfinalizedTotalFeesCollected,
pool.weightedStake,
unfinalizedTotalWeightedStake,
cobbDouglasAlphaNumerator,
cobbDouglasAlphaDenomintor
);
// Credit the pool the reward in the RewardVault.
(, uint256 membersPortionOfReward) = rewardVault.recordDepositFor(
poolId,
reward,
// If no delegated stake, all rewards go to the operator.
pool.delegatedStake == 0
);
// Sync delegator rewards.
if (membersPortionOfReward != 0) {
_recordRewardForDelegators(
poolId,
membersPortionOfReward,
pool.delegatedStake
);
}
}
/// @dev Converts the entire WETH balance of the contract into ETH.
function _unwrapWETH() private {
uint256 wethBalance = IEtherToken(WETH_ADDRESS).balanceOf(address(this));
if (wethBalance != 0) {
IEtherToken(WETH_ADDRESS).withdraw(wethBalance);
}
}
/// @dev The cobb-douglas function used to compute fee-based rewards for
/// staking pools in a given epoch. Note that in this function there
/// is no limitation on alpha; we tend to get better rounding on the
@@ -267,4 +224,54 @@ contract MixinFinalizer is
// Multiply the above with totalRewards.
ownerRewards = LibFixedMath._uintMul(n, totalRewards);
}
/// @dev Computes the reward owed to a pool during finalization and
/// credits it in the RewardVault.
/// @param epoch The epoch being finalized.
/// @param poolId The pool's ID.
/// @param pool The pool.
/// @return rewards Amount of rewards for this pool.
function _creditRewardToPool(
uint256 epoch,
bytes32 poolId,
IStructs.ActivePool memory pool
)
private
returns (uint256 reward)
{
// Use the cobb-douglas function to compute the reward.
reward = _cobbDouglas(
unfinalizedRewardsAvailable,
pool.feesCollected,
unfinalizedTotalFeesCollected,
pool.weightedStake,
unfinalizedTotalWeightedStake,
cobbDouglasAlphaNumerator,
cobbDouglasAlphaDenomintor
);
// Credit the pool the reward in the RewardVault.
(, uint256 membersPortionOfReward) = rewardVault.recordDepositFor(
poolId,
reward,
// If no delegated stake, all rewards go to the operator.
pool.delegatedStake == 0
);
// Sync delegator rewards.
if (membersPortionOfReward != 0) {
_recordRewardForDelegators(
poolId,
membersPortionOfReward,
pool.delegatedStake
);
}
}
/// @dev Converts the entire WETH balance of the contract into ETH.
function _unwrapWETH() private {
uint256 wethBalance = IEtherToken(WETH_ADDRESS).balanceOf(address(this));
if (wethBalance != 0) {
IEtherToken(WETH_ADDRESS).withdraw(wethBalance);
}
}
}

View File

@@ -88,12 +88,6 @@ contract TestStorageLayout is
if sub(currentEpochStartTimeInSeconds_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(protocolFeesThisEpochByPool_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(activePoolsThisEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_cumulativeRewardsByPool_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
@@ -129,6 +123,33 @@ contract TestStorageLayout is
if sub(cobbDouglasAlphaDenominator_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(totalFeesCollectedThisEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(totalWeightedStakeThisEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(activePoolsByEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(numActivePoolsThisEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(unfinalizedRewardsAvailable_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(unfinalizedPoolsRemaining_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(unfinalizedTotalFeesCollected_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(unfinalizedTotalWeightedStake_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(totalRewardsPaidLastEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
}
}
}

View File

@@ -27,6 +27,7 @@ import * as MixinCumulativeRewards from '../generated-artifacts/MixinCumulativeR
import * as MixinDeploymentConstants from '../generated-artifacts/MixinDeploymentConstants.json';
import * as MixinExchangeFees from '../generated-artifacts/MixinExchangeFees.json';
import * as MixinExchangeManager from '../generated-artifacts/MixinExchangeManager.json';
import * as MixinFinalizer from '../generated-artifacts/MixinFinalizer.json';
import * as MixinParams from '../generated-artifacts/MixinParams.json';
import * as MixinScheduler from '../generated-artifacts/MixinScheduler.json';
import * as MixinStake from '../generated-artifacts/MixinStake.json';
@@ -63,6 +64,7 @@ export const artifacts = {
StakingProxy: StakingProxy as ContractArtifact,
MixinExchangeFees: MixinExchangeFees as ContractArtifact,
MixinExchangeManager: MixinExchangeManager as ContractArtifact,
MixinFinalizer: MixinFinalizer as ContractArtifact,
MixinConstants: MixinConstants as ContractArtifact,
MixinDeploymentConstants: MixinDeploymentConstants as ContractArtifact,
MixinStorage: MixinStorage as ContractArtifact,

View File

@@ -25,6 +25,7 @@ export * from '../generated-wrappers/mixin_cumulative_rewards';
export * from '../generated-wrappers/mixin_deployment_constants';
export * from '../generated-wrappers/mixin_exchange_fees';
export * from '../generated-wrappers/mixin_exchange_manager';
export * from '../generated-wrappers/mixin_finalizer';
export * from '../generated-wrappers/mixin_params';
export * from '../generated-wrappers/mixin_scheduler';
export * from '../generated-wrappers/mixin_stake';

View File

@@ -25,6 +25,7 @@
"generated-artifacts/MixinDeploymentConstants.json",
"generated-artifacts/MixinExchangeFees.json",
"generated-artifacts/MixinExchangeManager.json",
"generated-artifacts/MixinFinalizer.json",
"generated-artifacts/MixinParams.json",
"generated-artifacts/MixinScheduler.json",
"generated-artifacts/MixinStake.json",