Created
February 1, 2018 17:28
-
-
Save jaumevn/c7e3a5da10c2e6b3f6cf7458ceb9e867 to your computer and use it in GitHub Desktop.
Hodlers Dapp
This file contains hidden or 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.18; | |
/** | |
* @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 OwnershipTransferred(address indexed previousOwner, address indexed newOwner); | |
/** | |
* @dev The Ownable constructor sets the original `owner` of the contract to the sender | |
* account. | |
*/ | |
function Ownable() { | |
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) onlyOwner public { | |
require(newOwner != address(0)); | |
OwnershipTransferred(owner, newOwner); | |
owner = newOwner; | |
} | |
} | |
/** | |
* @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) { | |
if (a == 0) { | |
return 0; | |
} | |
uint256 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 c; | |
} | |
/** | |
* @dev Substracts 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) { | |
uint256 c = a + b; | |
assert(c >= a); | |
return c; | |
} | |
} | |
contract Custodian is Ownable { | |
using SafeMath for uint256; | |
/** | |
* An Allocation is defined by the amount of ETH to hodl, the hodl | |
* expiration date and the destination ethereum address where the ETH | |
* will be sent. | |
*/ | |
struct Allocation { | |
uint256 amount; | |
uint256 timestamp; | |
address destinationAddress; | |
} | |
uint256 public constant ETH_DECIMALS_FACTOR = 10**uint256(18); | |
uint256 public constant FEE_FACTOR = 35000000000000000; | |
address public wallet; | |
mapping(address => Allocation) allocations; | |
// Triggered when the wallet has been updated | |
event WalletUpdated(address _who, address _oldWallet, address _newWallet); | |
// Triggered when a diposit has been created | |
event DepositCreated(address _who, address _destinationAddress, uint256 _amount, uint256 _timestamp); | |
// Triggered when a diposit has been claimed | |
event DepositClaimed(address _who, address _destinationAddress, uint256 _amount, uint256 _timestamp); | |
// Triggered when a diposit has been updated | |
event DepositUpdated(address _who, uint256 _amount); | |
function Custodian(address _wallet) public { | |
require(_wallet != address(0)); | |
wallet = _wallet; | |
} | |
function createDeposit(uint256 _timestamp, address _destinationAddress) payable external returns (bool) { | |
uint256 _amount = msg.value; | |
// The expiration date must be greater than the current time | |
require(_timestamp > now); | |
// The amount of ETH to deposit must be greater than 0 | |
require(_amount > 0); | |
// A user can only have one active allocation | |
Allocation storage allocation = allocations[msg.sender]; | |
require(allocation.amount == 0); | |
// Create and adds the new allocation to the allocations mapping | |
allocations[msg.sender] = Allocation(_amount, _timestamp, _destinationAddress); | |
DepositCreated(msg.sender, _destinationAddress, _amount, _timestamp); | |
return true; | |
} | |
function addFunds() payable external returns (bool) { | |
uint256 _amount = msg.value; | |
// The amount of ETH to deposit must be greater than 0 | |
require(_amount > 0); | |
// A user must have an active allocation | |
Allocation storage allocation = allocations[msg.sender]; | |
require(allocation.amount > 0); | |
// The deposit balance is updated | |
allocation.amount = allocation.amount.add(_amount); | |
DepositUpdated(msg.sender, _amount); | |
return true; | |
} | |
/** | |
* The user is charge with a fee 3,5% if claims deposit before the | |
* deposit expiration date | |
*/ | |
function claimDeposit() payable external returns (bool) { | |
// A user must have an active allocation | |
Allocation storage allocation = allocations[msg.sender]; | |
require(allocation.amount > 0); | |
uint256 _fee = 0; | |
uint256 _amountToTransfer = allocation.amount; | |
address _destinationAddress = allocation.destinationAddress; | |
// Calculates fee | |
if (now < allocation.timestamp) { | |
_fee = allocation.amount.mul(FEE_FACTOR).div(ETH_DECIMALS_FACTOR); | |
_amountToTransfer = _amountToTransfer.sub(_fee); | |
} | |
// Transfer ETH deposit to user | |
_destinationAddress.transfer(_amountToTransfer); | |
// Transfer ETH fee to wallet | |
if (_fee > 0) { | |
wallet.transfer(_fee); | |
} | |
DepositClaimed(msg.sender, _destinationAddress, _amountToTransfer, allocation.timestamp); | |
// Delete the allocation | |
delete allocations[msg.sender]; | |
return true; | |
} | |
function updateWallet(address _newWallet) external onlyOwner returns (bool) { | |
require(_newWallet != address(0)); | |
address _oldValue = wallet; | |
wallet = _newWallet; | |
WalletUpdated(msg.sender, _oldValue, wallet); | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment