Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions contracts/core/Core.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
pragma solidity 0.4.24;

import { CoreAccounting } from "./extensions/CoreAccounting.sol";
import { CoreExchangeDispatcher } from "./extensions/CoreExchangeDispatcher.sol";
import { CoreFactory } from "./extensions/CoreFactory.sol";
import { CoreInternal } from "./extensions/CoreInternal.sol";
import { CoreIssuance } from "./extensions/CoreIssuance.sol";
Expand All @@ -32,6 +33,7 @@ import { CoreIssuanceOrder } from "./extensions/CoreIssuanceOrder.sol";
* creating Sets, as well as all collateral flows throughout the system.
*/
contract Core is
CoreExchangeDispatcher,
CoreIssuanceOrder,
CoreAccounting,
CoreInternal,
Expand Down
67 changes: 67 additions & 0 deletions contracts/core/extensions/CoreExchangeDispatcher.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
Copyright 2018 Set Labs Inc.

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.24;

import { Ownable } from "zeppelin-solidity/contracts/ownership/Ownable.sol";
import { CoreState } from "../lib/CoreState.sol";


/**
* @title Core Exchange Dispatcher
* @author Set Protocol
*
* The CoreExchangeDispatcher factilitates updating permissible exchanges
* that are used in filling issuance orders. See CoreState.State.exchanges
*/
contract CoreExchangeDispatcher is
Ownable,
CoreState
{

/* ============ Events ============ */

// Logs registration of new exchange
event ExchangeRegistered(
uint8 _exchangeId,
address _exchange
);

/* ============ Setter Functions ============ */

/**
* Register exchange address into mapping of exchanges
*
* @param _exchangeId Enumeration of exchange
* @param _exchange Exchange address to set
*/
function registerExchange(
uint8 _exchangeId,
address _exchange
)
external
onlyOwner
{
// Add asset proxy and log registration.
state.exchanges[_exchangeId] = _exchange;

// Add asset proxy and log registration.
emit ExchangeRegistered(
_exchangeId,
_exchange
);
}
}
82 changes: 70 additions & 12 deletions contracts/core/extensions/CoreIssuanceOrder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@
*/

pragma solidity 0.4.24;
pragma experimental "ABIEncoderV2";


import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol";
import { CoreModifiers } from "../lib/CoreSharedModifiers.sol";
import { CoreState } from "../lib/CoreState.sol";
import { ExchangeHandler } from "../lib/ExchangeHandler.sol";
import { ICoreIssuance } from "../interfaces/ICoreIssuance.sol";
import { LibBytes } from "../../external/LibBytes.sol";
import { OrderLibrary } from "../lib/OrderLibrary.sol";


Expand All @@ -32,13 +36,17 @@ import { OrderLibrary } from "../lib/OrderLibrary.sol";
*
*/
contract CoreIssuanceOrder is
CoreModifiers,
ICoreIssuance
ICoreIssuance,
CoreState,
CoreModifiers
{
using SafeMath for uint256;

/* ============ Constants ============ */

uint256 constant HEADER_LENGTH = 64;

string constant INVALID_EXCHANGE = "Exchange does not exist.";
string constant INVALID_SIGNATURE = "Invalid order signature.";
string constant INVALID_TOKEN_AMOUNTS = "Quantity and makerTokenAmount should be greater than 0.";
string constant ORDER_EXPIRED = "This order has expired.";
Expand All @@ -48,27 +56,28 @@ contract CoreIssuanceOrder is
/**
* Fill an issuance order
*
* @param _addresses [setAddress, makerAddress, makerToken, relayerToken]
* @param _values [quantity, makerTokenAmount, expiration, relayerTokenAmount, salt]
* @param _fillQuantity Quantity of set to be filled
* @param _v v element of ECDSA signature
* @param _r r element of ECDSA signature
* @param _s s element of ECDSA signature
* @param _addresses [setAddress, makerAddress, makerToken, relayerToken]
* @param _values [quantity, makerTokenAmount, expiration, relayerTokenAmount, salt]
* @param _fillQuantity Quantity of set to be filled
* @param _v v element of ECDSA signature
* @param _r r element of ECDSA signature
* @param _s s element of ECDSA signature
* @param _orderData Bytes array containing the exchange orders to execute
*/
function fillOrder(
address[4] _addresses,
uint[5] _values,
uint _fillQuantity,
uint8 _v,
bytes32 _r,
bytes32 _s
bytes32 _s,
bytes _orderData
)
external
isValidSet(_addresses[0])
isPositiveQuantity(_fillQuantity)
isNaturalUnitMultiple(_fillQuantity, _addresses[0])
{

OrderLibrary.IssuanceOrder memory order = OrderLibrary.IssuanceOrder({
setAddress: _addresses[0],
quantity: _values[0],
Expand Down Expand Up @@ -103,6 +112,9 @@ contract CoreIssuanceOrder is
INVALID_SIGNATURE
);

// Execute exchange orders
executeExchangeOrders(_orderData);

//Issue Set
issueInternal(
order.makerAddress,
Expand All @@ -111,7 +123,53 @@ contract CoreIssuanceOrder is
);
}

/* ============ Internal Functions ============ */
/* ============ Private Functions ============ */

/**
* Execute the exchange orders by parsing the order data and facilitating the transfers
*
* @param _orderData Bytes array containing the exchange orders to execute
*/
function executeExchangeOrders(
bytes _orderData
)
private
{
uint256 scannedBytes;
while (scannedBytes < _orderData.length) {
// Read the next exchange order header
bytes memory headerData = LibBytes.slice(
_orderData,
scannedBytes,
scannedBytes.add(HEADER_LENGTH)
);
ExchangeHandler.OrderHeader memory header = ExchangeHandler.parseOrderHeader(
headerData
);

// Get exchange address from state mapping based on header exchange info
address exchange = state.exchanges[header.exchange];

// Verify exchange address is registered
require(
exchange != address(0),
INVALID_EXCHANGE
);

// Read the order body based on header order length info
uint256 orderLength = header.orderLength.add(HEADER_LENGTH);
bytes memory orderBody = LibBytes.slice(
_orderData,
scannedBytes.add(HEADER_LENGTH),
scannedBytes.add(orderLength)
);

// TODO: Call Exchange

// Update scanned bytes with header and body lengths
scannedBytes = scannedBytes.add(orderLength);
}
}

/**
* Validate order params are still valid
Expand All @@ -123,7 +181,7 @@ contract CoreIssuanceOrder is
OrderLibrary.IssuanceOrder _order,
uint _fillQuantity
)
internal
private
view
{
// Make sure makerTokenAmount and Set Token to issue is greater than 0.
Expand Down
39 changes: 39 additions & 0 deletions contracts/core/interfaces/IExchange.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
Copyright 2018 Set Labs Inc.

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.24;


/**
* @title IExchange
* @author Set Protocol
*
* Interface for executing an order with an exchange
*/
interface IExchange {

/**
* Exchange some amount of takerToken for makerToken.
*
* @param _orderData Arbitrary bytes data for any information to pass to the exchange
* @return uint256 The amount of makerToken received
*/
function exchange(
bytes _orderData
)
external
returns (uint256);
}
11 changes: 11 additions & 0 deletions contracts/core/lib/CoreState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ contract CoreState {
/* ============ Structs ============ */

struct State {
// Mapping of exchange enumeration to address
mapping(uint8 => address) exchanges;

// Address of the TransferProxy contract
address transferProxyAddress;

Expand All @@ -48,6 +51,14 @@ contract CoreState {

/* ============ Public Getters ============ */

function exchanges(uint8 _exchangeId)
public
view
returns(address)
{
return state.exchanges[_exchangeId];
}

function transferProxyAddress()
public
view
Expand Down
63 changes: 63 additions & 0 deletions contracts/core/lib/ExchangeHandler.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
Copyright 2018 Set Labs Inc.

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.24;
pragma experimental "ABIEncoderV2";


/**
* @title ExchangeHandler
* @author Set Protocol
*
* This library contains functions and structs to assist with parsing exchange orders data
*/
library ExchangeHandler {

// ============ Structs ============

struct OrderHeader {
uint8 exchange;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI - Currently, we don't get any storage savings from packing with just a uint8

uint256 orderLength;
}

// ============ Internal Functions ============

/**
* Function to convert bytes into OrderHeader
*
* This will always trail an ExchangeOrderHeader, so we don't need to skip
* the first 32. See Notes in parseExchangeOrdersHeader
*
* @param _headerData Bytes representing the order body information
* @return OrderHeader Struct containing exchange order body data
*/
function parseOrderHeader(
bytes _headerData
)
internal
pure
returns (OrderHeader memory)
{
OrderHeader memory header;

assembly {
mstore(header, mload(add(_headerData, 32))) // exchange
mstore(add(header, 32), mload(add(_headerData, 64))) // orderLength
}

return header;
}
}
Loading