Skip to content

Instantly share code, notes, and snippets.

@kbahr
Last active January 18, 2024 13:25
Show Gist options
  • Save kbahr/80e61ab761053849f7fdc6226b85a354 to your computer and use it in GitHub Desktop.
Save kbahr/80e61ab761053849f7fdc6226b85a354 to your computer and use it in GitHub Desktop.
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