@0x:contracts-exchange
Added the MixinStakingManager contract
This commit is contained in:
parent
365cb161cf
commit
415af90ae7
@ -28,13 +28,15 @@ import "@0x/contracts-exchange-libs/contracts/src/LibExchangeRichErrors.sol";
|
||||
import "./interfaces/IExchangeCore.sol";
|
||||
import "./MixinAssetProxyDispatcher.sol";
|
||||
import "./MixinSignatureValidator.sol";
|
||||
import "./MixinStakingManager.sol";
|
||||
|
||||
|
||||
contract MixinExchangeCore is
|
||||
LibEIP712ExchangeDomain,
|
||||
IExchangeCore,
|
||||
MixinAssetProxyDispatcher,
|
||||
MixinSignatureValidator
|
||||
MixinSignatureValidator,
|
||||
MixinStakingManager
|
||||
{
|
||||
using LibOrder for LibOrder.Order;
|
||||
using LibSafeMath for uint256;
|
||||
|
67
contracts/exchange/contracts/src/MixinStakingManager.sol
Normal file
67
contracts/exchange/contracts/src/MixinStakingManager.sol
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/Ownable.sol";
|
||||
import "./interfaces/IStakingManager.sol";
|
||||
|
||||
|
||||
contract MixinStakingManager is
|
||||
IStakingManager,
|
||||
Ownable
|
||||
{
|
||||
// The protocol fee multiplier -- the owner can update this field.
|
||||
uint256 public protocolFeeMultiplier;
|
||||
|
||||
// The address of the registered staking contract -- the owner can update this field.
|
||||
address public staking;
|
||||
|
||||
// The address of the wrapped ether contract -- the owner can update this field.
|
||||
address public weth;
|
||||
|
||||
/// @dev Allows the owner to update the protocol fee multiplier.
|
||||
/// @param updatedProtocolFeeMultiplier The updated protocol fee multiplier.
|
||||
function updateProtocolFeeMultiplier(uint256 updatedProtocolFeeMultiplier)
|
||||
external
|
||||
onlyOwner()
|
||||
{
|
||||
emit UpdatedProtocolFeeMultiplier(protocolFeeMultiplier, updatedProtocolFeeMultiplier);
|
||||
protocolFeeMultiplier = updatedProtocolFeeMultiplier;
|
||||
}
|
||||
|
||||
/// @dev Allows the owner to update the staking address.
|
||||
/// @param updatedStaking The updated staking contract address.
|
||||
function updateStakingAddress(address updatedStaking)
|
||||
external
|
||||
onlyOwner()
|
||||
{
|
||||
emit UpdatedStakingAddress(staking, updatedStaking);
|
||||
staking = updatedStaking;
|
||||
}
|
||||
|
||||
/// @dev Allows the owner to update the WETH address.
|
||||
/// @param updatedWeth The updated WETH contract address.
|
||||
function updateWethAddress(address updatedWeth)
|
||||
external
|
||||
onlyOwner()
|
||||
{
|
||||
emit UpdatedWethAddress(weth, updatedWeth);
|
||||
weth = updatedWeth;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
|
||||
contract IStakingManager {
|
||||
|
||||
// Logs updates to the protocol fee multiplier.
|
||||
event UpdatedProtocolFeeMultiplier(uint256 oldProtocolFeeMultiplier, uint256 updatedProtocolFeeMultiplier);
|
||||
|
||||
// Logs updates to the staking address.
|
||||
event UpdatedStakingAddress(address oldStaking, address updatedStaking);
|
||||
|
||||
// Logs updates to the weth address.
|
||||
event UpdatedWethAddress(address oldWeth, address updatedWeth);
|
||||
|
||||
/// @dev Allows the owner to update the protocol fee multiplier.
|
||||
/// @param updatedProtocolFeeMultiplier The updated protocol fee multiplier.
|
||||
function updateProtocolFeeMultiplier(uint256 updatedProtocolFeeMultiplier)
|
||||
external;
|
||||
|
||||
/// @dev Allows the owner to update the staking address.
|
||||
/// @param updatedStaking The updated staking contract address.
|
||||
function updateStakingAddress(address updatedStaking)
|
||||
external;
|
||||
|
||||
/// @dev Allows the owner to update the WETH address.
|
||||
/// @param updatedWeth The updated WETH contract address.
|
||||
function updateWethAddress(address updatedWeth)
|
||||
external;
|
||||
}
|
@ -35,7 +35,7 @@
|
||||
"compile:truffle": "truffle compile"
|
||||
},
|
||||
"config": {
|
||||
"abis": "./generated-artifacts/@(Exchange|ExchangeWrapper|IAssetProxy|IAssetProxyDispatcher|IEIP1271Wallet|IExchange|IExchangeCore|IMatchOrders|ISignatureValidator|ITransactions|ITransferSimulator|IWallet|IWrapperFunctions|IsolatedExchange|LibExchangeRichErrorDecoder|MixinAssetProxyDispatcher|MixinExchangeCore|MixinMatchOrders|MixinSignatureValidator|MixinTransactions|MixinTransferSimulator|MixinWrapperFunctions|ReentrancyTester|TestAssetProxyDispatcher|TestExchangeInternals|TestLibExchangeRichErrorDecoder|TestSignatureValidator|TestTransactions|TestValidatorWallet|TestWrapperFunctions|Whitelist).json",
|
||||
"abis": "./generated-artifacts/@(Exchange|ExchangeWrapper|IAssetProxy|IAssetProxyDispatcher|IEIP1271Wallet|IExchange|IExchangeCore|IMatchOrders|ISignatureValidator|IStakingManager|ITransactions|ITransferSimulator|IWallet|IWrapperFunctions|IsolatedExchange|LibExchangeRichErrorDecoder|MixinAssetProxyDispatcher|MixinExchangeCore|MixinMatchOrders|MixinSignatureValidator|MixinStakingManager|MixinTransactions|MixinTransferSimulator|MixinWrapperFunctions|ReentrancyTester|TestAssetProxyDispatcher|TestExchangeInternals|TestLibExchangeRichErrorDecoder|TestSignatureValidator|TestTransactions|TestValidatorWallet|TestWrapperFunctions|Whitelist).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
|
@ -14,16 +14,18 @@ import * as IExchange from '../generated-artifacts/IExchange.json';
|
||||
import * as IExchangeCore from '../generated-artifacts/IExchangeCore.json';
|
||||
import * as IMatchOrders from '../generated-artifacts/IMatchOrders.json';
|
||||
import * as ISignatureValidator from '../generated-artifacts/ISignatureValidator.json';
|
||||
import * as IsolatedExchange from '../generated-artifacts/IsolatedExchange.json';
|
||||
import * as IStakingManager from '../generated-artifacts/IStakingManager.json';
|
||||
import * as ITransactions from '../generated-artifacts/ITransactions.json';
|
||||
import * as ITransferSimulator from '../generated-artifacts/ITransferSimulator.json';
|
||||
import * as IWallet from '../generated-artifacts/IWallet.json';
|
||||
import * as IWrapperFunctions from '../generated-artifacts/IWrapperFunctions.json';
|
||||
import * as IsolatedExchange from '../generated-artifacts/IsolatedExchange.json';
|
||||
import * as LibExchangeRichErrorDecoder from '../generated-artifacts/LibExchangeRichErrorDecoder.json';
|
||||
import * as MixinAssetProxyDispatcher from '../generated-artifacts/MixinAssetProxyDispatcher.json';
|
||||
import * as MixinExchangeCore from '../generated-artifacts/MixinExchangeCore.json';
|
||||
import * as MixinMatchOrders from '../generated-artifacts/MixinMatchOrders.json';
|
||||
import * as MixinSignatureValidator from '../generated-artifacts/MixinSignatureValidator.json';
|
||||
import * as MixinStakingManager from '../generated-artifacts/MixinStakingManager.json';
|
||||
import * as MixinTransactions from '../generated-artifacts/MixinTransactions.json';
|
||||
import * as MixinTransferSimulator from '../generated-artifacts/MixinTransferSimulator.json';
|
||||
import * as MixinWrapperFunctions from '../generated-artifacts/MixinWrapperFunctions.json';
|
||||
@ -44,6 +46,7 @@ export const artifacts = {
|
||||
MixinExchangeCore: MixinExchangeCore as ContractArtifact,
|
||||
MixinMatchOrders: MixinMatchOrders as ContractArtifact,
|
||||
MixinSignatureValidator: MixinSignatureValidator as ContractArtifact,
|
||||
MixinStakingManager: MixinStakingManager as ContractArtifact,
|
||||
MixinTransactions: MixinTransactions as ContractArtifact,
|
||||
MixinTransferSimulator: MixinTransferSimulator as ContractArtifact,
|
||||
MixinWrapperFunctions: MixinWrapperFunctions as ContractArtifact,
|
||||
@ -54,6 +57,7 @@ export const artifacts = {
|
||||
IExchangeCore: IExchangeCore as ContractArtifact,
|
||||
IMatchOrders: IMatchOrders as ContractArtifact,
|
||||
ISignatureValidator: ISignatureValidator as ContractArtifact,
|
||||
IStakingManager: IStakingManager as ContractArtifact,
|
||||
ITransactions: ITransactions as ContractArtifact,
|
||||
ITransferSimulator: ITransferSimulator as ContractArtifact,
|
||||
IWallet: IWallet as ContractArtifact,
|
||||
|
@ -12,6 +12,7 @@ export * from '../generated-wrappers/i_exchange';
|
||||
export * from '../generated-wrappers/i_exchange_core';
|
||||
export * from '../generated-wrappers/i_match_orders';
|
||||
export * from '../generated-wrappers/i_signature_validator';
|
||||
export * from '../generated-wrappers/i_staking_manager';
|
||||
export * from '../generated-wrappers/i_transactions';
|
||||
export * from '../generated-wrappers/i_transfer_simulator';
|
||||
export * from '../generated-wrappers/i_wallet';
|
||||
@ -22,6 +23,7 @@ export * from '../generated-wrappers/mixin_asset_proxy_dispatcher';
|
||||
export * from '../generated-wrappers/mixin_exchange_core';
|
||||
export * from '../generated-wrappers/mixin_match_orders';
|
||||
export * from '../generated-wrappers/mixin_signature_validator';
|
||||
export * from '../generated-wrappers/mixin_staking_manager';
|
||||
export * from '../generated-wrappers/mixin_transactions';
|
||||
export * from '../generated-wrappers/mixin_transfer_simulator';
|
||||
export * from '../generated-wrappers/mixin_wrapper_functions';
|
||||
|
143
contracts/exchange/test/staking_manager.ts
Normal file
143
contracts/exchange/test/staking_manager.ts
Normal file
@ -0,0 +1,143 @@
|
||||
import { blockchainTests, constants, expect, LogDecoder } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, OwnableRevertErrors } from '@0x/utils';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
|
||||
import {
|
||||
artifacts,
|
||||
ExchangeContract,
|
||||
ExchangeUpdatedProtocolFeeMultiplierEventArgs,
|
||||
ExchangeUpdatedStakingAddressEventArgs,
|
||||
ExchangeUpdatedWethAddressEventArgs,
|
||||
} from '../src';
|
||||
|
||||
blockchainTests.resets('MixinStakingManager', env => {
|
||||
let accounts: string[];
|
||||
let exchange: ExchangeContract;
|
||||
let logDecoder: LogDecoder;
|
||||
let nonOwner: string;
|
||||
let owner: string;
|
||||
let staking: string;
|
||||
let weth: string;
|
||||
|
||||
// The protocolFeeMultiplier that will be used to test the update functions.
|
||||
const protocolFeeMultiplier = new BigNumber(15000);
|
||||
|
||||
before(async () => {
|
||||
accounts = await env.web3Wrapper.getAvailableAddressesAsync();
|
||||
owner = accounts[0];
|
||||
nonOwner = accounts[1];
|
||||
staking = accounts[2];
|
||||
weth = accounts[3];
|
||||
|
||||
// Update the from address of the txDefaults. This is the address that will become the owner.
|
||||
env.txDefaults.from = owner;
|
||||
|
||||
// Deploy the exchange contract.
|
||||
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
|
||||
artifacts.Exchange,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
{},
|
||||
new BigNumber(1337),
|
||||
);
|
||||
|
||||
// Configure the log decoder
|
||||
logDecoder = new LogDecoder(env.web3Wrapper, artifacts);
|
||||
});
|
||||
|
||||
blockchainTests.resets('updateProtocolFeeMultiplier', () => {
|
||||
it('should revert if msg.sender != owner', async () => {
|
||||
const expectedError = new OwnableRevertErrors.OnlyOwnerError(nonOwner, owner);
|
||||
|
||||
// Ensure that the transaction reverts with the expected rich error.
|
||||
const tx = exchange.updateStakingAddress.sendTransactionAsync(staking, {
|
||||
from: nonOwner,
|
||||
});
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should succeed and emit an UpdatedProtocolFeeMultiplier event if msg.sender == owner', async () => {
|
||||
// Call the `updateProtocolFeeMultiplier()` function and get the receipt.
|
||||
const receipt = await logDecoder.getTxWithDecodedLogsAsync(
|
||||
await exchange.updateProtocolFeeMultiplier.sendTransactionAsync(protocolFeeMultiplier, {
|
||||
from: owner,
|
||||
}),
|
||||
);
|
||||
|
||||
// Verify that the staking address was actually updated to the correct address.
|
||||
const updated = await exchange.protocolFeeMultiplier.callAsync();
|
||||
expect(updated).bignumber.to.be.eq(protocolFeeMultiplier);
|
||||
|
||||
// Ensure that the correct `UpdatedStakingAddress` event was logged.
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<ExchangeUpdatedProtocolFeeMultiplierEventArgs>;
|
||||
expect(updatedEvent.event).to.be.eq('UpdatedProtocolFeeMultiplier');
|
||||
expect(updatedEvent.args.oldProtocolFeeMultiplier).bignumber.to.be.eq(constants.ZERO_AMOUNT);
|
||||
expect(updatedEvent.args.updatedProtocolFeeMultiplier).bignumber.to.be.eq(protocolFeeMultiplier);
|
||||
});
|
||||
});
|
||||
|
||||
blockchainTests.resets('updateStakingAddress', () => {
|
||||
it('should revert if msg.sender != owner', async () => {
|
||||
const expectedError = new OwnableRevertErrors.OnlyOwnerError(nonOwner, owner);
|
||||
|
||||
// Ensure that the transaction reverts with the expected rich error.
|
||||
const tx = exchange.updateStakingAddress.sendTransactionAsync(staking, {
|
||||
from: nonOwner,
|
||||
});
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should succeed and emit an UpdatedStakingAddress event if msg.sender == owner', async () => {
|
||||
// Call the `updateStakingAddress()` function and get the receipt.
|
||||
const receipt = await logDecoder.getTxWithDecodedLogsAsync(
|
||||
await exchange.updateStakingAddress.sendTransactionAsync(staking, {
|
||||
from: owner,
|
||||
}),
|
||||
);
|
||||
|
||||
// Verify that the staking address was actually updated to the correct address.
|
||||
const updated = await exchange.staking.callAsync();
|
||||
expect(updated).to.be.eq(staking);
|
||||
|
||||
// Ensure that the correct `UpdatedStakingAddress` event was logged.
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<ExchangeUpdatedStakingAddressEventArgs>;
|
||||
expect(updatedEvent.event).to.be.eq('UpdatedStakingAddress');
|
||||
expect(updatedEvent.args.oldStaking).to.be.eq(constants.NULL_ADDRESS);
|
||||
expect(updatedEvent.args.updatedStaking).to.be.eq(staking);
|
||||
});
|
||||
});
|
||||
|
||||
blockchainTests.resets('updateWethAddress', () => {
|
||||
it('should revert if msg.sender != owner', async () => {
|
||||
const expectedError = new OwnableRevertErrors.OnlyOwnerError(nonOwner, owner);
|
||||
|
||||
// Ensure that the transaction reverts with the expected rich error.
|
||||
const tx = exchange.updateWethAddress.sendTransactionAsync(weth, {
|
||||
from: nonOwner,
|
||||
});
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should succeed and emit an UpdatedStakingAddress event if msg.sender == owner', async () => {
|
||||
// Call the `updateWethAddress()` function and get the receipt.
|
||||
const receipt = await logDecoder.getTxWithDecodedLogsAsync(
|
||||
await exchange.updateWethAddress.sendTransactionAsync(weth, {
|
||||
from: owner,
|
||||
}),
|
||||
);
|
||||
|
||||
// Verify that the staking address was actually updated to the correct address.
|
||||
const updated = await exchange.weth.callAsync();
|
||||
expect(updated).to.be.eq(weth);
|
||||
|
||||
// Ensure that the correct `UpdatedStakingAddress` event was logged.
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<ExchangeUpdatedWethAddressEventArgs>;
|
||||
expect(updatedEvent.event).to.be.eq('UpdatedWethAddress');
|
||||
expect(updatedEvent.args.oldWeth).to.be.eq(constants.NULL_ADDRESS);
|
||||
expect(updatedEvent.args.updatedWeth).to.be.eq(weth);
|
||||
});
|
||||
});
|
||||
});
|
@ -9,6 +9,9 @@ export const constants = {
|
||||
ExchangeFunctionName.RegisterAssetProxy,
|
||||
ExchangeFunctionName.SimulateDispatchTransferFromCalls,
|
||||
ExchangeFunctionName.TransferOwnership,
|
||||
ExchangeFunctionName.UpdateProtocolFeeMultiplier,
|
||||
ExchangeFunctionName.UpdateStakingAddress,
|
||||
ExchangeFunctionName.UpdateWethAddress,
|
||||
],
|
||||
SINGLE_FILL_FN_NAMES: [
|
||||
ExchangeFunctionName.FillOrder,
|
||||
|
@ -32,4 +32,7 @@ export enum ExchangeFunctionName {
|
||||
SetSignatureValidatorApproval = 'setSignatureValidatorApproval',
|
||||
SimulateDispatchTransferFromCalls = 'simulateDispatchTransferFromCalls',
|
||||
TransferOwnership = 'transferOwnership',
|
||||
UpdateProtocolFeeMultiplier = 'updateProtocolFeeMultiplier',
|
||||
UpdateStakingAddress = 'updateStakingAddress',
|
||||
UpdateWethAddress = 'updateWethAddress',
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
"generated-artifacts/IExchangeCore.json",
|
||||
"generated-artifacts/IMatchOrders.json",
|
||||
"generated-artifacts/ISignatureValidator.json",
|
||||
"generated-artifacts/IStakingManager.json",
|
||||
"generated-artifacts/ITransactions.json",
|
||||
"generated-artifacts/ITransferSimulator.json",
|
||||
"generated-artifacts/IWallet.json",
|
||||
@ -22,6 +23,7 @@
|
||||
"generated-artifacts/MixinExchangeCore.json",
|
||||
"generated-artifacts/MixinMatchOrders.json",
|
||||
"generated-artifacts/MixinSignatureValidator.json",
|
||||
"generated-artifacts/MixinStakingManager.json",
|
||||
"generated-artifacts/MixinTransactions.json",
|
||||
"generated-artifacts/MixinTransferSimulator.json",
|
||||
"generated-artifacts/MixinWrapperFunctions.json",
|
||||
|
Loading…
x
Reference in New Issue
Block a user