Skip to content

Instantly share code, notes, and snippets.

@nourharidy
Created December 1, 2018 21:04
Show Gist options
  • Save nourharidy/afca3cd014a66a4539c37cbf72fa86af to your computer and use it in GitHub Desktop.
Save nourharidy/afca3cd014a66a4539c37cbf72fa86af to your computer and use it in GitHub Desktop.
Multi user HODLing contract. Untested and could be vulnerable.
pragma solidity ^0.5.0;
// DISCLAIMER: THIS CODE IS UNTESTED AND UNGUARANTEED TO WORK SECURELY
/*
Usage:
1. User must use the register() function to set a release date for all of their deposited funds. Optionally, the user can send Ether with the transaction as an initial deposit.
2. User can simply send Ether as many times as he wants to this contract address and it will be automatically deposited to their balance
3. After release date has passed, user can use withdraw() function to take back all of his previously deposited ether
4. In order to reuse the contract, the user must go back to step 1 and set a new release date.
*/
contract HODLer {
mapping (address => User) users;
struct User {
uint releaseDate;
uint balance;
}
// Only registered users can deposit simply be sending ether to the contract address. This can be done multiple times.
function () payable external {
User storage thisUser = users[msg.sender];
require(thisUser.releaseDate > 0); // Require previous registration
thisUser.balance += msg.value; // Add sent Ether to user balance
}
// New users need to register once to set their release date. Optionally, they can send Ether with the registration transaction to initiate their balance
function register(uint secondsSince1971) public payable {
User storage thisUser = users[msg.sender];
require(thisUser.releaseDate == 0); // User must not have already registered
require(secondsSince1971 > now); // Release date must be in the future to prevent mistakes
if(msg.value > 0) {
thisUser.balance += msg.value; // If user sent Ether with transaction, add to their balance
}
thisUser.releaseDate = secondsSince1971; // Update user releaseDate
}
// Each user can withdraw their Ether balance after releaseDate has passed
// Needs to be tested against reentrancy attack
function withdraw() public {
User storage thisUser = users[msg.sender];
require(thisUser.releaseDate > 0 && thisUser.releaseDate < now); // User must be registered and releaseDate must have passed
msg.sender.transfer(thisUser.balance);
thisUser.releaseDate = 0; // Reset user release date after withdrawal
thisUser.balance = 0; // Reset user balance after withdrawal, user must reregister
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment