Skip to content

Instantly share code, notes, and snippets.

@yunho0130
Last active July 7, 2018 05:02
Show Gist options
  • Save yunho0130/48917f674f5c8780c31b92237a7b372a to your computer and use it in GitHub Desktop.
Save yunho0130/48917f674f5c8780c31b92237a7b372a to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.18;
// Import OpenZeppelin's SafeMath contract to prevent overflow/underflow security issues
// import "./SafeMath.sol";
// Import the custom token contract you just wrote.
import "./HachToken.sol";
// Set up your contract.
contract HachTokenLoan {
// Attach SafeMath library functions to the uint256 type.
using SafeMath for uint256;
// 2018 MaengDev
// Q. What is different point between inheritence and import
////////////////////////////////////////
// 1. Set structs
// structs: custom type, groups variables
struct Creditor {
address credWallet;
uint256 credAmount;
uint256 credEtherBalence;
}
struct Debtor {
address debtWallet;
uint256 debtAmount;
uint256 debtEtherBalence;
}
struct P2PDeal {
string dealName;
address debtor;
uint256 interestRate;
uint256 etherAmount;
uint256 dealPeriod;
uint256 dueDate;
bool dealStatus;
bool dealClosing;
}
////////////////////////////////////////
// 2. Check creditor
// modifiers: semantic helper functions
modifier onlyCreditor {
require(msg.sender == creditOwner); // conditional requirement check
_; // function gets amended here
}
address public creditOwner;
// constructor: optional function, executed on contract creation
constructor() public {
creditOwner = msg.sender;
}
////////////////////////////////////////
// 3. Set Hashtable
// mappings: kind of like a hash table, with keys and values
mapping (address => Creditor) public Creditors; // `public` automatically creates a getter function
mapping (address => Debtor) public Debtors; // `public` automatically creates a getter function
mapping (address => P2PDeal) public Deals; // `public` automatically creates a getter function
// mapping (address => P2PLoan) public Loans; // `public` automatically creates a getter function
// events: interface for EVM logs (historical record)
event CreateDeal(address dealAddress, string dealName, address debtor, uint256 interestRate, uint256 etherAmount, uint256 dealPeriod, bool dealStatus, bool dealClosing);
event NewLoan(uint256 loanDuedate, address dealAddress, address fromCreditor, address toDebtor, uint256 value);
event NewCreditor(address credtorAddress , address credWallet, uint256 credAmount, uint256 credEtherBalence);
event NewDebtor(address debtorAddress , address debtWallet, uint256 debtAmount, uint256 debtEtherBalence);
////////////////////////////////////////
// 4. Set Deals
function setDeal(string _dealName, address _debtor, uint256 _interestRate, uint256 _etherAmount, uint256 _dealPeriod) public {
// Set conditions with require statements to make sure the rate is a positive number and the addresses are non-zero.
_preValidateDeal(_debtor, _interestRate, _etherAmount, _dealPeriod);
address _address = msg.sender;
// Set deal information
// Q. how to get the transaction/contract _address?
P2PDeal storage deal = Deals[_address];
deal.dealName = _dealName;
deal.debtor = _debtor;
// Please keep in mind you have to use div(100) for checking
deal.interestRate = _interestRate;
// 1Ether = wei^18 = gwei^9
deal.etherAmount = _etherAmount;
// To implement timestamp? block.timestamp & now, seconds UTC
// 1 day = 86400 sec
deal.dealPeriod = _dealPeriod;
deal.dueDate = block.timestamp.add(_dealPeriod.mul(86400));
deal.dealStatus = true;
deal.dealClosing = false;
bool _dealStatus;
bool _dealClosing;
_dealStatus = deal.dealStatus;
_dealClosing = deal.dealClosing;
// emit an Event, which stores the values in EVM logs
emit CreateDeal(_address , _dealName, _debtor, _interestRate, _etherAmount, _dealPeriod, _dealStatus, _dealClosing);
}
////////////////////////////////////////
// Set creditor and debtor
function setCreditor (address _credWallet, uint256 _credAmount, uint256 _credEtherBalence) public {
address _address = msg.sender;
Creditor storage creditor = Creditors[_address];
creditor.credWallet = _credWallet;
creditor.credAmount = _credAmount;
creditor.credEtherBalence = _credEtherBalence;
emit NewCreditor(_address , _credWallet, _credAmount, _credEtherBalence);
}
function setDebtor (address _debtWallet, uint256 _debtAmount, uint256 _debtEtherBalence) public {
address _address = msg.sender;
Debtor storage debtor = Debtors[_address];
debtor.debtWallet = _debtWallet;
debtor.debtAmount = _debtAmount;
debtor.debtEtherBalence = _debtEtherBalence;
emit NewDebtor(_address , _debtWallet, _debtAmount, _debtEtherBalence);
}
////////////////////////////////////////
// 5. Loan
// ! Future Plan: enrollWhitelist
// Define 4 publicly accessible state variables.
// Your custom token being sold.
HachToken public token;
// Wallet address where fees are collected.
address public wallet;
// Rate of how many token units a buyer gets per wei. Note that wei*10^-18 converts to ether.
uint256 public rate;
// Amount of wei raised.
uint256 public weiRaised;
// raise event
event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
// Q. How to input the struct as a parameter
function excutionLoan(address _dealAddress, address _fromCreditor, address _toDebtor, uint256 _value) onlyCreditor public payable {
// Check the dael status
require(Deals[_dealAddress].dealStatus == true);
// ! many 'require' are needed
// Q. How to make these function call as a transaction (All or Nothing)
// Transfer Loan
token.approve(_toDebtor, _value);
token.transferFrom(_fromCreditor, _toDebtor, _value);
// cred & debtAmount change
Creditors[_fromCreditor].credAmount.add(_value);
Debtors[_toDebtor].debtAmount.add(_value);
// Set loanDuedate
uint256 loanDuedate = block.timestamp.add(Deals[_dealAddress].dealPeriod);
// emit an Event, which stores the values in EVM logs
emit NewLoan(loanDuedate, _dealAddress, _fromCreditor, _toDebtor, _value);
// Change deal status
Deals[_dealAddress].dealStatus == false;
}
//
////////////////////////////////////////
// 6. reimburse: pay for debt
function reimburse(address _dealAddress, address _fromDebtor, address _toCreditor, uint256 _reimburseValue) public payable {
// Check the dael status
require(Deals[_dealAddress].dealClosing == false);
// Check msg.sender
require(msg.sender == Deals[_dealAddress].debtor);
// Check the debt size
require(_reimburseValue == Debtors[_fromDebtor].debtAmount.mul(Deals[_dealAddress].interestRate));
// ! Validate balance, debt, etc...
// Reimburse Value
token.approve(_toCreditor, _reimburseValue);
token.transferFrom(_fromDebtor, _toCreditor, _reimburseValue);
// cred & debtAmount change
Creditors[_toCreditor].credAmount.sub(_reimburseValue);
Debtors[_fromDebtor].debtAmount.sub(_reimburseValue);
// Closing deal
Deals[_dealAddress].dealClosing == true;
}
////////////////////////////////////////
// . exchangeToken
function exchangeToken() public payable {
chargeFee();
}
////////////////////////////////////////
// . chargeFee
function chargeFee() public payable {
}
////////////////////////////////////////
// . dealPeriodChecker
function dealPeriodChecker() public {
}
////////////////////////////////////////
// . timeLock and PoS reward
function timeLock() internal{
}
function posReward() public payable {
}
// THIS PORTION IS FOR THE CONTRACT'S EXTERNAL INTERFACE.
// We suggest skipping down to fill out the internal interface before coming back to complete the external interface.
// Create the fallback function that is called whenever anyone sends funds to this contract.
// Fallback functions are functions without a name that serve as a default function.
// Functions dealing with funds have a special modifier.
function () external payable {
// Call buyTokens function with the address defaulting to the address the message originates from.
buyTokens(msg.sender);
}
// Create the function used for token purchase with one parameter for the address performing the token purchase.
function buyTokens(address _beneficiary) public payable {
// Define a uint256 variable that is equal to the number of wei sent with the message.
uint256 weiAmount = msg.value;
// Call function that validates an incoming purchase.
_preValidatePurchase(_beneficiary, weiAmount);
// Calculate token amount to be created and define it as type uint256.
uint256 tokens = _getTokenAmount(weiAmount);
// Update amount of funds raised.
weiRaised = weiRaised.add(weiAmount);
// Call function that processes a purchase.
_processPurchase(_beneficiary, tokens);
// Raise the event associated with a token purchase.
TokenPurchase(msg.sender, _beneficiary, weiAmount, tokens);
// Call function that stores ETH from purchases into a wallet address.
_forwardFunds();
}
////////////////////////////////////////
// THIS PORTION IS FOR THE CONTRACT'S INTERNAL INTERFACE.
// Remember, the following functions are for the contract's internal interface.
// . For Set Deal
function _preValidateDeal(address _debtor, uint256 _interestRate, uint256 _etherAmount, uint256 _dealPeriod) internal {
// require(_dealName != ''); // default value is 0 if it is existance.
require(_interestRate > 0);
require(_etherAmount > 0);
require(_debtor != address(0));
require(_dealPeriod > 0);
}
////////////////////////////////////////
// . CrowdSale
// Create function that validates an incoming purchase with two parameters: beneficiary's address and value of wei.
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal {
// Set conditions to make sure the beneficiary's address and the value of wei involved in purchase are non-zero.
require(_beneficiary != address(0));
require(_weiAmount != 0);
}
// Create function that delivers the purchased tokens with two parameters: beneficiary's address and number of tokens.
function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal {
// Set condition that requires contract to mint your custom token with the mint method inherited from your MintableToken contract.
require(HachToken(token).mint(_beneficiary, _tokenAmount));
}
// Create function that executes the deliver function when a purchase has been processed with two parameters: beneficiary's address and number of tokens.
function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal {
_deliverTokens(_beneficiary, _tokenAmount);
}
// Create function to convert purchase value in wei into tokens with one parameter: value in wei.
// Write the function so that it returns the number of tokens (value in wei multiplied by defined rate).
// Multiplication can be done as a method.
function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) {
return _weiAmount.mul(rate);
}
// Create function to store ETH from purchases into a wallet address.
function _forwardFunds() internal {
wallet.transfer(msg.value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment