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: 1 addition & 1 deletion contracts/core/extensions/CoreIssuance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ contract CoreIssuance is
/**
* Exchanges components for Set Tokens, accepting any owner
*
* @param _owner Address to issue set to
* @param _owner Address to issue set to
* @param _setAddress Address of set to issue
* @param _quantity Quantity of set to issue
*/
Expand Down
110 changes: 100 additions & 10 deletions contracts/core/extensions/CoreIssuanceOrder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ pragma solidity 0.4.24;


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


/**
Expand All @@ -36,17 +37,106 @@ contract CoreIssuanceOrder is
{
using SafeMath for uint256;

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

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

/* ============ External Functions ============ */

/**
* 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
*/
function fillOrder(
address _maker,
address _setAddress,
uint _quantity
address[4] _addresses,
uint[5] _values,
uint _fillQuantity,
uint8 _v,
bytes32 _r,
bytes32 _s
)
public
isValidSet(_setAddress)
isPositiveQuantity(_quantity)
isNaturalUnitMultiple(_quantity, _setAddress)
external
isValidSet(_addresses[0])
isPositiveQuantity(_fillQuantity)
isNaturalUnitMultiple(_fillQuantity, _addresses[0])
{

OrderLibrary.IssuanceOrder memory order = OrderLibrary.IssuanceOrder({
setAddress: _addresses[0],
quantity: _values[0],
makerAddress: _addresses[1],
makerToken: _addresses[2],
makerTokenAmount: _values[1],
expiration: _values[2],
relayerToken: _addresses[3],
relayerTokenAmount: _values[3],
salt: _values[4],
orderHash: OrderLibrary.generateOrderHash(
_addresses,
_values
)
});

// Verify order is valid
validateOrder(
order,
_fillQuantity
);

// Verify signature is authentic
require(
OrderLibrary.validateSignature(
order.orderHash,
order.makerAddress,
_v,
_r,
_s
),
INVALID_SIGNATURE
);

//Issue Set
issueInternal(_maker, _setAddress, _quantity);
issueInternal(
order.makerAddress,
order.setAddress,
_fillQuantity
);
}

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

/**
* Validate order params are still valid
*
* @param _order IssuanceOrder object containing order params
* @param _fillQuantity Quantity of Set to be filled
*/
function validateOrder(
OrderLibrary.IssuanceOrder _order,
uint _fillQuantity
)
internal
view
{
// Make sure makerTokenAmount and Set Token to issue is greater than 0.
require(
_order.makerTokenAmount > 0 && _order.quantity > 0,
INVALID_TOKEN_AMOUNTS
);
// Make sure the order hasn't expired
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: space when you work on this next

require(
block.timestamp <= _order.expiration,
ORDER_EXPIRED
);
// TO DO: Check to make sure quantity is multiple of natural unit
// TO DO: Check to see if filled
}
}
}
114 changes: 114 additions & 0 deletions contracts/core/lib/OrderLibrary.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
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 OrderLibrary
* @author Set Protocol
*
* The Order Library contains functions for checking validation and hashing of Orders.
*
*/

library OrderLibrary {

/* ============ Structs ============ */

struct IssuanceOrder {
address setAddress; // _addresses[0]
uint256 quantity; // _values[0]
address makerAddress; // _addresses[1]
address makerToken; // _addresses[2]
uint256 makerTokenAmount; // _values[1]
uint256 expiration; // _values[2]
address relayerToken; // _addresses[3]
uint256 relayerTokenAmount; // _values[3]
uint256 salt; // _values[4]
bytes32 orderHash;
}

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

/**
* Create hash of order parameters
*
* @param _addresses [setAddress, makerAddress, makerToken, relayerToken]
* @param _values [quantity, makerTokenAmount, expiration, relayerTokenAmount, salt]
*/
function generateOrderHash(
address[4] _addresses,
uint[5] _values
)
internal
pure
returns(bytes32)
{
// Hash the order parameters
return keccak256(
abi.encodePacked(
_addresses[0], // setAddress
_addresses[1], // makerAddress
_addresses[2], // makerToken
_addresses[3], // relayerToken
_values[0], // quantity
_values[1], // makerTokenAmount
_values[2], // expiration
_values[3], // relayerTokenAmount
_values[4] // salt
)
);
}

/**
* Validate order signature
*
* @param _orderHash Hash of issuance order
* @param _signerAddress Address of Issuance Order signer
* @param _v v element of ECDSA signature
* @param _r r element of ECDSA signature
* @param _s s element of ECDSA signature
*/
function validateSignature(
bytes32 _orderHash,
address _signerAddress,
uint8 _v,
bytes32 _r,
bytes32 _s
)
internal
pure
returns(bool)
{
// Public address returned by ecrecover function
address recAddress;

// Ethereum msg prefix
bytes memory msgPrefix = "\x19Ethereum Signed Message:\n32";

// Find what address signed the order
recAddress = ecrecover(
keccak256(abi.encodePacked(msgPrefix, _orderHash)),
_v,
_r,
_s
);

return recAddress == _signerAddress;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: space

}
42 changes: 42 additions & 0 deletions contracts/test/lib/MockOrderLibrary.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
pragma solidity 0.4.24;
pragma experimental "ABIEncoderV2";

import { OrderLibrary } from "../../core/lib/OrderLibrary.sol";

// Mock contract implementation of OrderLibrary functions
contract MockOrderLibrary {
function testGenerateOrderHash(
address[4] _addresses,
uint[5] _values
)
public
pure
returns(bytes32)
{
return OrderLibrary.generateOrderHash(
_addresses,
_values
);
}

function testValidateSignature(
bytes32 _orderHash,
address _signerAddress,
uint8 _v,
bytes32 _r,
bytes32 _s
)
public
pure
returns(bool)
{
return OrderLibrary.validateSignature(
_orderHash,
_signerAddress,
_v,
_r,
_s
);
}
}

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"dist": "bash scripts/prepare_dist.sh",
"clean": "rm -rf build; rm -rf transpiled; rm -rf types/generated",
"compile": "truffle compile",
"prepare-test": "yarn clean && truffle compile --all && yarn run generate-typings && yarn run transpile",
"prepare-test": "yarn clean && truffle compile --all && yarn run generate-typings && yarn run transpile",
"test": "yarn prepare-test && truffle test `find ./transpiled/test -name '*.spec.js'`",
"transpile": "tsc",
"generate-typings": "abi-gen --abis './build/contracts/*.json' --out './types/generated' --template './types/contract_templates/contract.mustache' --partials './types/contract_templates/partials/*.mustache' && yarn run rename-generated-abi",
Expand Down
Loading