Contracts
The mine is three contracts on each chain. Everything the rest of these docs describes is readable from them.
In short
WinzeTokenis the ERC20. Fixed supply, no owner, no mint function.WinzeMineholds the pool, the stakes, the levels and the rate history.- A price source gives the mine a USD price for each listed token.
- Four actions, a set of free views, four owner calls.
- The ABIs are below. The addresses land when the mine is deployed.
The three contracts
WinzeTokenis the WINZE ERC20. Fixed supply, minted once at deploy, no owner and no mint function.WinzeMineholds the pool, the stakes, the levels and the rate history. Every action and every view on this page is on it.- A price source gives the mine a USD price for each listed token. Either
ManualPriceSourceorChainlinkPriceSource, behind the same interface. See prices.
The interface
Actions
| Function | What it does |
|---|---|
| stake(address token, uint256 amount) | Settles, then adds to a position. |
| unstake(address token, uint256 amount) | Settles, then removes from a position. Never blocked by a price or a delisting. |
| claim() returns (uint256) | Settles every position of the caller and transfers the total. |
| poke(address user) | Settles every position of a miner. Anyone can call. |
Views
| Function | What it returns |
|---|---|
| mineSummary() | TVL, level, rate, next threshold, minted, left, exhausted, epoch count. |
| tvlUsd() | Total value staked, USD 1e18. A token with no price counts as zero. |
| tributePerUsdPerDay() | The current rate, per $ per day, 1e18. |
| currentRatePerUsdPerSecond() | The current rate per second, 1e36. |
| thresholdFor(uint32 level) | TVL at which a level starts. Pure. |
| rateForLevel(uint32 level) | Rate per $ per second at a level. Pure. |
| nextLevelThreshold() | Where the next halving is. |
| epochCount() | How many rate epochs exist. |
| allEpochs() | The full rate history, one entry per halving. |
| remaining() | WINZE left in the pool. |
| listedTokens() | Tokens that can be staked right now. |
| allTokens() | Every token the mine has ever tracked, listed or not. |
| tokenInfo(address token) | Listing, source, total staked, decimals, price, price time. |
| isStale(address token) | True past seven days, or when the source will not answer. |
| pendingTribute(address user) | Claimable plus unsettled, capped by the pool. |
| positionOf(address user, address token) | Amount, USD value, tribute per day, claimable. |
| positionsOf(address user) | Every position with a stake or claimable tribute. |
| minerSummary(address user) | Staked value, tribute per day, claimable, token count. |
Owner only
| Function | What it does |
|---|---|
| setWinze(address) | One shot, before the mine opens. Requires the pool to be held. |
| listToken(address token, address src) | Lists a token with its price source. |
| delistToken(address token) | Blocks new stakes of a token. Nothing else. |
| setPriceSource(address token, address src) | Repoints a token at another source. |
Events
The full life of the mine is readable from these. The app reads Halving for the level history, and a miner's own Staked, Unstaked and Claimed for their history, from the deploy block.
| Event | Contract |
|---|---|
| Staked(address user, address token, uint256 amount, uint256 usdValue) | WinzeMine |
| Unstaked(address user, address token, uint256 amount) | WinzeMine |
| Claimed(address user, uint256 amount) | WinzeMine |
| Halving(uint32 newLevel, uint256 newRate, uint256 tvlAtCross) | WinzeMine |
| TokenListed(address token, address priceSource) | WinzeMine |
| TokenDelisted(address token) | WinzeMine |
| PriceSourceSet(address token, address priceSource) | WinzeMine |
| Exhausted(uint256 minted) | WinzeMine |
| WinzeSet(address winze) | WinzeMine |
| PriceSet(address token, uint256 price1e18, uint256 updatedAt) | ManualPriceSource |
| FeedSet(address token, address feed) | ChainlinkPriceSource |
Errors
| Error | Contract | Raised when |
|---|---|---|
| ZeroAmount | WinzeMine | An amount of zero. |
| ZeroAddress | WinzeMine | A required address is the zero address. |
| NotListed | WinzeMine | The token is not listed, or was never tracked. |
| AlreadyListed | WinzeMine | Listing a token that is already listed. |
| InsufficientStake | WinzeMine | Unstaking more than the position holds. |
| NothingToClaim | WinzeMine | Claiming with a total of zero. |
| MineNotReady | WinzeMine | The mine has not been handed its pool. |
| MineExhausted | WinzeMine | Staking after the pool is spent. |
| WinzeAlreadySet | WinzeMine | The pool was already handed over. |
| PoolNotFunded | WinzeMine | The mine does not hold the full allocation. |
| InvalidToken | WinzeMine | Listing WINZE itself. |
| PriceUnavailable | WinzeMine | The token's price source did not answer. |
| LengthMismatch | ManualPriceSource | Tokens and prices are different lengths. |
| FeedNotSet | ChainlinkPriceSource | The token has no feed. |
| InvalidAnswer | ChainlinkPriceSource | The feed answered zero or below. |
| Unauthorized | Solady Ownable | The caller is not the owner or keeper. |
| Reentrancy | Solady | A nested call into the mine. |
The ones a miner can actually meet, with what each one means in practice, are in staking.
ABIs
Each file is the ABI array from the Foundry build.
WinzeMine. Stake, unstake, claim, poke, the views and the events. Download WinzeMine.jsonWinzeToken. The WINZE ERC20. Download WinzeToken.jsonManualPriceSource. Prices pushed by a keeper. Download ManualPriceSource.jsonChainlinkPriceSource. Prices read from Chainlink feeds. Download ChainlinkPriceSource.json
Robinhood Chain
Chain id 4663. The mine is not deployed there yet. The stock token addresses, the owner, the liquidity address and the treasury address are not published, and the deploy script refuses to run while any of them is still a placeholder.
When it is deployed, the addresses, the deploy block and the listed token set are written to the address book the app reads, and the verified source links open the contract tab of the Blockscout explorer.
Robinhood Chain testnet
Chain id 46630. Not deployed yet either. The testnet deploy uses the same scripts with the deployer standing in for the multisig.
Anvil
Chain id 31337. The local development chain, deployed by the seed script on a fresh Anvil, where the addresses are deterministic.
| Contract | Address |
|---|---|
| WinzeMine | 0x5FbDB2315678afecb367f032d93F642f64180aa3 |
| WinzeToken | 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 |
| Price source | 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 |
The seed script also deploys four mock stock tokens, pushes prices for them and stakes enough from two wallets to sit just under the first threshold, so a developer can cross level 1 from the interface.