Created
February 16, 2018 15:29
-
-
Save jaumevn/fe67d23efdfd623169e8c051e2830443 to your computer and use it in GitHub Desktop.
hodlers smart contract
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; | |
struct Allocation { | |
uint256 amount; | |
uint256 timestamp; | |
} | |
uint256 public constant FEE_FACTOR = 5; | |
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, uint256 _amount, uint256 _timestamp); | |
// Triggered when a diposit has been claimed | |
event DepositClaimed(address _who, 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 hodl(uint256 _timestamp) 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); | |
DepositCreated(msg.sender, _amount, _timestamp); | |
return true; | |
} | |
/** | |
* The user is charge with a fee 3,5% if claims deposit before the | |
* deposit expiration date | |
*/ | |
function withdraw() 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; | |
// Calculates fee | |
if (now < allocation.timestamp) { | |
_fee = allocation.amount.mul(FEE_FACTOR).div(100); | |
_amountToTransfer = _amountToTransfer.sub(_fee); | |
} | |
// Transfer ETH deposit to user | |
msg.sender.transfer(_amountToTransfer); | |
// Transfer ETH fee to wallet | |
if (_fee > 0) { | |
wallet.transfer(_fee); | |
} | |
DepositClaimed(msg.sender, _amountToTransfer, allocation.timestamp); | |
// Delete the allocation | |
delete allocations[msg.sender]; | |
return true; | |
} | |
function setWallet(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