Created
February 19, 2018 21:37
-
-
Save anonymous/61b969d0f7af252a54f48f4b50f2c3f5 to your computer and use it in GitHub Desktop.
Created using browser-solidity: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://ethereum.github.io/browser-solidity/#version=soljson-v0.4.20+commit.3155dd80.js&optimize=false&gist=
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.18; | |
//import "ds-math/math.sol"; | |
contract DSMath { | |
/* | |
standard uint256 functions | |
*/ | |
function add(uint256 x, uint256 y) constant internal returns (uint256 z) { | |
assert((z = x + y) >= x); | |
} | |
function sub(uint256 x, uint256 y) constant internal returns (uint256 z) { | |
assert((z = x - y) <= x); | |
} | |
function mul(uint256 x, uint256 y) constant internal returns (uint256 z) { | |
z = x * y; | |
assert(x == 0 || z / x == y); | |
} | |
function div(uint256 x, uint256 y) constant internal returns (uint256 z) { | |
z = x / y; | |
} | |
function min(uint256 x, uint256 y) constant internal returns (uint256 z) { | |
return x <= y ? x : y; | |
} | |
function max(uint256 x, uint256 y) constant internal returns (uint256 z) { | |
return x >= y ? x : y; | |
} | |
/* | |
uint128 functions (h is for half) | |
*/ | |
function hadd(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
assert((z = x + y) >= x); | |
} | |
function hsub(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
assert((z = x - y) <= x); | |
} | |
function hmul(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
z = x * y; | |
assert(x == 0 || z / x == y); | |
} | |
function hdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
z = x / y; | |
} | |
function hmin(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
return x <= y ? x : y; | |
} | |
function hmax(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
return x >= y ? x : y; | |
} | |
/* | |
int256 functions | |
*/ | |
function imin(int256 x, int256 y) constant internal returns (int256 z) { | |
return x <= y ? x : y; | |
} | |
function imax(int256 x, int256 y) constant internal returns (int256 z) { | |
return x >= y ? x : y; | |
} | |
/* | |
WAD math | |
*/ | |
uint128 constant WAD = 10 ** 18; | |
function wadd(uint128 x, uint128 y) constant internal returns (uint128) { | |
return hadd(x, y); | |
} | |
function wsub(uint128 x, uint128 y) constant internal returns (uint128) { | |
return hsub(x, y); | |
} | |
function wmul(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
z = cast((uint256(x) * y + WAD / 2) / WAD); | |
} | |
function wdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
z = cast((uint256(x) * WAD + y / 2) / y); | |
} | |
function wmin(uint128 x, uint128 y) constant internal returns (uint128) { | |
return hmin(x, y); | |
} | |
function wmax(uint128 x, uint128 y) constant internal returns (uint128) { | |
return hmax(x, y); | |
} | |
/* | |
RAY math | |
*/ | |
uint128 constant RAY = 10 ** 27; | |
function radd(uint128 x, uint128 y) constant internal returns (uint128) { | |
return hadd(x, y); | |
} | |
function rsub(uint128 x, uint128 y) constant internal returns (uint128) { | |
return hsub(x, y); | |
} | |
function rmul(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
z = cast((uint256(x) * y + RAY / 2) / RAY); | |
} | |
function rdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { | |
z = cast((uint256(x) * RAY + y / 2) / y); | |
} | |
function rpow(uint128 x, uint64 n) constant internal returns (uint128 z) { | |
// This famous algorithm is called "exponentiation by squaring" | |
// and calculates x^n with x as fixed-point and n as regular unsigned. | |
// | |
// It's O(log n), instead of O(n) for naive repeated multiplication. | |
// | |
// These facts are why it works: | |
// | |
// If n is even, then x^n = (x^2)^(n/2). | |
// If n is odd, then x^n = x * x^(n-1), | |
// and applying the equation for even x gives | |
// x^n = x * (x^2)^((n-1) / 2). | |
// | |
// Also, EVM division is flooring and | |
// floor[(n-1) / 2] = floor[n / 2]. | |
z = n % 2 != 0 ? x : RAY; | |
for (n /= 2; n != 0; n /= 2) { | |
x = rmul(x, x); | |
if (n % 2 != 0) { | |
z = rmul(z, x); | |
} | |
} | |
} | |
function rmin(uint128 x, uint128 y) constant internal returns (uint128) { | |
return hmin(x, y); | |
} | |
function rmax(uint128 x, uint128 y) constant internal returns (uint128) { | |
return hmax(x, y); | |
} | |
function cast(uint256 x) constant internal returns (uint128 z) { | |
assert((z = uint128(x)) == x); | |
} | |
} | |
contract KeyRewardPool is DSMath{ | |
uint public collectedTokens; | |
uint public balance; | |
uint constant public yearlyRewardPercentage = 10; | |
function KeyRewardPool() public{ | |
balance = 2048; | |
} | |
// @notice call this method to extract the tokens | |
function collectToken(uint nowTime, uint rewardStartTime) public returns(bool){ | |
require(nowTime > rewardStartTime); | |
uint total = add(collectedTokens, balance); | |
uint remainingTokens = total; | |
uint yearCount = yearFor(nowTime, rewardStartTime); | |
for(uint i = 0; i < yearCount; i++) { | |
remainingTokens = div(mul(remainingTokens, 100 - yearlyRewardPercentage), 100); | |
} | |
// | |
uint totalRewardThisYear = div(mul(remainingTokens, yearlyRewardPercentage), 100); | |
// the reward will be increasing linearly in one year. | |
uint canExtractThisYear = div(mul(totalRewardThisYear, (nowTime - rewardStartTime) % 365 days), 365 days); | |
uint canExtract = canExtractThisYear + total - remainingTokens; | |
canExtract = sub(canExtract, collectedTokens); | |
if(canExtract > balance) { | |
canExtract = balance; | |
} | |
collectedTokens = add(collectedTokens, canExtract); | |
balance = sub(balance, canExtract); | |
return true; | |
} | |
function yearFor(uint nowTime, uint rewardStartTime) public constant returns(uint) { | |
return nowTime< rewardStartTime | |
? 0 | |
: sub(nowTime, rewardStartTime) / (365 days); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment