Skip to content

Commit

Permalink
Merge branch 'staging' into greenkeeper/moment-2.22.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Petrovics committed Apr 2, 2018
2 parents b1550ef + 3a31dfa commit 5c45de6
Show file tree
Hide file tree
Showing 20 changed files with 311 additions and 152 deletions.
2 changes: 1 addition & 1 deletion contracts/AugmintReserves.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ NB: reserves are held under the contract address, therefore any transaction on t
*/

pragma solidity 0.4.19;
pragma solidity 0.4.21;
import "./generic/SystemAccount.sol";
import "./interfaces/AugmintTokenInterface.sol";

Expand Down
36 changes: 18 additions & 18 deletions contracts/Exchange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- deduct fee
- consider take funcs (frequent rate changes with takeBuyToken? send more and send back remainder?)
*/
pragma solidity 0.4.19;
pragma solidity 0.4.21;

import "./generic/SafeMath.sol";
import "./interfaces/AugmintTokenInterface.sol";
Expand Down Expand Up @@ -61,7 +61,7 @@ contract Exchange {
buyTokenOrders[orderId] = Order(uint64(activeBuyOrders.length), msg.sender, price, msg.value);
activeBuyOrders.push(orderId);

NewOrder(orderId, msg.sender, price, 0, msg.value);
emit NewOrder(orderId, msg.sender, price, 0, msg.value);
}

/* this function requires previous approval to transfer tokens */
Expand All @@ -70,6 +70,17 @@ contract Exchange {
return _placeSellTokenOrder(msg.sender, price, tokenAmount);
}

/* place sell token order called from AugmintToken's transferAndNotify
Flow:
1) user calls token contract's transferAndNotify price passed in data arg
2) transferAndNotify transfers tokens to the Exchange contract
3) transferAndNotify calls Exchange.transferNotification with lockProductId
*/
function transferNotification(address maker, uint tokenAmount, uint price) external {
require(msg.sender == address(augmintToken));
_placeSellTokenOrder(maker, uint32(price), tokenAmount);
}

function cancelBuyTokenOrder(uint64 buyTokenId) external {
Order storage order = buyTokenOrders[buyTokenId];
require(order.maker == msg.sender);
Expand All @@ -80,7 +91,7 @@ contract Exchange {

msg.sender.transfer(amount);

CancelledOrder(buyTokenId, msg.sender, 0, amount);
emit CancelledOrder(buyTokenId, msg.sender, 0, amount);
}

function cancelSellTokenOrder(uint64 sellTokenId) external {
Expand All @@ -93,7 +104,7 @@ contract Exchange {

augmintToken.transferWithNarrative(msg.sender, amount, "Sell token order cancelled");

CancelledOrder(sellTokenId, msg.sender, amount, 0);
emit CancelledOrder(sellTokenId, msg.sender, amount, 0);
}

/* matches any two orders if the sell price >= buy price
Expand All @@ -111,7 +122,7 @@ contract Exchange {
function matchMultipleOrders(uint64[] buyTokenIds, uint64[] sellTokenIds) external returns(uint matchCount) {
uint len = buyTokenIds.length;
require(len == sellTokenIds.length);
for (uint i = 0; i < len && msg.gas > ORDER_MATCH_WORST_GAS; i++) {
for (uint i = 0; i < len && gasleft() > ORDER_MATCH_WORST_GAS; i++) {
_fillOrder(buyTokenIds[i], sellTokenIds[i]);
matchCount++;
}
Expand Down Expand Up @@ -139,17 +150,6 @@ contract Exchange {
}
}

/* place sell token order called from AugmintToken's transferAndNotify
Flow:
1) user calls token contract's transferAndNotify price passed in data arg
2) transferAndNotify transfers tokens to the Exchange contract
3) transferAndNotify calls Exchange.transferNotification with lockProductId
*/
function transferNotification(address maker, uint tokenAmount, uint price) public {
require(msg.sender == address(augmintToken));
_placeSellTokenOrder(maker, uint32(price), tokenAmount);
}

function _fillOrder(uint64 buyTokenId, uint64 sellTokenId) private {
Order storage buy = buyTokenOrders[buyTokenId];
Order storage sell = sellTokenOrders[sellTokenId];
Expand Down Expand Up @@ -184,7 +184,7 @@ contract Exchange {
augmintToken.transferWithNarrative(buy.maker, tradedTokens, "Buy token order fill");
sell.maker.transfer(tradedWei);

OrderFill(buy.maker, sell.maker, buyTokenId,
emit OrderFill(buy.maker, sell.maker, buyTokenId,
sellTokenId, uint32(price), tradedWei, tradedTokens);
}

Expand All @@ -197,7 +197,7 @@ contract Exchange {
sellTokenOrders[orderId] = Order(uint64(activeSellOrders.length), maker, price, tokenAmount);
activeSellOrders.push(orderId);

NewOrder(orderId, maker, price, tokenAmount, 0);
emit NewOrder(orderId, maker, price, tokenAmount, 0);
}

function _removeBuyOrder(Order storage order) private {
Expand Down
2 changes: 1 addition & 1 deletion contracts/FeeAccount.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Contract to collect fees from system */

pragma solidity 0.4.19;
pragma solidity 0.4.21;
import "./generic/SystemAccount.sol";


Expand Down
2 changes: 1 addition & 1 deletion contracts/InterestEarnedAccount.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* Contract to hold earned interest from loans repaid
premiums for locks are being accrued (i.e. transferred) to Locker */

pragma solidity 0.4.19;
pragma solidity 0.4.21;
import "./generic/SystemAccount.sol";
import "./interfaces/AugmintTokenInterface.sol";

Expand Down
38 changes: 19 additions & 19 deletions contracts/LoanManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- create and use InterestEarnedAccount interface instead?
- make collect() run as long as gas provided allows
*/
pragma solidity 0.4.19;
pragma solidity 0.4.21;

import "./Rates.sol";
import "./generic/Restricted.sol";
Expand Down Expand Up @@ -88,13 +88,13 @@ contract LoanManager is Restricted {
uint32 newProductId = uint32(_newProductId);
require(newProductId == _newProductId);

LoanProductAdded(newProductId);
emit LoanProductAdded(newProductId);
}

function setLoanProductActiveState(uint32 productId, bool newState)
external restrict ("MonetaryBoard") {
products[productId].isActive = false;
LoanProductActiveStateChanged(productId, newState);
emit LoanProductActiveStateChanged(productId, newState);
}

function newEthBackedLoan(uint32 productId) external payable {
Expand Down Expand Up @@ -124,7 +124,19 @@ contract LoanManager is Restricted {
// Issue tokens and send to borrower
monetarySupervisor.issueLoan(msg.sender, loanAmount);

NewLoan(productId, loanId, msg.sender, msg.value, loanAmount, repaymentAmount, maturity);
emit NewLoan(productId, loanId, msg.sender, msg.value, loanAmount, repaymentAmount, maturity);
}

/* repay loan, called from AugmintToken's transferAndNotify
Flow for repaying loan:
1) user calls token contract's transferAndNotify loanId passed in data arg
2) transferAndNotify transfers tokens to the Lender contract
3) transferAndNotify calls Lender.transferNotification with lockProductId
*/
// from arg is not used as we allow anyone to repay a loan:
function transferNotification(address, uint repaymentAmount, uint loanId) external {
require(msg.sender == address(augmintToken));
_repayLoan(loanId, repaymentAmount);
}

function collect(uint[] loanIds) external {
Expand Down Expand Up @@ -166,11 +178,11 @@ contract LoanManager is Restricted {

totalCollateralToCollect = totalCollateralToCollect.add(collateralToCollect);

LoanCollected(loanIds[i], loan.borrower, collateralToCollect, releasedCollateral, defaultingFee);
emit LoanCollected(loanIds[i], loan.borrower, collateralToCollect, releasedCollateral, defaultingFee);
}

if (totalCollateralToCollect > 0) {
monetarySupervisor.augmintReserves().transfer(totalCollateralToCollect);
address(monetarySupervisor.augmintReserves()).transfer(totalCollateralToCollect);
}

monetarySupervisor.loanCollectionNotification(totalLoanAmountCollected);// update KPIs
Expand Down Expand Up @@ -247,18 +259,6 @@ contract LoanManager is Restricted {
loan.productId, uint(loanState), loan.maturity, disbursementTime, loanAmount, interestAmount];
}

/* repay loan, called from AugmintToken's transferAndNotify
Flow for repaying loan:
1) user calls token contract's transferAndNotify loanId passed in data arg
2) transferAndNotify transfers tokens to the Lender contract
3) transferAndNotify calls Lender.transferNotification with lockProductId
*/
// from arg is not used as we allow anyone to repay a loan:
function transferNotification(address, uint repaymentAmount, uint loanId) public {
require(msg.sender == address(augmintToken));
_repayLoan(loanId, repaymentAmount);
}

function calculateLoanValues(LoanProduct storage product, uint repaymentAmount)
internal view returns (uint loanAmount, uint interestAmount) {
// calculate loan values based on repayment amount
Expand Down Expand Up @@ -292,7 +292,7 @@ contract LoanManager is Restricted {

loan.borrower.transfer(loan.collateralAmount); // send back ETH collateral

LoanRepayed(loanId, loan.borrower);
emit LoanRepayed(loanId, loan.borrower);
}

}
46 changes: 23 additions & 23 deletions contracts/Locker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
-> return only active loan products from getLoanProducts?
*/

pragma solidity 0.4.19;
pragma solidity 0.4.21;

import "./generic/Restricted.sol";
import "./generic/SafeMath.sol";
Expand Down Expand Up @@ -82,17 +82,35 @@ contract Locker is Restricted, TokenReceiver {
LockProduct(perTermInterest, durationInSecs, minimumLockAmount, isActive)) - 1;
uint32 newLockProductId = uint32(_newLockProductId);
require(newLockProductId == _newLockProductId);
NewLockProduct(newLockProductId, perTermInterest, durationInSecs, minimumLockAmount, isActive);
emit NewLockProduct(newLockProductId, perTermInterest, durationInSecs, minimumLockAmount, isActive);

}

function setLockProductActiveState(uint32 lockProductId, bool isActive) external restrict("MonetaryBoard") {

lockProducts[lockProductId].isActive = isActive;
LockProductActiveChange(lockProductId, isActive);
emit LockProductActiveChange(lockProductId, isActive);

}

/* lock funds, called from AugmintToken's transferAndNotify
Flow for locking tokens:
1) user calls token contract's transferAndNotify lockProductId passed in data arg
2) transferAndNotify transfers tokens to the Lock contract
3) transferAndNotify calls Lock.transferNotification with lockProductId
*/
function transferNotification(address from, uint256 amountToLock, uint _lockProductId) external {
require(msg.sender == address(augmintToken));
uint32 lockProductId = uint32(_lockProductId);
require(lockProductId == _lockProductId);
/* TODO: make data arg generic bytes
uint productId;
assembly { // solhint-disable-line no-inline-assembly
productId := mload(data)
} */
_createLock(lockProductId, from, amountToLock);
}

function releaseFunds(uint lockId) external {
Lock storage lock = locks[lockId];
LockProduct storage lockProduct = lockProducts[lock.productId];
Expand All @@ -108,7 +126,7 @@ contract Locker is Restricted, TokenReceiver {
augmintToken.transferWithNarrative(lock.owner, lock.amountLocked.add(interestEarned),
"Funds released from lock");

LockReleased(lock.owner, lockId);
emit LockReleased(lock.owner, lockId);
}

function getLockProductCount() external view returns (uint) {
Expand Down Expand Up @@ -180,24 +198,6 @@ contract Locker is Restricted, TokenReceiver {
}
}

/* lock funds, called from AugmintToken's transferAndNotify
Flow for locking tokens:
1) user calls token contract's transferAndNotify lockProductId passed in data arg
2) transferAndNotify transfers tokens to the Lock contract
3) transferAndNotify calls Lock.transferNotification with lockProductId
*/
function transferNotification(address from, uint256 amountToLock, uint _lockProductId) public {
require(msg.sender == address(augmintToken));
uint32 lockProductId = uint32(_lockProductId);
require(lockProductId == _lockProductId);
/* TODO: make data arg generic bytes
uint productId;
assembly { // solhint-disable-line no-inline-assembly
productId := mload(data)
} */
_createLock(lockProductId, from, amountToLock);
}

function calculateInterest(uint32 perTermInterest, uint amountToLock) public pure returns (uint interestEarned) {
interestEarned = amountToLock.mul(perTermInterest).div(1000000);
}
Expand All @@ -218,7 +218,7 @@ contract Locker is Restricted, TokenReceiver {

monetarySupervisor.requestInterest(amountToLock, interestEarned); // update KPIs & transfer interest here

NewLock(lockOwner, lockId, amountToLock, interestEarned, lockedUntil, lockProduct.perTermInterest,
emit NewLock(lockOwner, lockId, amountToLock, interestEarned, lockedUntil, lockProduct.perTermInterest,
lockProduct.durationInSecs, true);
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity 0.4.19;
pragma solidity 0.4.21;


contract Migrations {
Expand Down
40 changes: 37 additions & 3 deletions contracts/MonetarySupervisor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@
- enforces system wide limits
- burns and issues to AugmintReserves
- Send funds from reserve to exchange when intervening (not implemented yet)
- Converts older versions of AugmintTokens in 1:1 to new
TODO:
- enforce LTD limits
- MonetarySupervisorInterface (and use it everywhere)
- interestEarnedAccount setter?
- create and use InterestEarnedAccount interface instead?
*/

pragma solidity 0.4.19;
pragma solidity 0.4.21;
import "./generic/SafeMath.sol";
import "./generic/Restricted.sol";
import "./interfaces/AugmintTokenInterface.sol";
import "./interfaces/TokenReceiver.sol";
import "./InterestEarnedAccount.sol";
import "./AugmintReserves.sol";


contract MonetarySupervisor is Restricted { // solhint-disable-line no-empty-blocks
contract MonetarySupervisor is Restricted, TokenReceiver { // solhint-disable-line no-empty-blocks
using SafeMath for uint256;

AugmintTokenInterface public augmintToken;
Expand All @@ -39,8 +42,14 @@ contract MonetarySupervisor is Restricted { // solhint-disable-line no-empty-blo
uint public allowedLtdDifferenceAmount; /* in token - if totalLoan and totalLock difference is less than that
then allow loan or lock even if ltdDifference limit would go off with it */

/* Previously deployed AugmintTokens which are accepted for conversion (see transferNotification() )
NB: it's not iterable so old version addresses needs to be added for UI manually after each deploy */
mapping(address => bool) public acceptedLegacyAugmintTokens;

event ParamsChanged(uint ltdDifferenceLimit, uint allowedLtdDifferenceAmount);

event AcceptedLegacyAugmintTokenChanged(address augmintTokenAddress, bool newAcceptedState);

function MonetarySupervisor(AugmintTokenInterface _augmintToken, AugmintReserves _augmintReserves,
InterestEarnedAccount _interestEarnedAccount,
uint _ltdDifferenceLimit, uint _allowedLtdDifferenceAmount) public {
Expand Down Expand Up @@ -94,17 +103,42 @@ contract MonetarySupervisor is Restricted { // solhint-disable-line no-empty-blo
totalLoanAmount = totalLoanAmount.sub(totalLoanAmountCollected);
}

function setAcceptedLegacyAugmintToken(address legacyAugmintTokenAddress, bool newAcceptedState)
external restrict("MonetaryBoard") {
acceptedLegacyAugmintTokens[legacyAugmintTokenAddress] = newAcceptedState;
emit AcceptedLegacyAugmintTokenChanged(legacyAugmintTokenAddress, newAcceptedState);
}

function setParams(uint _ltdDifferenceLimit, uint _allowedLtdDifferenceAmount)
external restrict("MonetaryBoard") {
ltdDifferenceLimit = _ltdDifferenceLimit;
allowedLtdDifferenceAmount = _allowedLtdDifferenceAmount;

ParamsChanged(ltdDifferenceLimit, allowedLtdDifferenceAmount);
emit ParamsChanged(ltdDifferenceLimit, allowedLtdDifferenceAmount);
}

// helper function for FrontEnd to reduce calls
function getParams() external view returns(uint[2]) {
return [ltdDifferenceLimit, allowedLtdDifferenceAmount];
}

/* User can request to convert their tokens from older AugmintToken versions in 1:1
transferNotification is called from AugmintToken's transferAndNotify
Flow for converting old tokens:
1) user calls old token contract's transferAndNotify with the amount to convert,
addressing the new MonetarySupervisor Contract
2) transferAndNotify transfers user's old tokens to the current MonetarySupervisor contract's address
3) transferAndNotify calls MonetarySupervisor.transferNotification
4) MonetarySupervisor checks if old AugmintToken is permitted
5) MonetarySupervisor issues new tokens to user's account in current AugmintToken
6) MonetarySupervisor burns old tokens from own balance
*/
function transferNotification(address from, uint amount, uint /* data, not used */ ) external {
AugmintTokenInterface legacyToken = AugmintTokenInterface(msg.sender);
require(acceptedLegacyAugmintTokens[legacyToken]);

legacyToken.burn(amount);
augmintToken.issueTo(from, amount);
}

}

0 comments on commit 5c45de6

Please sign in to comment.