HEX utilities in solidity to get stake values
pragma solidity ^0.5.12; | |
import "./HEX.sol"; | |
contract HexUtilities { | |
struct StakeStore { | |
uint40 stakeId; | |
uint72 stakedHearts; | |
uint72 stakeShares; | |
uint16 lockedDay; | |
uint16 stakedDays; | |
uint16 unlockedDay; | |
bool isAutoStake; | |
} | |
struct DailyDataCache { | |
uint256 dayPayoutTotal; | |
uint256 dayStakeSharesTotal; | |
uint256 dayUnclaimedSatoshisTotal; | |
} | |
HEX private constant hx = HEX(0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39); | |
uint256 private constant HEARTS_UINT_SHIFT = 72; | |
uint256 private constant HEARTS_MASK = (1 << HEARTS_UINT_SHIFT) - 1; | |
uint256 private constant SATS_UINT_SHIFT = 56; | |
uint256 private constant SATS_MASK = (1 << SATS_UINT_SHIFT) - 1; | |
function decodeDailyData(uint256 encDay) | |
private | |
pure | |
returns (DailyDataCache memory) | |
{ | |
uint256 v = encDay; | |
uint256 payout = v & HEARTS_MASK; | |
v = v >> HEARTS_UINT_SHIFT; | |
uint256 shares = v & HEARTS_MASK; | |
v = v >> HEARTS_UINT_SHIFT; | |
uint256 sats = v & SATS_MASK; | |
return DailyDataCache(payout, shares, sats); | |
} | |
function interestForRange(DailyDataCache[] memory dailyData, uint256 myShares) | |
private | |
pure | |
returns (uint256) | |
{ | |
uint256 len = dailyData.length; | |
uint256 total = 0; | |
for(uint256 i = 0; i < len; i++){ | |
total += interestForDay(dailyData[i], myShares); | |
} | |
return total; | |
} | |
function interestForDay(DailyDataCache memory dayObj, uint256 myShares) | |
private | |
pure | |
returns (uint256) | |
{ | |
return myShares * dayObj.dayPayoutTotal / dayObj.dayStakeSharesTotal; | |
} | |
function getDataRange(uint256 b, uint256 e) | |
private | |
view | |
returns (DailyDataCache[] memory) | |
{ | |
uint256[] memory dataRange = hx.dailyDataRange(b, e); | |
uint256 len = dataRange.length; | |
DailyDataCache[] memory data = new DailyDataCache[](len); | |
for(uint256 i = 0; i < len; i++){ | |
data[i] = decodeDailyData(dataRange[i]); | |
} | |
return data; | |
} | |
function getStakeByStakeId(address addr, uint40 sid) | |
private | |
view | |
returns (StakeStore memory) | |
{ | |
uint40 stakeId; | |
uint72 stakedHearts; | |
uint72 stakeShares; | |
uint16 lockedDay; | |
uint16 stakedDays; | |
uint16 unlockedDay; | |
bool isAutoStake; | |
uint256 stakeCount = hx.stakeCount(addr); | |
for(uint256 i = 0; i < stakeCount; i++){ | |
(stakeId, | |
stakedHearts, | |
stakeShares, | |
lockedDay, | |
stakedDays, | |
unlockedDay, | |
isAutoStake) = hx.stakeLists(addr, i); | |
if(stakeId == sid){ | |
return StakeStore(stakeId, | |
stakedHearts, | |
stakeShares, | |
lockedDay, | |
stakedDays, | |
unlockedDay, | |
isAutoStake); | |
} | |
} | |
} | |
function getStakeByIndex(address addr, uint256 idx) | |
private | |
view | |
returns (StakeStore memory) | |
{ | |
uint40 stakeId; | |
uint72 stakedHearts; | |
uint72 stakeShares; | |
uint16 lockedDay; | |
uint16 stakedDays; | |
uint16 unlockedDay; | |
bool isAutoStake; | |
(stakeId, | |
stakedHearts, | |
stakeShares, | |
lockedDay, | |
stakedDays, | |
unlockedDay, | |
isAutoStake) = hx.stakeLists(addr, idx); | |
return StakeStore(stakeId, | |
stakedHearts, | |
stakeShares, | |
lockedDay, | |
stakedDays, | |
unlockedDay, | |
isAutoStake); | |
} | |
function getLastDataDay() | |
private | |
view | |
returns(uint256) | |
{ | |
uint256[13] memory globalInfo = hx.globalInfo(); | |
uint256 lastDay = globalInfo[4]; | |
return lastDay; | |
} | |
function getInterestByStake(StakeStore memory s) | |
private | |
view | |
returns (uint256) | |
{ | |
uint256 b = s.lockedDay; | |
uint256 e = getLastDataDay(); // ostensibly "today" | |
if (b >= e) { | |
//not started - error | |
return 0; | |
} else { | |
DailyDataCache[] memory data = getDataRange(b, e); | |
return interestForRange(data, s.stakeShares); | |
} | |
} | |
function getInterestByStakeId(address addr, uint40 stakeId) | |
public | |
view | |
returns (uint256) | |
{ | |
StakeStore memory s = getStakeByStakeId(addr, stakeId); | |
return getInterestByStake(s); | |
} | |
function getInterestByIndex(address addr, uint256 idx) | |
public | |
view | |
returns (uint256) | |
{ | |
StakeStore memory s = getStakeByIndex(addr, idx); | |
return getInterestByStake(s); | |
} | |
function getTotalValueByIndex(address addr, uint256 stakeIndex) | |
public | |
view | |
returns (uint256) | |
{ | |
StakeStore memory stake = getStakeByIndex(addr, stakeIndex); | |
uint256 interest = getInterestByStake(stake); | |
return stake.stakedHearts + interest; | |
} | |
function getTotalValueByStakeId(address addr, uint40 stakeId) | |
public | |
view | |
returns (uint256) | |
{ | |
StakeStore memory stake = getStakeByStakeId(addr, stakeId); | |
uint256 interest = getInterestByStake(stake); | |
return stake.stakedHearts + interest; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment