Skip to content

Instantly share code, notes, and snippets.

@vieyang
Last active June 20, 2020 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vieyang/0f9a43aea560413b49a9e08f4d5f34b5 to your computer and use it in GitHub Desktop.
Save vieyang/0f9a43aea560413b49a9e08f4d5f34b5 to your computer and use it in GitHub Desktop.
/*
* References:
* 1. https://uploads-ssl.webflow.com/5ad71ffeb79acc67c8bcdaba/5ad8d1193a40977462982470_scalable-reward-distribution-paper.pdf
* 2. https://eips.ethereum.org/EIPS/eip-1973
*/
pragma solidity 0.4.24;
contract Test {
// using SafeMath for uint256;
uint256 public totalStaking = 0;
mapping (address => uint256) public staking;
mapping (address => uint256) public rewards;
function deposit() payable public {
staking[msg.sender] += msg.value;
totalStaking += msg.value;
}
function distribute() payable public {
uint256 reward = msg.value;
if (totalStaking == 0) {
return;
}
// TODO: distribute reward to user base on pass block number
}
function () payable public {
distribute();
}
function claimReward() public {
address user = msg.sender;
uint256 reward = rewards[user];
if (reward > 0) {
user.transfer(reward); // use Address.sendValue
}
}
function withdraw() public {
address user = msg.sender;
uint256 deposited = staking[user];
staking[user] = 0;
user.transfer(deposited);
}
/*
* Tips:
* 1. add SafeMath and Address
* 2. mul 10e18 for totalReward, div 10e18 for reward
*/
}
@Enigmatic331
Copy link

Unfortunately you won't be able to access past information from a smart contract - It is only capable of accessing its current contract storage slots.

There are some super convoluted mechanisms using merkle proofs at a particular block height, but even with that you need to rely on the user (or some server) to keep the parameters to the proof so it could be validated during the distribution stage.

Easiest way is to emit an event whenever the user does a deposit, and down the road you'd use event information to trigger the distribute() function. E.g. on server side read events from block xxx to block yyy, loop and call distribute() while passing in stake amount, for example.

@Enigmatic331
Copy link

(likewise you can emit an event when the user withdraws, so you can calculate when the deposit starts and when the deposit ends, and disburse according to the staked duration - if qualified, for example).

@vieyang
Copy link
Author

vieyang commented Jun 10, 2020

@Enigmatic331 thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment