Skip to content
This repository has been archived by the owner on Jan 18, 2023. It is now read-only.

Commit

Permalink
Merge pull request #74 from SetProtocol/brian/core_issuance_order
Browse files Browse the repository at this point in the history
Brian/core issuance order
  • Loading branch information
bweick authored Jun 27, 2018
2 parents 8c7ca7a + c4704f1 commit 0620e36
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 84 deletions.
7 changes: 5 additions & 2 deletions contracts/core/Core.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { CoreAccounting } from "./extensions/CoreAccounting.sol";
import { CoreFactory } from "./extensions/CoreFactory.sol";
import { CoreInternal } from "./extensions/CoreInternal.sol";
import { CoreIssuance } from "./extensions/CoreIssuance.sol";
import { CoreIssuanceOrder } from "./extensions/CoreIssuanceOrder.sol";



/**
Expand All @@ -30,8 +32,9 @@ import { CoreIssuance } from "./extensions/CoreIssuance.sol";
* creating Sets, as well as all collateral flows throughout the system.
*/
contract Core is
CoreIssuanceOrder,
CoreAccounting,
CoreIssuance,
CoreInternal,
CoreFactory
CoreFactory,
CoreIssuance
{}
166 changes: 85 additions & 81 deletions contracts/core/extensions/CoreIssuance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@ contract CoreIssuance is
// Use SafeMath library for all uint256 arithmetic
using SafeMath for uint256;

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

string constant INVALID_QUANTITY = "Quantity must be multiple of the natural unit of the set.";
string constant INVALID_SET = "Set token is disabled or does not exist.";
string constant ZERO_QUANTITY = "Quantity must be greater than zero.";

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

event IssuanceComponentDeposited(
Expand All @@ -51,17 +45,6 @@ contract CoreIssuance is
uint _quantity
);

/* ============ Modifiers ============ */

// Validate quantity is multiple of natural unit
modifier isNaturalUnitMultiple(uint _quantity, address _setToken) {
require(
_quantity % ISetToken(_setToken).naturalUnit() == 0,
INVALID_QUANTITY
);
_;
}

/* ============ Public Functions ============ */

/**
Expand All @@ -79,70 +62,8 @@ contract CoreIssuance is
isPositiveQuantity(_quantity)
isNaturalUnitMultiple(_quantity, _setAddress)
{
// Fetch set token components
address[] memory components = ISetToken(_setAddress).getComponents();
// Fetch set token component units
uint[] memory units = ISetToken(_setAddress).getUnits();

// Inspect vault for required component quantity
for (uint16 i = 0; i < components.length; i++) {
address component = components[i];
uint unit = units[i];

// Calculate required component quantity
uint requiredComponentQuantity = calculateTransferValue(
unit,
ISetToken(_setAddress).naturalUnit(),
_quantity
);

// Fetch component quantity in vault
uint vaultBalance = IVault(state.vaultAddress).getOwnerBalance(msg.sender, component);
if (vaultBalance >= requiredComponentQuantity) {
// Decrement vault balance by the required component quantity
IVault(state.vaultAddress).decrementTokenOwner(
msg.sender,
component,
requiredComponentQuantity
);
} else {
// User has less than required amount, decrement the vault by full balance
if (vaultBalance > 0) {
IVault(state.vaultAddress).decrementTokenOwner(
msg.sender,
component,
vaultBalance
);
}

// Calculate remainder to deposit
uint amountToDeposit = requiredComponentQuantity.sub(vaultBalance);

// Transfer the remainder component quantity required to vault
ITransferProxy(state.transferProxyAddress).transferToVault(
msg.sender,
component,
requiredComponentQuantity.sub(vaultBalance)
);

// Log transfer of component from issuer waller
emit IssuanceComponentDeposited(
_setAddress,
component,
amountToDeposit
);
}

// Increment the vault balance of the set token for the component
IVault(state.vaultAddress).incrementTokenOwner(
_setAddress,
component,
requiredComponentQuantity
);
}

// Issue set token
ISetToken(_setAddress).mint(msg.sender, _quantity);
// Run issueInternal
issueInternal(msg.sender, _setAddress, _quantity);
}

/**
Expand Down Expand Up @@ -214,4 +135,87 @@ contract CoreIssuance is
{
return _quantity.div(_naturalUnit).mul(_componentUnits);
}


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

/**
* Issue
*
* @param _owner Address to issue set to
* @param _setAddress Address of set to issue
* @param _quantity Quantity of set to issue
*/
function issueInternal(
address _owner,
address _setAddress,
uint _quantity
)
internal
{
// Fetch set token components
address[] memory components = ISetToken(_setAddress).getComponents();
// Fetch set token component units
uint[] memory units = ISetToken(_setAddress).getUnits();

// Inspect vault for required component quantity
for (uint16 i = 0; i < components.length; i++) {
address component = components[i];
uint unit = units[i];

// Calculate required component quantity
uint requiredComponentQuantity = calculateTransferValue(
unit,
ISetToken(_setAddress).naturalUnit(),
_quantity
);

// Fetch component quantity in vault
uint vaultBalance = IVault(state.vaultAddress).getOwnerBalance(_owner, component);
if (vaultBalance >= requiredComponentQuantity) {
// Decrement vault balance by the required component quantity
IVault(state.vaultAddress).decrementTokenOwner(
_owner,
component,
requiredComponentQuantity
);
} else {
// User has less than required amount, decrement the vault by full balance
if (vaultBalance > 0) {
IVault(state.vaultAddress).decrementTokenOwner(
_owner,
component,
vaultBalance
);
}

// Calculate remainder to deposit
uint amountToDeposit = requiredComponentQuantity.sub(vaultBalance);

// Transfer the remainder component quantity required to vault
ITransferProxy(state.transferProxyAddress).transferToVault(
_owner,
component,
requiredComponentQuantity.sub(vaultBalance)
);

// Log transfer of component from issuer waller
emit IssuanceComponentDeposited(
_setAddress,
component,
amountToDeposit
);
}

// Increment the vault balance of the set token for the component
IVault(state.vaultAddress).incrementTokenOwner(
_setAddress,
component,
requiredComponentQuantity
);
}

// Issue set token
ISetToken(_setAddress).mint(_owner, _quantity);
}
}
52 changes: 52 additions & 0 deletions contracts/core/extensions/CoreIssuanceOrder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
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 { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol";
import { ICoreIssuance } from "../interfaces/ICoreIssuance.sol";
import { CoreModifiers } from "../lib/CoreSharedModifiers.sol";

/**
* @title CoreIssuanceOrder
* @author Set Protocol
*
* The Core Issuance Order extension houses all functions related to the filling and
* canceling issuance orders.
*
*/

contract CoreIssuanceOrder is
CoreModifiers,
ICoreIssuance
{
using SafeMath for uint256;

function fillOrder(
address _maker,
address _setAddress,
uint _quantity
)
public
isValidSet(_setAddress)
isPositiveQuantity(_quantity)
isNaturalUnitMultiple(_quantity, _setAddress)
{
//Issue Set
issueInternal(_maker, _setAddress, _quantity);
}
}
42 changes: 42 additions & 0 deletions contracts/core/interfaces/ICoreIssuance.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
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 ICoreIssuance
* @author Set Protocol
*
* The ICoreIssuance Contract defines all the functions exposed in the CoreIssuance
* extension.
*/

contract ICoreIssuance {

/**
* Issue internally. Can define who to issue to.
*
* @param _owner Address to issue set to
* @param _setAddress Address of set to issue
* @param _quantity Quantity of set to issue
*/
function issueInternal(
address _owner,
address _setAddress,
uint _quantity
)
internal;
}
13 changes: 12 additions & 1 deletion contracts/core/lib/CoreSharedModifiers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

pragma solidity 0.4.24;

import { CoreState } from "../lib/CoreState.sol";
import { CoreState } from "./CoreState.sol";
import { ISetToken } from "../interfaces/ISetToken.sol";

/**
* @title Core Shared Modifiers
Expand All @@ -32,6 +33,7 @@ contract CoreModifiers is

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

string constant INVALID_QUANTITY = "Quantity must be multiple of the natural unit of the set.";
string constant ZERO_QUANTITY = "Quantity must be greater than zero.";
string constant INVALID_SET = "Set token is disabled or does not exist.";
string constant INVALID_FACTORY = "Factory is disabled or does not exist.";
Expand Down Expand Up @@ -64,4 +66,13 @@ contract CoreModifiers is
);
_;
}

// Validate quantity is multiple of natural unit
modifier isNaturalUnitMultiple(uint _quantity, address _setToken) {
require(
_quantity % ISetToken(_setToken).naturalUnit() == 0,
INVALID_QUANTITY
);
_;
}
}
Loading

0 comments on commit 0620e36

Please sign in to comment.