@0x:contracts-exchange Added the MixinProtocolFees contract
This commit is contained in:
@@ -30,8 +30,8 @@ import "@0x/contracts-exchange-libs/contracts/src/LibExchangeRichErrors.sol";
|
||||
import "@0x/contracts-staking/contracts/src/interfaces/IStaking.sol";
|
||||
import "./interfaces/IExchangeCore.sol";
|
||||
import "./MixinAssetProxyDispatcher.sol";
|
||||
import "./MixinProtocolFees.sol";
|
||||
import "./MixinSignatureValidator.sol";
|
||||
import "./MixinStakingManager.sol";
|
||||
|
||||
|
||||
contract MixinExchangeCore is
|
||||
@@ -40,7 +40,7 @@ contract MixinExchangeCore is
|
||||
IExchangeCore,
|
||||
MixinAssetProxyDispatcher,
|
||||
MixinSignatureValidator,
|
||||
MixinStakingManager
|
||||
MixinProtocolFees
|
||||
{
|
||||
using LibOrder for LibOrder.Order;
|
||||
using LibSafeMath for uint256;
|
||||
|
||||
54
contracts/exchange/contracts/src/MixinProtocolFees.sol
Normal file
54
contracts/exchange/contracts/src/MixinProtocolFees.sol
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
|
||||
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/IProtocolFees.sol";
|
||||
|
||||
|
||||
contract MixinProtocolFees is
|
||||
IProtocolFees,
|
||||
Ownable
|
||||
{
|
||||
// The protocol fee multiplier -- the owner can update this field.
|
||||
uint256 public protocolFeeMultiplier;
|
||||
|
||||
// The address of the registered protocolFeeCollector contract -- the owner can update this field.
|
||||
address public protocolFeeCollector;
|
||||
|
||||
/// @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 protocolFeeCollector address.
|
||||
/// @param updatedProtocolFeeCollector The updated protocolFeeCollector contract address.
|
||||
function updateProtocolFeeCollectorAddress(address updatedProtocolFeeCollector)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
emit UpdatedProtocolFeeCollectorAddress(protocolFeeCollector, updatedProtocolFeeCollector);
|
||||
protocolFeeCollector = updatedProtocolFeeCollector;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
|
||||
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 IProtocolFees {
|
||||
|
||||
// Logs updates to the protocol fee multiplier.
|
||||
event UpdatedProtocolFeeMultiplier(uint256 oldProtocolFeeMultiplier, uint256 updatedProtocolFeeMultiplier);
|
||||
|
||||
// Logs updates to the protocolFeeCollector address.
|
||||
event UpdatedProtocolFeeCollectorAddress(address oldProtocolFeeCollector, address updatedProtocolFeeCollector);
|
||||
|
||||
/// @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 protocolFeeCollector address.
|
||||
/// @param updatedProtocolFeeCollector The updated protocolFeeCollector contract address.
|
||||
function updateProtocolFeeCollectorAddress(address updatedProtocolFeeCollector)
|
||||
external;
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import * as IEIP1271Wallet from '../generated-artifacts/IEIP1271Wallet.json';
|
||||
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 IProtocolFees from '../generated-artifacts/IProtocolFees.json';
|
||||
import * as ISignatureValidator from '../generated-artifacts/ISignatureValidator.json';
|
||||
import * as IStakingManager from '../generated-artifacts/IStakingManager.json';
|
||||
import * as ITransactions from '../generated-artifacts/ITransactions.json';
|
||||
@@ -24,6 +25,7 @@ import * as LibExchangeRichErrorDecoder from '../generated-artifacts/LibExchange
|
||||
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 MixinProtocolFees from '../generated-artifacts/MixinProtocolFees.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';
|
||||
@@ -45,6 +47,7 @@ export const artifacts = {
|
||||
MixinAssetProxyDispatcher: MixinAssetProxyDispatcher as ContractArtifact,
|
||||
MixinExchangeCore: MixinExchangeCore as ContractArtifact,
|
||||
MixinMatchOrders: MixinMatchOrders as ContractArtifact,
|
||||
MixinProtocolFees: MixinProtocolFees as ContractArtifact,
|
||||
MixinSignatureValidator: MixinSignatureValidator as ContractArtifact,
|
||||
MixinStakingManager: MixinStakingManager as ContractArtifact,
|
||||
MixinTransactions: MixinTransactions as ContractArtifact,
|
||||
@@ -56,6 +59,7 @@ export const artifacts = {
|
||||
IExchange: IExchange as ContractArtifact,
|
||||
IExchangeCore: IExchangeCore as ContractArtifact,
|
||||
IMatchOrders: IMatchOrders as ContractArtifact,
|
||||
IProtocolFees: IProtocolFees as ContractArtifact,
|
||||
ISignatureValidator: ISignatureValidator as ContractArtifact,
|
||||
IStakingManager: IStakingManager as ContractArtifact,
|
||||
ITransactions: ITransactions as ContractArtifact,
|
||||
|
||||
@@ -11,6 +11,7 @@ export * from '../generated-wrappers/i_e_i_p1271_wallet';
|
||||
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_protocol_fees';
|
||||
export * from '../generated-wrappers/i_signature_validator';
|
||||
export * from '../generated-wrappers/i_staking_manager';
|
||||
export * from '../generated-wrappers/i_transactions';
|
||||
@@ -22,6 +23,7 @@ export * from '../generated-wrappers/lib_exchange_rich_error_decoder';
|
||||
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_protocol_fees';
|
||||
export * from '../generated-wrappers/mixin_signature_validator';
|
||||
export * from '../generated-wrappers/mixin_staking_manager';
|
||||
export * from '../generated-wrappers/mixin_transactions';
|
||||
|
||||
110
contracts/exchange/test/protocol_fees.ts
Normal file
110
contracts/exchange/test/protocol_fees.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { blockchainTests, constants, expect, LogDecoder } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, OwnableRevertErrors } from '@0x/utils';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
|
||||
import {
|
||||
artifacts,
|
||||
ExchangeContract,
|
||||
ExchangeUpdatedProtocolFeeCollectorAddressEventArgs,
|
||||
ExchangeUpdatedProtocolFeeMultiplierEventArgs,
|
||||
} from '../src';
|
||||
|
||||
blockchainTests.resets('MixinProtocolFees', env => {
|
||||
let accounts: string[];
|
||||
let exchange: ExchangeContract;
|
||||
let logDecoder: LogDecoder;
|
||||
let nonOwner: string;
|
||||
let owner: string;
|
||||
let protocolFeeCollector: 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];
|
||||
protocolFeeCollector = accounts[2];
|
||||
|
||||
// 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.updateProtocolFeeCollectorAddress.sendTransactionAsync(protocolFeeCollector, {
|
||||
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 protocolFeeCollector 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 `UpdatedProtocolFeeCollectorAddress` 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('updateProtocolFeeCollectorAddress', () => {
|
||||
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.updateProtocolFeeCollectorAddress.sendTransactionAsync(protocolFeeCollector, {
|
||||
from: nonOwner,
|
||||
});
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should succeed and emit an UpdatedProtocolFeeCollectorAddress event if msg.sender == owner', async () => {
|
||||
// Call the `updateProtocolFeeCollectorAddress()` function and get the receipt.
|
||||
const receipt = await logDecoder.getTxWithDecodedLogsAsync(
|
||||
await exchange.updateProtocolFeeCollectorAddress.sendTransactionAsync(protocolFeeCollector, {
|
||||
from: owner,
|
||||
}),
|
||||
);
|
||||
|
||||
// Verify that the protocolFeeCollector address was actually updated to the correct address.
|
||||
const updated = await exchange.protocolFeeCollector.callAsync();
|
||||
expect(updated).to.be.eq(protocolFeeCollector);
|
||||
|
||||
// Ensure that the correct `UpdatedProtocolFeeCollectorAddress` event was logged.
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<
|
||||
ExchangeUpdatedProtocolFeeCollectorAddressEventArgs
|
||||
>;
|
||||
expect(updatedEvent.event).to.be.eq('UpdatedProtocolFeeCollectorAddress');
|
||||
expect(updatedEvent.args.oldProtocolFeeCollector).to.be.eq(constants.NULL_ADDRESS);
|
||||
expect(updatedEvent.args.updatedProtocolFeeCollector).to.be.eq(protocolFeeCollector);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10,8 +10,7 @@ export const constants = {
|
||||
ExchangeFunctionName.SimulateDispatchTransferFromCalls,
|
||||
ExchangeFunctionName.TransferOwnership,
|
||||
ExchangeFunctionName.UpdateProtocolFeeMultiplier,
|
||||
ExchangeFunctionName.UpdateStakingAddress,
|
||||
ExchangeFunctionName.UpdateWethAddress,
|
||||
ExchangeFunctionName.UpdateProtocolFeeCollectorAddress,
|
||||
],
|
||||
SINGLE_FILL_FN_NAMES: [
|
||||
ExchangeFunctionName.FillOrder,
|
||||
|
||||
@@ -33,6 +33,5 @@ export enum ExchangeFunctionName {
|
||||
SimulateDispatchTransferFromCalls = 'simulateDispatchTransferFromCalls',
|
||||
TransferOwnership = 'transferOwnership',
|
||||
UpdateProtocolFeeMultiplier = 'updateProtocolFeeMultiplier',
|
||||
UpdateStakingAddress = 'updateStakingAddress',
|
||||
UpdateWethAddress = 'updateWethAddress',
|
||||
UpdateProtocolFeeCollectorAddress = 'updateProtocolFeeCollectorAddress',
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"generated-artifacts/IExchange.json",
|
||||
"generated-artifacts/IExchangeCore.json",
|
||||
"generated-artifacts/IMatchOrders.json",
|
||||
"generated-artifacts/IProtocolFees.json",
|
||||
"generated-artifacts/ISignatureValidator.json",
|
||||
"generated-artifacts/IStakingManager.json",
|
||||
"generated-artifacts/ITransactions.json",
|
||||
@@ -22,6 +23,7 @@
|
||||
"generated-artifacts/MixinAssetProxyDispatcher.json",
|
||||
"generated-artifacts/MixinExchangeCore.json",
|
||||
"generated-artifacts/MixinMatchOrders.json",
|
||||
"generated-artifacts/MixinProtocolFees.json",
|
||||
"generated-artifacts/MixinSignatureValidator.json",
|
||||
"generated-artifacts/MixinStakingManager.json",
|
||||
"generated-artifacts/MixinTransactions.json",
|
||||
|
||||
Reference in New Issue
Block a user