Skip to content

Commit

Permalink
Merge pull request #68 from Augmint/staging
Browse files Browse the repository at this point in the history
staging to master
  • Loading branch information
Peter Petrovics committed Apr 3, 2018
2 parents e7b5e97 + 1307487 commit 8b77247
Show file tree
Hide file tree
Showing 36 changed files with 858 additions and 660 deletions.
4 changes: 1 addition & 3 deletions .solcover.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
module.exports = {
compileCommand: "../node_modules/.bin/truffle compile",
testCommand: "../node_modules/.bin/truffle test --network coverage",
// skip interfaces until this resolved: https://github.com/sc-forks/solidity-coverage/issues/162
skipFiles: ["interfaces/ERC20Interface.sol", "interfaces/TokenReceiver.sol"]
testCommand: "../node_modules/.bin/truffle test --network coverage"
};
89 changes: 45 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,53 +35,54 @@ Read more and try it: **[www.augmint.cc](http://www.augmint.cc)**

Sequence diagrams about the planned:

* [Loan flow](docs/loanFlow.png)
* [Lock flow](docs/lockFlow.png)
* [Exchange flow](docs/exchangeFlow.png)
* [Loan flow](docs/loanFlow.png)
* [Lock flow](docs/lockFlow.png)
* [Exchange flow](docs/exchangeFlow.png)
* [Reserve Sales flow](docs/reserveSalesFlow.png) _(not implemented yet)_

[Flow of funds](https://docs.google.com/drawings/d/13BP5sj-GZ41zdBC2WPIdfLpVJbYia_9Tdw5_g4M4Psg/edit?usp=sharing)

## Solidity Contracts

* [Restricted.sol](./contracts/generic/Owned.sol)
Stores which address can access which function call.
* [ERC20.sol](./contracts/generic/ERC20.sol)
Standard [ERC20](https://theethereum.wiki/w/index.php/ERC20_Token_Standard) token interface.
* [SystemAccount.sol](./contracts/generic/ERC20.sol)
Generic contract to maintain balances of Augmint system accounts
* [AugmintReserves](./contracts/AugmintReserves.sol)
* Holds Augmint's ETH and token reserves
* [InterestEarnedAccount](./contracts/InterestEarnedAccount.sol)
* Holds interest from lending (token) - only repaid loans, ie. already "earned"
* Provides interest for Locks
* [FeeAccount.sol](./contracts/FeeAccount.sol)
* holds all fees (ETH & Token)
* calculates fees (not implemented yet, to be split out from AugmintToken & Exchange & LoanManager)
* [AugmintToken.sol](./contracts/generic/AugmintToken.sol)
Base contract for all Augmint tokens.
* ERC20 standard functions
* maintains account token balances
* Generic `transferAndNotify` "convenience" function
* allow MonetarySupervisor to issue tokens on loan disbursement and for reserve
* allows accounts to burn their tokens (used by repay loan and burn from reserves via MonetarySupervisor contract)
* [MonetarySupervisor.sol](./contracts/MonetarySupervisor.sol)
* maintains system wide KPIs (eg totalLockAmount, totalLoanAmount)
* holds system wide parameters/limits
* enforces system wide limits
* issue to & from reserve functions
* [TokenAEur.sol](./contracts/TokenAEur.sol)
* First AugmintToken contract instance, pegged for pegged to EUR (A-EUR aka Augmint Crypto Euro aka A€ )
* Sets standard token parameters (name, symbol, decimals, peggedSymbol etc.)
* [Rates.sol](./contracts/Rates.sol)
A contract to return fiat/ETH exchange rates
* [Exchange.sol](./contracts/Exchange.sol)
A-EUR / ETH exchange contract. Sell or buy A-EUR for ETH on A-EUR/ETH market rates.
* [LoanManager.sol](./contracts/LoanManager.sol)
* Loan products and their parameters
* Maintains all loans: new loans, repayment, collection
* [Locker.sol](./contracts/Lock.sol)
* Lock products and parameters
* Token fund locking and releasing
* [Restricted.sol](./contracts/generic/Owned.sol)
Stores which address can access which function call.
* [ERC20.sol](./contracts/generic/ERC20.sol)
Standard [ERC20](https://theethereum.wiki/w/index.php/ERC20_Token_Standard) token interface.
* [SystemAccount.sol](./contracts/generic/ERC20.sol)
Generic contract to maintain balances of Augmint system accounts
* [AugmintReserves](./contracts/AugmintReserves.sol)
* Holds Augmint's ETH and token reserves
* [InterestEarnedAccount](./contracts/InterestEarnedAccount.sol)
* Holds interest from lending (token) - only repaid loans, ie. already "earned"
* Provides interest for Locks
* [FeeAccount.sol](./contracts/FeeAccount.sol)
* holds all fees (ETH & Token)
* calculates fees (not implemented yet, to be split out from AugmintToken & Exchange & LoanManager)
* [AugmintToken.sol](./contracts/generic/AugmintToken.sol)
Base contract for all Augmint tokens.
* ERC20 standard functions
* maintains account token balances
* Generic `transferAndNotify` "convenience" function
* allow MonetarySupervisor to issue tokens on loan disbursement and for reserve
* allows accounts to burn their tokens (used by repay loan and burn from reserves via MonetarySupervisor contract)
* [MonetarySupervisor.sol](./contracts/MonetarySupervisor.sol)
* maintains system wide KPIs (eg totalLockAmount, totalLoanAmount)
* holds system wide parameters/limits
* enforces system wide limits
* issue to & from reserve functions
* [TokenAEur.sol](./contracts/TokenAEur.sol)
* First AugmintToken contract instance, pegged for pegged to EUR (A-EUR aka Augmint Crypto Euro aka A€ )
* Sets standard token parameters (name, symbol, decimals, peggedSymbol etc.)
* [Rates.sol](./contracts/Rates.sol)
A contract to return fiat/ETH exchange rates
* [Exchange.sol](./contracts/Exchange.sol)
A-EUR / ETH exchange contract. Sell or buy A-EUR for ETH on A-EUR/ETH market rates.
* [LoanManager.sol](./contracts/LoanManager.sol)
* Loan products and their parameters
* Maintains all loans: new loans, repayment, collection
* [Locker.sol](./contracts/Lock.sol)
* Lock products and parameters
* Token fund locking and releasing

## Contribution

Expand All @@ -105,8 +106,8 @@ The project was born at [DECENT Labs](http://www.decent.org)

### Concept, initial version

* [szerintedmi](https://github.com/szerintedmi)
* [Charlie](https://github.com/krosza)
* [szerintedmi](https://github.com/szerintedmi)
* [Charlie](https://github.com/krosza)

Check the whole team on [augmint.cc](http://www.augmint.cc)

Expand Down
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);
}

}

0 comments on commit 8b77247

Please sign in to comment.