From ca775451db44471171945da9f369b40585db3eb4 Mon Sep 17 00:00:00 2001 From: wangdong Date: Sat, 21 Apr 2018 12:23:55 -0400 Subject: [PATCH 1/4] added broker --- contracts/TokenRegistryImpl.sol | 13 ++- contracts/TradeBroker.sol | 162 ++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 contracts/TradeBroker.sol diff --git a/contracts/TokenRegistryImpl.sol b/contracts/TokenRegistryImpl.sol index 81160cd4..81c811df 100644 --- a/contracts/TokenRegistryImpl.sol +++ b/contracts/TokenRegistryImpl.sol @@ -34,7 +34,7 @@ contract TokenRegistryImpl is TokenRegistry, Claimable { mapping (string => address) symbolMap; struct TokenInfo { - uint pos; // 0 mens unregistered; if > 0, pos + 1 is the + uint pos; // 0 mens unregistered; if > 0, pos - 1 is the // token's position in `addresses`. string symbol; // Symbol of the token } @@ -170,6 +170,17 @@ contract TokenRegistryImpl is TokenRegistry, Claimable { } } + // address[] public addresses; + // mapping (address => TokenInfo) addressMap; + // mapping (string => address) symbolMap; + + // struct TokenInfo { + // uint pos; // 0 mens unregistered; if > 0, pos - 1 is the + // // token's position in `addresses`. + // string symbol; // Symbol of the token + // } + + function registerTokenInternal( address addr, string symbol diff --git a/contracts/TradeBroker.sol b/contracts/TradeBroker.sol new file mode 100644 index 00000000..86b88a6f --- /dev/null +++ b/contracts/TradeBroker.sol @@ -0,0 +1,162 @@ +/* + + Copyright 2017 Loopring Project Ltd (Loopring Foundation). + + 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.4.23; +pragma experimental "v0.5.0"; +pragma experimental "ABIEncoderV2"; + + +/// @title ERC20 Token Mint +/// @dev This contract deploys ERC20 token contract and registered the contract +/// so the token can be traded with Loopring Protocol. +/// @author Kongliang Zhong - , +/// @author Daniel Wang - . +contract TradeBroker { + event BrokerRegistered( + address owner, + address broker, + address tracker + ); + + event BrokerUnregistered( + address owner, + address broker + ); + + struct Broker { + uint pos; // 0 mens unregistered; if > 0, pos - 1 is the + // token's position in `addresses`. + address owner; + address addr; + address tracker; + } + + mapping(address => Broker[]) public brokerageMap; + mapping(address => mapping(address => Broker)) public brokerMap; + + function getBroker( + address owner, + address broker + ) + external + view + returns( + bool authenticated, + address tracker + ) + { + Broker storage b = brokerMap[owner][broker]; + authenticated = (b.addr != 0x0); + tracker = b.tracker; + } + + function getBrokers( + uint start, + uint count + ) + public + view + returns (address[] brokers, address[] trackers) + { + Broker[] storage _brokers = brokerageMap[msg.sender]; + uint num = _brokers.length; + + if (start >= num) { + return; + } + + uint end = start + count; + if (end > num) { + end = num; + } + + if (start == num) { + return; + } + + brokers = new address[](end - start); + trackers = new address[](end - start); + for (uint i = start; i < end; i++) { + brokers[i - start] = _brokers[i].addr; + trackers[i - start] = _brokers[i].tracker; + } + } + + function registerBroker( + address broker, + address tracker // 0x0 allowed + ) + external + { + require(0x0 != broker,"bad broker"); + require(0 == brokerMap[msg.sender][broker].pos, "broker exists"); + + Broker[] storage brokers = brokerageMap[msg.sender]; + Broker memory b = Broker( + brokers.length + 1, + msg.sender, + broker, + tracker + ); + + brokers.push(b); + brokerMap[msg.sender][broker] = b; + + emit BrokerRegistered( + msg.sender, + broker, + tracker + ); + } + + function unregisterBroker( + address broker + ) + external + { + require(0x0 != broker, "bad broker"); + require( + brokerMap[msg.sender][broker].addr == broker, + "broker not found" + ); + + Broker storage b = brokerMap[msg.sender][broker]; + delete brokerMap[msg.sender][broker]; + + Broker[] storage brokers = brokerageMap[msg.sender]; + Broker storage lastBroker = brokers[brokers.length - 1]; + + if (lastBroker.addr != broker) { + // Swap with the last token and update the pos + lastBroker.pos = b.pos; + brokers[b.pos - 1] = lastBroker; + brokerMap[lastBroker.owner][lastBroker.addr] = lastBroker; + } + + brokers.length--; + + emit BrokerUnregistered(msg.sender, broker); + } +} + +contract TradeBrokerageTracker { + function getAllowance( + address owner, + address broker + ) + external + returns (uint allowance); +} From 1ad8bcaa29aec86bc375958292693d84d1dc9594 Mon Sep 17 00:00:00 2001 From: wangdong Date: Sat, 21 Apr 2018 12:30:05 -0400 Subject: [PATCH 2/4] refactor --- contracts/BrokerageTracker.sol | 34 ++++++++ contracts/TradeBroker.sol | 105 ++--------------------- contracts/TradeBrokerImpl.sol | 147 +++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 98 deletions(-) create mode 100644 contracts/BrokerageTracker.sol create mode 100644 contracts/TradeBrokerImpl.sol diff --git a/contracts/BrokerageTracker.sol b/contracts/BrokerageTracker.sol new file mode 100644 index 00000000..fd47f7a4 --- /dev/null +++ b/contracts/BrokerageTracker.sol @@ -0,0 +1,34 @@ +/* + + Copyright 2017 Loopring Project Ltd (Loopring Foundation). + + 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.4.23; +pragma experimental "v0.5.0"; +pragma experimental "ABIEncoderV2"; + + +/// @title ERC20 Token Mint +/// @dev This contract deploys ERC20 token contract and registered the contract +/// so the token can be traded with Loopring Protocol. +/// @author Kongliang Zhong - , +/// @author Daniel Wang - . +contract BrokerageTracker { + function getAllowance( + address owner, + address broker + ) + external + returns (uint allowance); +} \ No newline at end of file diff --git a/contracts/TradeBroker.sol b/contracts/TradeBroker.sol index 86b88a6f..fc04d90b 100644 --- a/contracts/TradeBroker.sol +++ b/contracts/TradeBroker.sol @@ -36,17 +36,6 @@ contract TradeBroker { address broker ); - struct Broker { - uint pos; // 0 mens unregistered; if > 0, pos - 1 is the - // token's position in `addresses`. - address owner; - address addr; - address tracker; - } - - mapping(address => Broker[]) public brokerageMap; - mapping(address => mapping(address => Broker)) public brokerMap; - function getBroker( address owner, address broker @@ -56,12 +45,7 @@ contract TradeBroker { returns( bool authenticated, address tracker - ) - { - Broker storage b = brokerMap[owner][broker]; - authenticated = (b.addr != 0x0); - tracker = b.tracker; - } + ); function getBrokers( uint start, @@ -69,94 +53,19 @@ contract TradeBroker { ) public view - returns (address[] brokers, address[] trackers) - { - Broker[] storage _brokers = brokerageMap[msg.sender]; - uint num = _brokers.length; - - if (start >= num) { - return; - } - - uint end = start + count; - if (end > num) { - end = num; - } - - if (start == num) { - return; - } - - brokers = new address[](end - start); - trackers = new address[](end - start); - for (uint i = start; i < end; i++) { - brokers[i - start] = _brokers[i].addr; - trackers[i - start] = _brokers[i].tracker; - } - } + returns ( + address[] brokers, + address[] trackers + ); function registerBroker( address broker, address tracker // 0x0 allowed ) - external - { - require(0x0 != broker,"bad broker"); - require(0 == brokerMap[msg.sender][broker].pos, "broker exists"); - - Broker[] storage brokers = brokerageMap[msg.sender]; - Broker memory b = Broker( - brokers.length + 1, - msg.sender, - broker, - tracker - ); - - brokers.push(b); - brokerMap[msg.sender][broker] = b; - - emit BrokerRegistered( - msg.sender, - broker, - tracker - ); - } + external; function unregisterBroker( address broker ) - external - { - require(0x0 != broker, "bad broker"); - require( - brokerMap[msg.sender][broker].addr == broker, - "broker not found" - ); - - Broker storage b = brokerMap[msg.sender][broker]; - delete brokerMap[msg.sender][broker]; - - Broker[] storage brokers = brokerageMap[msg.sender]; - Broker storage lastBroker = brokers[brokers.length - 1]; - - if (lastBroker.addr != broker) { - // Swap with the last token and update the pos - lastBroker.pos = b.pos; - brokers[b.pos - 1] = lastBroker; - brokerMap[lastBroker.owner][lastBroker.addr] = lastBroker; - } - - brokers.length--; - - emit BrokerUnregistered(msg.sender, broker); - } -} - -contract TradeBrokerageTracker { - function getAllowance( - address owner, - address broker - ) - external - returns (uint allowance); + external; } diff --git a/contracts/TradeBrokerImpl.sol b/contracts/TradeBrokerImpl.sol new file mode 100644 index 00000000..0a1bbe60 --- /dev/null +++ b/contracts/TradeBrokerImpl.sol @@ -0,0 +1,147 @@ +/* + + Copyright 2017 Loopring Project Ltd (Loopring Foundation). + + 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.4.23; +pragma experimental "v0.5.0"; +pragma experimental "ABIEncoderV2"; + +import "./TradeBroker.sol"; + + +/// @title An Implementation of TradeBroker. +/// @author Daniel Wang - . +contract TradeBrokerImpl is TradeBroker { + struct Broker { + uint pos; // 0 mens unregistered; if > 0, pos - 1 is the + // token's position in `addresses`. + address owner; + address addr; + address tracker; + } + + mapping(address => Broker[]) public brokerageMap; + mapping(address => mapping(address => Broker)) public brokerMap; + + function getBroker( + address owner, + address broker + ) + external + view + returns( + bool authenticated, + address tracker + ) + { + Broker storage b = brokerMap[owner][broker]; + authenticated = (b.addr != 0x0); + tracker = b.tracker; + } + + function getBrokers( + uint start, + uint count + ) + public + view + returns ( + address[] brokers, + address[] trackers + ) + { + Broker[] storage _brokers = brokerageMap[msg.sender]; + uint num = _brokers.length; + + if (start >= num) { + return; + } + + uint end = start + count; + if (end > num) { + end = num; + } + + if (start == num) { + return; + } + + brokers = new address[](end - start); + trackers = new address[](end - start); + for (uint i = start; i < end; i++) { + brokers[i - start] = _brokers[i].addr; + trackers[i - start] = _brokers[i].tracker; + } + } + + function registerBroker( + address broker, + address tracker // 0x0 allowed + ) + external + { + require(0x0 != broker,"bad broker"); + require( + 0 == brokerMap[msg.sender][broker].pos, + "broker already exists" + ); + + Broker[] storage brokers = brokerageMap[msg.sender]; + Broker memory b = Broker( + brokers.length + 1, + msg.sender, + broker, + tracker + ); + + brokers.push(b); + brokerMap[msg.sender][broker] = b; + + emit BrokerRegistered( + msg.sender, + broker, + tracker + ); + } + + function unregisterBroker( + address broker + ) + external + { + require(0x0 != broker, "bad broker"); + require( + brokerMap[msg.sender][broker].addr == broker, + "broker not found" + ); + + Broker storage b = brokerMap[msg.sender][broker]; + delete brokerMap[msg.sender][broker]; + + Broker[] storage brokers = brokerageMap[msg.sender]; + Broker storage lastBroker = brokers[brokers.length - 1]; + + if (lastBroker.addr != broker) { + // Swap with the last token and update the pos + lastBroker.pos = b.pos; + brokers[b.pos - 1] = lastBroker; + brokerMap[lastBroker.owner][lastBroker.addr] = lastBroker; + } + + brokers.length--; + + emit BrokerUnregistered(msg.sender, broker); + } +} From b5d7335197ee704ce54b864b3a6cd4aaecf08c55 Mon Sep 17 00:00:00 2001 From: wangdong Date: Sat, 21 Apr 2018 12:57:08 -0400 Subject: [PATCH 3/4] refactored BrokerageTracker --- contracts/BrokerageTracker.sol | 37 ++++++++++++++++++++++++++-------- contracts/TradeBroker.sol | 9 +++++---- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/contracts/BrokerageTracker.sol b/contracts/BrokerageTracker.sol index fd47f7a4..7ee3501f 100644 --- a/contracts/BrokerageTracker.sol +++ b/contracts/BrokerageTracker.sol @@ -19,16 +19,37 @@ pragma experimental "v0.5.0"; pragma experimental "ABIEncoderV2"; -/// @title ERC20 Token Mint -/// @dev This contract deploys ERC20 token contract and registered the contract -/// so the token can be traded with Loopring Protocol. -/// @author Kongliang Zhong - , -/// @author Daniel Wang - . +/// @title BrokerageTracker +/// @dev This tracker MUST set the TokenTransferDelegateImpl as the owner. contract BrokerageTracker { + /// @dev Returns the max amount the broker can buy or sell. function getAllowance( address owner, - address broker + address broker, + address tokenB, + address tokenS ) - external - returns (uint allowance); + public + view + returns ( + uint allowanceB, + uint allowanceS, + uint lrcAllowance + ); + + /// @dev This method will be called from TokenTransferDelegateImpl, so + /// it must check `msg.sender` is the address of TokenTransferDelegateImpl. + /// Check https://github.com/Loopring/token-listing/blob/master/ethereum/deployment.md + /// for the current address of TokenTransferDelegateImpl. + function onSettlement( + address owner, + address broker, + address tokenB, + uint amountB, + address tokenS, + uint amountS, + uint lrcFee, + uint lrcReward + ) + public; } \ No newline at end of file diff --git a/contracts/TradeBroker.sol b/contracts/TradeBroker.sol index fc04d90b..5b7fc65c 100644 --- a/contracts/TradeBroker.sol +++ b/contracts/TradeBroker.sol @@ -19,10 +19,11 @@ pragma experimental "v0.5.0"; pragma experimental "ABIEncoderV2"; -/// @title ERC20 Token Mint -/// @dev This contract deploys ERC20 token contract and registered the contract -/// so the token can be traded with Loopring Protocol. -/// @author Kongliang Zhong - , +/// @title Trade Broker +/// @dev A broker is an account that can submit order on behalf of other +/// accounts. When register a broker, the owner can also specify a +/// pre-deployed BrokageTracker to manage the allowance of for the +/// specific broker. /// @author Daniel Wang - . contract TradeBroker { event BrokerRegistered( From 63387692720a1f75ceb84c95b9f6f3aa82d8cbed Mon Sep 17 00:00:00 2001 From: wangdong Date: Sat, 21 Apr 2018 13:12:03 -0400 Subject: [PATCH 4/4] rename --- contracts/{TradeBroker.sol => BrokerRegistry.sol} | 2 +- .../{TradeBrokerImpl.sol => BrokerRegistryImpl.sol} | 6 +++--- contracts/{BrokerageTracker.sol => BrokerTracker.sol} | 9 ++++----- contracts/LoopringProtocolImpl.sol | 2 ++ 4 files changed, 10 insertions(+), 9 deletions(-) rename contracts/{TradeBroker.sol => BrokerRegistry.sol} (98%) rename contracts/{TradeBrokerImpl.sol => BrokerRegistryImpl.sol} (96%) rename contracts/{BrokerageTracker.sol => BrokerTracker.sol} (83%) diff --git a/contracts/TradeBroker.sol b/contracts/BrokerRegistry.sol similarity index 98% rename from contracts/TradeBroker.sol rename to contracts/BrokerRegistry.sol index 5b7fc65c..3daf3e96 100644 --- a/contracts/TradeBroker.sol +++ b/contracts/BrokerRegistry.sol @@ -25,7 +25,7 @@ pragma experimental "ABIEncoderV2"; /// pre-deployed BrokageTracker to manage the allowance of for the /// specific broker. /// @author Daniel Wang - . -contract TradeBroker { +contract BrokerRegistry { event BrokerRegistered( address owner, address broker, diff --git a/contracts/TradeBrokerImpl.sol b/contracts/BrokerRegistryImpl.sol similarity index 96% rename from contracts/TradeBrokerImpl.sol rename to contracts/BrokerRegistryImpl.sol index 0a1bbe60..e8ac9b0d 100644 --- a/contracts/TradeBrokerImpl.sol +++ b/contracts/BrokerRegistryImpl.sol @@ -18,12 +18,12 @@ pragma solidity 0.4.23; pragma experimental "v0.5.0"; pragma experimental "ABIEncoderV2"; -import "./TradeBroker.sol"; +import "./BrokerRegistry.sol"; -/// @title An Implementation of TradeBroker. +/// @title An Implementation of BrokerRegistry. /// @author Daniel Wang - . -contract TradeBrokerImpl is TradeBroker { +contract BrokerRegistryImpl is BrokerRegistry { struct Broker { uint pos; // 0 mens unregistered; if > 0, pos - 1 is the // token's position in `addresses`. diff --git a/contracts/BrokerageTracker.sol b/contracts/BrokerTracker.sol similarity index 83% rename from contracts/BrokerageTracker.sol rename to contracts/BrokerTracker.sol index 7ee3501f..55c9247c 100644 --- a/contracts/BrokerageTracker.sol +++ b/contracts/BrokerTracker.sol @@ -19,9 +19,8 @@ pragma experimental "v0.5.0"; pragma experimental "ABIEncoderV2"; -/// @title BrokerageTracker -/// @dev This tracker MUST set the TokenTransferDelegateImpl as the owner. -contract BrokerageTracker { +/// @title BrokerTracker +contract BrokerTracker { /// @dev Returns the max amount the broker can buy or sell. function getAllowance( address owner, @@ -38,9 +37,9 @@ contract BrokerageTracker { ); /// @dev This method will be called from TokenTransferDelegateImpl, so - /// it must check `msg.sender` is the address of TokenTransferDelegateImpl. + /// it must check `msg.sender` is the address of LoopringProtocol. /// Check https://github.com/Loopring/token-listing/blob/master/ethereum/deployment.md - /// for the current address of TokenTransferDelegateImpl. + /// for the current address of LoopringProtocol deployment. function onSettlement( address owner, address broker, diff --git a/contracts/LoopringProtocolImpl.sol b/contracts/LoopringProtocolImpl.sol index 9b780535..6830a45d 100644 --- a/contracts/LoopringProtocolImpl.sol +++ b/contracts/LoopringProtocolImpl.sol @@ -21,6 +21,8 @@ pragma experimental "ABIEncoderV2"; import "./lib/AddressUtil.sol"; import "./lib/ERC20.sol"; import "./lib/MathUint.sol"; +import "./BrokerRegistry.sol"; +import "./BrokerTracker.sol"; import "./LoopringProtocol.sol"; import "./TokenRegistry.sol"; import "./TokenTransferDelegate.sol";