Contract Functions

This section will be a little more technical and discuss the different functions exposed by the HEX contract and can be invoked by any caller willing to pay the gas. Some of these functions are marked `external` and some `public`. From the Solidity documentation there is no difference to a caller other than `external` functions are sometimes more gas efficient. I suspect this is used more as a marker by the developer of which functions are intended to be called on a regular basis by an external client.

External Functions

These are the `external` functions that are the primary normal interactions with the contract

Informational

Functions that related to information about the contract

globalInfo

This returns the global state of the contract in the form of an array of values

  • lockedHeartsTotal
  • nextStakeSharesTotal
  • shareRate
  • stakePenaltyPool
  • daysStored
  • stakeSharesTotal
  • latestStakeId
  • unclaimedSatoshisTotal
  • claimedSatoshisTotal
  • claimedBtcAddrCount
  • currentContractDay
  • totalSupply (i.e. circulating supply)
allocatedSupply

Returns the total supply of HEX in circulation plus the aggregate locked HEX. This is importantly different from the ERC-20 function totalSupply because the contract burns locked HEX, meaning it will not be accounted for by totalSupply.

totalSupply

Returns the total minted HEX which is synonymous with the circulating supply of HEX.

dailyDataUpdate

Takes as input a day#, with 0 being interpreted as “current day”. This idempotently calculates and sets the day’s payout data before the given day#. For example, 1 year after launch, I call this function with `343` as input and it will calculate all day stake data for days 1 – 342 or whichever days had not yet been calculated.

dailyDataRange

Takes as input a day# and number of days. This is a data fetching function that returns the list of payout data for the requested range of days. The data is packed into uint256 values (unclaimed satoshi snapshot << 160, share total << 80, payout total).

currentDay

Returns current contract day.

Transform

Functions to participate in Transform Lobbies and related functionality

xfLobbyEnter

Enters supplied ETH into the current day’s Transform Lobby. If a referrer address is provided, it is captured in order to credit that referrer with normal referral bonuses upon leaving the lobby (collecting HEX). Multiple entries may be made in a day and are entered into a queue, resolved first-in-first-out upon “leave”.

xfLobbyExit

Takes a target day and number of entries to resolve. For example, you join day 3 lobby four times. After day 3, you may call this function with 3 for the day and 0-4 for the number of entries to resolve. 0 means “all”. The contract will resolve the supplied number of entries from oldest to newest, accumulating HEX to be minted to the caller and minting referral bonus HEX to referrers as entries are resolved.

In the above example say the first and second entry have different referrers, A and B. If I call leaveXfLobby(3, 2), the contract will calculate my transformed HEX for the first entry, mint the referral bonus to A, calculate my transformed HEX for the second entry, mint the referral bonus to B, then mint the total transformed HEX to me.

xfLobbyflush

Flushes transformed ETH to predefined flush address.

xfLobbyRange

Returns the lobby values for a range of days specified by begin and end day inputs

xfLobbyEntry

Returns the ETH and referrer for a given entry on a given day. The input “entryId” is a bit-packed value of the day + index in the entry queue.

xfLobbyPendingDays

Returns an array of days which have pending entries eligible for collection.

Stake

Functions to stake or directly related to staking

stakeStart

Begins a stake. Takes as inputs the stake amount and stake length. The contract calculates shares based on stake length and adds a stake entry for the user. The identifier for this stake is a just a number equal to the number of stakes in the system plus 1. For example, I have 3 active stakes and other users have a combined 20 active stakes. The global “next stake id” is 24 and start a new stake. To refer to the new stake later, its id is 24. Starting a stake burns the committed HEX and accounts for them in the global “allocated supply”.

stakeEnd

Ends a stake. The logic changes quite a bit if the stake ends early, late, or on time. The details are covered above. The necessary inputs are an id for the stake (this was determined when the stake was created) and the index of the stake among the user’s active stakes. This mints new HEX to fulfill the stake return and adds to the total (i.e. circulating) supply.

stakeGoodAccounting

This function safely ends a mature stake. If the stake is not mature, the function errors. It does *not* pay out to the staker. It can be invoked by anyone on behalf of any staker. It takes as input a staker address and a stake id for that address.

stakeCount

This returns the number of open stakes a user has.

Claim

Functions to claim or directly related to claiming

btcAddressIsClaimable

Takes a BTC address and returns whether it can be claimed, meaning it has not been claimed yet and is valid

btcAddressIsValid

Validates whether claim parameters BTC address, satoshis, and proof constitute a valid claim

merkleProofIsValid

Validates a Merkle proof and Leaf are valid for the Merkle Tree built from the UTXO set

btcAddressWasClaimed

Takes a BTC address and returns whether it has been claimed or not.

claimBtcAddress

This is a big one. This is the claim function that could be called by a naive client but certainly is intended to be invoked by the claim tool. It takes several inputs to validate a bitcoin claim and returns the resulting “free” HEX including the speed bonus, late penalty, and referral bonus (10% if other-referred, 32% if a self-referral). “Free” has a special meaning here, see below.

For folks interested in the technical details, the inputs are:

  • `referrer` is the referring ETH address, if any
  • `v`, `r`, and `s` are known parameters needed for the ECDSA signature validation
  • `addrType`, `pubKeyX`, and `pubKeyY` are parameters to convert a public ECDSA key into its associated BTC address
  • `claimToAddr` is the destination ETH address that shall receive the HEX should the claim be valid
  • `proof` is the data used to prove that a given address is in the snapshot (`verifyProof` function). The details here are technical, but rest assured this is standard and in fact one of the benefits of the data structures used for BTC data
  • `rawSatoshis` the claim amount in Satoshis, the smallest denomination of BTC (think pennies to bitcoin’s dollar)
  • `autoStakeDays` – this is unrelated to the claim verification but rather a new contract Rule, explained below

The contract now automatically stakes 90% of a claim’s value for a minimum of 350 days. The function takes autostake days as an input and validates that it is as least 350 days. Emergency unstaking is disabled before 350 days. For example, a “default” claim with 350 day autostake will be allowed to end that stake at maturity but not before. An aggressive user may claim with supplied autostake days of 700. After 350 served days, they may unstake albeit with all applicable early unstake penalties.

The remaining 10% of claimed HEX is minted to the claimant and may be traded or staked as desired.

Public Functions

These are the `public` functions that the contract exposes to be called but may or may not make sense. This statement will make more sense shortly.

claimMessageMatchesSignature

Synthesizes a claim message from a key then compares the extracted address from the recreated message and the address converted from the public key

pubKeyToEthAddress

Converts a public key to an ETH address

pubKeyToBtcAddress

Converts a public key to a BTC address

Contract Events

The Events have been restructured in the contract to use custom bit-packing so these values are not correct. The values they capture are all documented below with roughly the sizes indicated.

Bit packing means that the author of the contract and wallet uses only uint256 values and has an encoding scheme that fills in the 256 bits in predictable chunks. This is because Solidity only allows uint sizes in increments of 8 bits, but many values in HEX require numbers close to a multiple of 8. This means that some gas efficiency can be gained by using more precise sizing and encoding the values into uint256 values.

XfLobbyEnter

Emitted upon joining a daily lobby

Fields:

uint40 timestamp,

address indexed memberAddr,

uint256 indexed entryId,

uint96 rawAmount,

address indexed referrerAddr

XfLobbyExit

Emitted upon resolving a lobby entry. For xfLobbyExit calls of multiple entries, multiple events are emitted.

Fields:

uint40 timestamp,

address indexed memberAddr,

uint256 indexed entryId,

uint72 xfAmount,

address indexed referrerAddr

DailyDataUpdate

Emitted upon completion of daily data updates. A single event is emitted per batch of daily data computed.

Fields:

uint40 timestamp,

uint16 daysStoredAdded,

uint16 daysStoredTotal,

bool isAutoUpdate,

address indexed updaterAddr

Claim

Emitted upon completion of a BTC claim

Fields:

uint40 timestamp,

address indexed claimToAddr,

bytes20 indexed btcAddr,

uint8 claimFlags,

uint56 rawSatoshis,

uint56 adjSatoshis,

uint72 claimedHearts,

address indexed referrerAddr,

address senderAddr

ClaimAssist

Emitted upon completion of a BTC claim wherein the claimant is not the sender of contract call. This is emitted in addition to the above Claim event.

Fields:

uint40 timestamp,

address claimToAddr,

bytes20 btcAddr,

uint8 claimFlags,

uint56 rawSatoshis,

uint56 adjSatoshis,

uint72 claimedHearts,

address referrerAddr,

address indexed senderAddr

StakeStart

Emitted upon starting a stake.

Fields:

uint40 timestamp,

address indexed stakerAddr,

uint40 indexed stakeId,

uint72 stakedHearts,

uint72 stakeShares,

uint16 stakedDays,

bool isAutoStake

StakeGoodAccounting

Emitted upon call to stakeGoodAccounting, if successful.

Fields:

uint40 timestamp,

address indexed stakerAddr,

uint40 indexed stakeId,

uint72 payout,

uint72 penalty,

address indexed senderAddr

StakeEnd

Emitted upon ending a stake

Fields:

uint40 timestamp,

address indexed stakerAddr,

uint40 indexed stakeId,

uint72 payout,

uint72 penalty,

uint16 servedDays

ShareRateChange

Emitted if the share rate is changed by an stakeEnd with the new share rate.

Fields:

uint40 timestamp,

uint40 shareRate,

uint40 indexed stakeId