Created
June 1, 2018 14:31
-
-
Save BenjaminLu/0def5add4bdf015db67a0f20c099f3e9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.24; | |
/** | |
* @title SafeMath | |
* @dev Math operations with safety checks that throw on error | |
*/ | |
library SafeMath { | |
/** | |
* @dev Multiplies two numbers, throws on overflow. | |
*/ | |
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
if (a == 0) { | |
return 0; | |
} | |
c = a * b; | |
assert(c / a == b); | |
return c; | |
} | |
/** | |
* @dev Integer division of two numbers, truncating the quotient. | |
*/ | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
// assert(b > 0); // Solidity automatically throws when dividing by 0 | |
// uint256 c = a / b; | |
// assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
return a / b; | |
} | |
/** | |
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). | |
*/ | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
assert(b <= a); | |
return a - b; | |
} | |
/** | |
* @dev Adds two numbers, throws on overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
c = a + b; | |
assert(c >= a); | |
return c; | |
} | |
} | |
/** | |
* @title Ownable | |
* @dev The Ownable contract has an owner address, and provides basic authorization control | |
* functions, this simplifies the implementation of "user permissions". | |
*/ | |
contract Ownable { | |
address public owner; | |
event OwnershipRenounced(address indexed previousOwner); | |
event OwnershipTransferred( | |
address indexed previousOwner, | |
address indexed newOwner | |
); | |
/** | |
* @dev The Ownable constructor sets the original `owner` of the contract to the sender | |
* account. | |
*/ | |
constructor() public { | |
owner = msg.sender; | |
} | |
/** | |
* @dev Throws if called by any account other than the owner. | |
*/ | |
modifier onlyOwner() { | |
require(msg.sender == owner); | |
_; | |
} | |
/** | |
* @dev Allows the current owner to transfer control of the contract to a newOwner. | |
* @param newOwner The address to transfer ownership to. | |
*/ | |
function transferOwnership(address newOwner) public onlyOwner { | |
require(newOwner != address(0)); | |
emit OwnershipTransferred(owner, newOwner); | |
owner = newOwner; | |
} | |
/** | |
* @dev Allows the current owner to relinquish control of the contract. | |
*/ | |
function renounceOwnership() public onlyOwner { | |
emit OwnershipRenounced(owner); | |
owner = address(0); | |
} | |
} | |
contract AcceleratedContract is Ownable { | |
using SafeMath for uint256; | |
address public tenant; | |
uint256 public totalMonth = 12; | |
bool public start = false; | |
uint256 public rentPerMonth = 12000; | |
uint256 public totalMoney = totalMonth.mul(rentPerMonth); | |
uint256 public currentMonth = 0; | |
uint256 public currentPaid = 0; | |
uint256 public deposit = 0; | |
uint256 public timeoutPerMonth = 30 days; | |
uint256 public lastDay = 0; | |
uint256 public nextDeadline = 0; | |
event StartRent(); | |
event PaidForMonth(); | |
event WithdrawDepositFromTenant(); | |
event WithdrawDepositFromLandlord(); | |
modifier contractNotStart { | |
require(!start); | |
_; | |
} | |
modifier contractStart { | |
require(start); | |
_; | |
} | |
modifier notTimeout { | |
require(now <= nextDeadline); | |
_; | |
} | |
modifier timeout { | |
require(now > nextDeadline); | |
_; | |
} | |
function startRent() | |
contractNotStart | |
public | |
payable | |
{ | |
uint firstPaid = msg.value; | |
// 付二個月押金 + 第一個月房租 | |
require(firstPaid == rentPerMonth.mul(3)); | |
// 紀錄承租人 | |
tenant = msg.sender; | |
// 第一個月付了 | |
currentMonth = 1; | |
// 紀錄第一個月付了 | |
currentPaid = rentPerMonth; | |
// 押金數量兩個月 | |
deposit = rentPerMonth.mul(2); | |
// 下個月租金繳費期限 | |
nextDeadline = now.add(timeoutPerMonth); | |
lastDay = now.add(365 days); | |
start = true; | |
emit StartRent(); | |
} | |
function payRent() | |
contractStart | |
notTimeout | |
public | |
payable | |
{ | |
uint paidForMonthRent = msg.value; | |
// 付一個月房租 | |
require(paidForMonthRent == rentPerMonth); | |
// 更新下次timeout,基於已付款的月份計算 | |
nextDeadline = nextDeadline.add(timeoutPerMonth); | |
// 已繳月份加1 | |
currentMonth = currentMonth.add(1); | |
// 已繳金額更新 | |
currentPaid = currentPaid.add(rentPerMonth); | |
emit PaidForMonth(); | |
// 租金直接給房東 | |
owner.transfer(paidForMonthRent); | |
if (currentMonth == 12) { | |
// 繳滿房租,退押金給租客 | |
uint256 depositShouldReturn = deposit; | |
deposit = 0; | |
tenant.transfer(depositShouldReturn); | |
emit WithdrawDepositFromTenant(); | |
} | |
} | |
function withdrawDeposit() | |
timeout | |
onlyOwner | |
public | |
{ | |
// 房租逾期押金歸房東 | |
owner.transfer(deposit); | |
emit WithdrawDepositFromLandlord(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment