From d280a332512b00ff9a0f7192da564474ea81a2de Mon Sep 17 00:00:00 2001 From: decanus Date: Thu, 17 May 2018 12:01:20 +0200 Subject: [PATCH 1/7] started working on new fees --- contracts/Exchange.sol | 9 --------- contracts/Fees/FeeInterface.sol | 7 +++++++ contracts/Fees/FeeManager.sol | 25 +++++++++++++++++++++++++ contracts/Libraries/ExchangeLibrary.sol | 19 +++++++++++++++++-- 4 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 contracts/Fees/FeeInterface.sol create mode 100644 contracts/Fees/FeeManager.sol diff --git a/contracts/Exchange.sol b/contracts/Exchange.sol index 707bf5c..9f1029f 100644 --- a/contracts/Exchange.sol +++ b/contracts/Exchange.sol @@ -13,8 +13,6 @@ contract Exchange is Ownable, ExchangeInterface { address constant public ETH = 0x0; - uint256 constant public MAX_FEE = 5000000000000000; // 0.5% ((0.5 / 100) * 10**18) - ExchangeLibrary.Exchange public exchange; function Exchange(uint _takerFee, address _feeAccount, VaultInterface _vault) public { @@ -144,13 +142,6 @@ contract Exchange is Ownable, ExchangeInterface { return exchange.fills[hash]; } - /// @dev Sets the taker fee. - /// @param _takerFee New taker fee. - function setFees(uint _takerFee) public onlyOwner { - require(_takerFee <= MAX_FEE); - exchange.takerFee = _takerFee; - } - /// @dev Sets the account where fees will be transferred to. /// @param _feeAccount Address for the account. function setFeeAccount(address _feeAccount) public onlyOwner { diff --git a/contracts/Fees/FeeInterface.sol b/contracts/Fees/FeeInterface.sol new file mode 100644 index 0000000..059eedb --- /dev/null +++ b/contracts/Fees/FeeInterface.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.4.18; + +interface FeeInterface { + + function fees(address user) external view returns (uint); + +} diff --git a/contracts/Fees/FeeManager.sol b/contracts/Fees/FeeManager.sol new file mode 100644 index 0000000..a2cfb49 --- /dev/null +++ b/contracts/Fees/FeeManager.sol @@ -0,0 +1,25 @@ +pragma solidity ^0.4.18; + +import "./FeeInterface.sol"; +import "./../Ownership/Ownable.sol"; + +contract FeeManager is FeeInterface { + + uint256 constant public MAX_FEE = 5000000000000000; // 0.5% ((0.5 / 100) * 10**18) + + mapping (uint => uint) public tiers; + mapping (address => uint) public level; + + function setTier(uint tier, uint fee) external onlyOwner { + require(fee <= MAX_FEE); + tiers[tier] = fee; + } + + function setUserLevel(address user, uint tier) external onlyOwner { + level[user] = tier; + } + + function fees(address user) external view returns (uint) { + return tiers[level[user]]; + } +} diff --git a/contracts/Libraries/ExchangeLibrary.sol b/contracts/Libraries/ExchangeLibrary.sol index ac60775..dcf1000 100644 --- a/contracts/Libraries/ExchangeLibrary.sol +++ b/contracts/Libraries/ExchangeLibrary.sol @@ -5,11 +5,13 @@ import "./SafeMath.sol"; import "@dexyproject/signature-validator/contracts/SignatureValidator.sol"; import "./../Vault/VaultInterface.sol"; import "./../HookSubscriber.sol"; +import "./../Fees/FeeInterface.sol"; library ExchangeLibrary { using SafeMath for *; using OrderLibrary for OrderLibrary.Order; + using ExchangeLibrary for ExchangeLibrary.Exchange; event Traded( bytes32 indexed hash, @@ -23,7 +25,7 @@ library ExchangeLibrary { struct Exchange { VaultInterface vault; - uint takerFee; + FeeInterface fees; address feeAccount; mapping (address => mapping (bytes32 => bool)) orders; mapping (bytes32 => uint) fills; @@ -61,7 +63,7 @@ library ExchangeLibrary { require(self.vault.balanceOf(order.takerToken, taker) >= fillAmount); uint makeAmount = order.makerTokenAmount.mul(fillAmount).div(order.takerTokenAmount); - uint tradeTakerFee = makeAmount.mul(self.takerFee).div(1 ether); + uint tradeTakerFee = self.calculateFee(makeAmount, taker); if (tradeTakerFee > 0) { self.vault.transfer(order.makerToken, order.maker, self.feeAccount, tradeTakerFee); @@ -165,4 +167,17 @@ library ExchangeLibrary { return remainder.mul(1000000).div(numerator.mul(target)); } + + function calculateFee(Exchange storage self, uint makeAmount, address taker) + internal + view + returns (uint) + { + uint feeAmount = self.fees.fees(taker); + if (feeAmount == 0) { + return 0; + } + + return makeAmount.mul(feeAmount).div(1 ether); + } } From 09be49057d271cfdf02bdcffeafbca7e8cc57d6e Mon Sep 17 00:00:00 2001 From: decanus Date: Thu, 17 May 2018 12:21:24 +0200 Subject: [PATCH 2/7] Renamed fees to fee manager --- contracts/Libraries/ExchangeLibrary.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Libraries/ExchangeLibrary.sol b/contracts/Libraries/ExchangeLibrary.sol index dcf1000..a99f4e5 100644 --- a/contracts/Libraries/ExchangeLibrary.sol +++ b/contracts/Libraries/ExchangeLibrary.sol @@ -25,7 +25,7 @@ library ExchangeLibrary { struct Exchange { VaultInterface vault; - FeeInterface fees; + FeeInterface feeManager; address feeAccount; mapping (address => mapping (bytes32 => bool)) orders; mapping (bytes32 => uint) fills; @@ -173,7 +173,7 @@ library ExchangeLibrary { view returns (uint) { - uint feeAmount = self.fees.fees(taker); + uint feeAmount = self.feeManager.fees(taker); if (feeAmount == 0) { return 0; } From 0b250f139e0af990667c6fa4e317bc667636f33e Mon Sep 17 00:00:00 2001 From: decanus Date: Thu, 17 May 2018 18:19:00 +0200 Subject: [PATCH 3/7] minor reworking --- contracts/Libraries/ExchangeLibrary.sol | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/contracts/Libraries/ExchangeLibrary.sol b/contracts/Libraries/ExchangeLibrary.sol index a99f4e5..2212e03 100644 --- a/contracts/Libraries/ExchangeLibrary.sol +++ b/contracts/Libraries/ExchangeLibrary.sol @@ -62,8 +62,10 @@ library ExchangeLibrary { require(roundingPercent(fillAmount, order.takerTokenAmount, order.makerTokenAmount) <= MAX_ROUNDING_PERCENTAGE); require(self.vault.balanceOf(order.takerToken, taker) >= fillAmount); - uint makeAmount = order.makerTokenAmount.mul(fillAmount).div(order.takerTokenAmount); - uint tradeTakerFee = self.calculateFee(makeAmount, taker); + uint tradeTakerFee = self.calculateFee( + order.makerTokenAmount.mul(fillAmount).div(order.takerTokenAmount), + taker + ); if (tradeTakerFee > 0) { self.vault.transfer(order.makerToken, order.maker, self.feeAccount, tradeTakerFee); @@ -168,16 +170,17 @@ library ExchangeLibrary { return remainder.mul(1000000).div(numerator.mul(target)); } - function calculateFee(Exchange storage self, uint makeAmount, address taker) - internal - view - returns (uint) - { + /// @dev Returns the fee for a specific amount. + /// @param self Exchange storage. + /// @param takeAmount Amount of order to be taken. + /// @param taker Address of the taker. + /// @return Fee amount. + function calculateFee(Exchange storage self, uint takeAmount, address taker) internal view returns (uint) { uint feeAmount = self.feeManager.fees(taker); if (feeAmount == 0) { return 0; } - return makeAmount.mul(feeAmount).div(1 ether); + return takeAmount.mul(feeAmount).div(1 ether); } } From 6c052ada3dcd21689486ef2d9ad24febb05664c2 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 20 May 2018 11:14:38 +0200 Subject: [PATCH 4/7] updated --- contracts/Libraries/ExchangeLibrary.sol | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contracts/Libraries/ExchangeLibrary.sol b/contracts/Libraries/ExchangeLibrary.sol index 2212e03..a5d4201 100644 --- a/contracts/Libraries/ExchangeLibrary.sol +++ b/contracts/Libraries/ExchangeLibrary.sol @@ -62,10 +62,8 @@ library ExchangeLibrary { require(roundingPercent(fillAmount, order.takerTokenAmount, order.makerTokenAmount) <= MAX_ROUNDING_PERCENTAGE); require(self.vault.balanceOf(order.takerToken, taker) >= fillAmount); - uint tradeTakerFee = self.calculateFee( - order.makerTokenAmount.mul(fillAmount).div(order.takerTokenAmount), - taker - ); + uint makeAmount = order.makerTokenAmount.mul(fillAmount).div(order.takerTokenAmount); + uint tradeTakerFee = self.calculateFee(makeAmount, taker); if (tradeTakerFee > 0) { self.vault.transfer(order.makerToken, order.maker, self.feeAccount, tradeTakerFee); From abc5a3786047e80eeb23ee4ccfa34ac9ee0b1bca Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 20 May 2018 11:18:35 +0200 Subject: [PATCH 5/7] removed --- contracts/Exchange.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/Exchange.sol b/contracts/Exchange.sol index 9f1029f..142c996 100644 --- a/contracts/Exchange.sol +++ b/contracts/Exchange.sol @@ -15,9 +15,8 @@ contract Exchange is Ownable, ExchangeInterface { ExchangeLibrary.Exchange public exchange; - function Exchange(uint _takerFee, address _feeAccount, VaultInterface _vault) public { + function Exchange(address _feeAccount, VaultInterface _vault) public { require(address(_vault) != 0x0); - setFees(_takerFee); setFeeAccount(_feeAccount); exchange.vault = _vault; } From 2a256a68480d9ac279016922655f2ca9ea810995 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 20 May 2018 11:23:20 +0200 Subject: [PATCH 6/7] removed --- contracts/Fees/FeeManager.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/Fees/FeeManager.sol b/contracts/Fees/FeeManager.sol index a2cfb49..0edbcf1 100644 --- a/contracts/Fees/FeeManager.sol +++ b/contracts/Fees/FeeManager.sol @@ -3,7 +3,7 @@ pragma solidity ^0.4.18; import "./FeeInterface.sol"; import "./../Ownership/Ownable.sol"; -contract FeeManager is FeeInterface { +contract FeeManager is Ownable, FeeInterface { uint256 constant public MAX_FEE = 5000000000000000; // 0.5% ((0.5 / 100) * 10**18) From 8d40957945f349ec3ae39520a550b410f744b718 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 20 May 2018 11:27:41 +0200 Subject: [PATCH 7/7] removed fee from constructor, need to add fee manager --- test/TestExchange.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/TestExchange.js b/test/TestExchange.js index e2b7f2c..4b20c84 100644 --- a/test/TestExchange.js +++ b/test/TestExchange.js @@ -28,7 +28,7 @@ contract('Exchange', function (accounts) { web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545/")); vault = await Vault.new(erc820Registry.$address); - exchange = await Exchange.new(2500000000000000, feeAccount, vault.address); + exchange = await Exchange.new(feeAccount, vault.address); await vault.addSpender(exchange.address) });