Early access to the blockchain betting platform
Start playing in Early Access now and get 1000  demo currency.
Start Game
Documentation
OraclyV1 OraclyV1Core MetaOraclyV1 Game Round Prediction Price EOutcome StakingOraclyV1 Deposit Epoch MentoringOraclyV1 ORCY DEMO VestingOraclyV1

OraclyV1

This contract implements the erc20 related functionality for the Oracly Protocol’s decentralized prediction game. It allows bettors to participate in prediction rounds, manages the lifecycle of each round, integrates with Chainlink to obtain price data, and determines round outcomes based on price movements. The contract also handles bettor payouts, refunds, and manages reward distributions via external contracts.

Contract for the Oracly Protocol’s decentralized prediction game. Manages prediction rounds, integrates with Chainlink for price data, determines round outcomes, and handles bettor payouts and refunds.

STAKING_CONTRACT

address STAKING_CONTRACT

Address of the staking contract used for distributing staking rewards.

This address should point to a valid smart contract. It is used to manage staking rewards in the Oracly protocol. The contract must implement the expected staking interface to ensure proper reward distribution.

MENTORING_CONTRACT

address MENTORING_CONTRACT

Address of the mentoring contract used for distributing mentor rewards.

This address must be a smart contract. It handles the distribution of mentor rewards, and interacts with the core protocol to facilitate appropriate rewards based on mentoring actions.

DISTRIBUTOR_EOA

address DISTRIBUTOR_EOA

Externally Owned Account (EOA) address used as a backup for reward distribution in case the main contracts encounter issues.

This address must be an EOA (not a contract). It serves as a backup to handle reward distributions manually if either the staking or mentoring contract fails and is bypassed.

constructor

constructor(address distributorEOA_address, address stakingContract_address, address mentoringContract_address, address metaoraclyContract_address) public

Constructor to initialize the reward distributors and related contracts.

Validates the addresses for staking and mentoring contracts to ensure they are contracts and not EOAs. Also validates that the distributorEOA_address is an EOA and not a contract.

Parameters

Name Type Description
distributorEOA_address address Address of the EOA used as a backup for reward distribution.
stakingContract_address address Address of the staking contract for staking rewards.
mentoringContract_address address Address of the mentoring contract for mentor rewards.
metaoraclyContract_address address Address of the MetaOracly contract that handles oracle game data.

resolve

function resolve(bytes32 roundid, uint80 exitPriceid) external

Resolves a prediction round by validating the Exit Price ID and determining the outcome.

This function resolves a prediction round, ensuring that the provided priceid corresponds to a valid Exit Price from the price feed. - The function is protected against re-entrancy attacks via nonReentrant modifier. - It is restricted to off-chain callers EOA using the onlyOffChainCallable modifier. Emits: - RoundResolvedNoContest: If the round concludes with a “No Contest” outcome. - RoundResolved: If the round ends with a valid outcome: Down, Up, or Zero.

Parameters

Name Type Description
roundid bytes32 The ID of the round that needs to be resolved.
exitPriceid uint80 The ID of the Exit Price that is used to determine the final outcome of the round.

resolve4withdraw

function resolve4withdraw(bytes32 roundid, bytes32 predictionid, address erc20, uint80 exitPriceid) external

Resolves a prediction round and processes the withdrawal of the payout.

This function first resolves the specified round and prediction, based on the provided Exit Price. It then facilitates the withdrawal of the payout in the specified ERC20 token. - The function is protected against re-entrancy attacks via nonReentrant modifier. - It is restricted to off-chain callers EOA using the onlyOffChainCallable modifier. Emits: - RoundResolvedNoContest: If the round concludes with a “No Contest” outcome. - RoundResolved: If the round ends with a valid outcome: Down, Up, or Zero. - FATAL_EVENT_INSUFFICIENT_PRIZEPOOL if there are insufficient funds in the prize pool. - PredictionClaimed event emitted when a bettor claims the payout for prediction. - RoundPrizepoolReleased event on a successful prize pool release. - RoundArchived event once the round is archived. - MentorsRewardDistributedViaContract when mentor commission is successfully distributed via contract. - MentorsRewardDistributedViaEOA when mentor commission is distributed via EOA due to a fallback. - StakersRewardDistributedViaContract when staker commission is successfully distributed via contract. - StakersRewardDistributedViaEOA when staker commission is distributed via EOA due to a fallback.

Parameters

Name Type Description
roundid bytes32 The ID of the prediction round to resolve.
predictionid bytes32 The ID of the specific prediction within the round.
erc20 address The address of the ERC20 token contract used for the withdrawal.
exitPriceid uint80 The ID of the price point (exit price) used to resolve the prediction.

withdraw

function withdraw(bytes32 roundid, bytes32 predictionid, address erc20) external

Claims a payout based on the result of a prediction in a specific round, using the specified ERC20 token for withdrawal.

This function allows off-chain callers EOA to withdraw winnings from a prediction in a specific round, denominated in a given ERC20 token. - The function is protected against re-entrancy attacks via nonReentrant modifier. - It is restricted to off-chain callers EOA using the onlyOffChainCallable modifier. Emits: - FATAL_EVENT_INSUFFICIENT_PRIZEPOOL if there are insufficient funds in the prize pool. - MentorsRewardDistributedViaContract when mentor commission is successfully distributed via contract. - MentorsRewardDistributedViaEOA when mentor commission is distributed via EOA due to a fallback. - StakersRewardDistributedViaContract when staker commission is successfully distributed via contract. - StakersRewardDistributedViaEOA when staker commission is distributed via EOA due to a fallback. - PredictionClaimed event emitted when a bettor claims the payout for prediction. - RoundPrizepoolReleased event on a successful prize pool release. - RoundArchived event once the round is archived.

Parameters

Name Type Description
roundid bytes32 The ID of the round in which the prediction was made.
predictionid bytes32 The ID of the specific prediction to claim the payout for.
erc20 address The address of the ERC20 token to be used for the payout withdrawal.

placePrediction

function placePrediction(uint256 amount, uint8 position, bytes32 gameid, bytes32 roundid) external

Places a prediction on the specified game and round.

This function allows off-chain callers EOA to place a prediction on a game round by depositing a certain amount of ERC20 tokens. The bettor predicts an outcome (Down, Up, or Zero) for the given game and round. Requirements: - The amount must be greater than zero. - The position must be one of the valid values (1 for Down, 2 for Up, 3 for Zero). - The function is protected against re-entrancy attacks via nonReentrant modifier. - It is restricted to off-chain callers EOA using the onlyOffChainCallable modifier. Emits: - RoundCreated event upon successful creation of the round. - RoundPrizepoolAdd event to signal that the prize pool has been updated. - PredictionCreated event if a new prediction is created. - IncreasePredictionDeposit event if the bettor’s prediction is updated.

Parameters

Name Type Description
amount uint256 The amount of ERC20 tokens the bettor deposits to place the prediction.
position uint8 The predicted outcome for the game round. Valid values: (1 for Down, 2 for Up, 3 for Zero)
gameid bytes32 The ID of the game where the prediction is being placed.
roundid bytes32 The ID of the specific round within the game.

onlyOffChainCallable

modifier onlyOffChainCallable()

Restricts function execution to external accounts (EOA) only.

This modifier ensures that only EOAs (Externally Owned Accounts) can call functions protected by this modifier, preventing contracts from executing such functions. The check is performed by verifying that the caller has no code associated with it (not a contract) and by comparing tx.origin with _msgSender().

FATAL_EVENT_INSUFFICIENT_PRIZEPOOL

event FATAL_EVENT_INSUFFICIENT_PRIZEPOOL(address bettor, address erc20, uint256 balance, uint256 payout, uint256 commission)

Emitted when the contract’s prize pool is insufficient to cover both a bettor’s payout and the commission. This event signals a critical failure that effectively prevents the specified ERC20 token from being used as the deposit token for further predictions.

This is a fatal event that indicates the current prize pool cannot satisfy the requested payout and commission amounts.

Parameters

Name Type Description
bettor address The address of the bettor attempting to withdraw the funds.
erc20 address The ERC20 token involved in the payout and commission transaction.
balance uint256 The current balance of the ERC20 token held in the contract.
payout uint256 The payout amount requested by the bettor.
commission uint256 The commission amount that is due to the contract.

MentorsRewardDistributedViaContract

event MentorsRewardDistributedViaContract(address distributor, address bettor, address erc20, uint256 amount)

This event is emitted when a mentor’s reward is distributed via a smart contract.

This event captures the distribution of rewards to mentors based on the bettor’s activity. It logs the distributor (the smart contract handling the distribution), the bettor (the bettor whose activity triggered the reward), the ERC20 token used, and the reward amount.

Parameters

Name Type Description
distributor address The address of the contract that is distributing the reward.
bettor address The address of the bettor who generated the mentor’s reward.
erc20 address The address of the ERC20 token contract used for distributing the reward.
amount uint256 The amount of the reward in the ERC20 token.

MentorsRewardDistributedViaEOA

event MentorsRewardDistributedViaEOA(address distributor, address bettor, address erc20, uint256 amount)

Emitted when a mentor’s reward is distributed using an Externally Owned Account (EOA). This happens as a fallback mechanism when direct distribution through smart contracts is not possible.

This event is triggered whenever the mentor’s reward is sent via an EOA, in scenarios where automated reward distribution through the smart contract system fails and is bypassed. The mentor’s reward is distributed using an ERC20 token.

Parameters

Name Type Description
distributor address The address of the EOA responsible for distributing the reward to the mentor.
bettor address The address of the bettor whose activity generated the reward for the mentor.
erc20 address The address of the ERC20 token contract used to transfer the reward.
amount uint256 The amount of ERC20 tokens that are distributed as the reward.

StakersRewardDistributedViaContract

event StakersRewardDistributedViaContract(address distributor, address bettor, address erc20, uint256 amount)

Emitted when a staker’s reward is distributed through a contract.

This event logs the details of a reward distribution to stakers initiated by a contract.

Parameters

Name Type Description
distributor address The address of the contract responsible for distributing the reward.
bettor address The address of the bettor whose actions generated the reward for the stakers.
erc20 address The ERC20 token used for the reward distribution.
amount uint256 The total amount of the ERC20 reward distributed.

StakersRewardDistributedViaEOA

event StakersRewardDistributedViaEOA(address distributor, address bettor, address erc20, uint256 amount)

Emitted when a staker’s reward is distributed via an Externally Owned Account (EOA). This event acts as a fallback mechanism when the reward distribution does not go through the primary method, triggering the involvement of an EOA.

This event provides a backup solution in cases where a direct reward transfer to the staking contract fails and is bypassed, allowing the reward to be manually handled by the EOA.

Parameters

Name Type Description
distributor address The address of the EOA responsible for distributing the reward.
bettor address The address of the bettor whose actions resulted in the reward.
erc20 address The address of the ERC20 token used to pay out the reward.
amount uint256 The amount of tokens (in the ERC20 standard) distributed as the reward.

OraclyV1Core

Core contract for handling prediction games, managing rounds, and calculating payouts.

Provides essential logic for creating and managing prediction rounds, fetching price data, determining outcomes, and distributing prize pools. This contract is abstract and should be inherited by other contracts like OraclyV1, which will handle bettor interactions and protocol logic. Key functionalities: - Creation of new prediction rounds. - Fetching and validation of price data from oracles. - Determination of winners based on price movements. - Calculation and distribution of prize pools among winning participants. Note: This contract integrated with secure price oracles like Chainlink for price feeds.

VIGORISH_PERCENT

uint8 VIGORISH_PERCENT

The percentage taken as commission for stakers and mentors from the prize.

Vigorish is a commission applied to the prize. It is set as a constant 1%.

_predictions

mapping(bytes32 => struct Prediction) _predictions

Mapping to store predictions for each round.

Maps a round ID (bytes32) to a specific Prediction object. This stores the predictions made by bettors for a particular round.

_rounds

mapping(bytes32 => struct Round) _rounds

Mapping to store round information.

Maps a round ID (bytes32) to a specific Round object that holds all the relevant information for the round, such as start time, end time, and other metadata.

FATAL_INSUFFICIENT_PRIZEPOOL_ERROR

mapping(address => bool) __FATAL_INSUFFICIENT_PRIZEPOOL_ERROR__

Tracks ERC20 tokens that have triggered a fatal error due to insufficient funds in the prize pool.

This mapping stores a boolean flag for each ERC20 token address. When the flag is set to true, it indicates that the corresponding token’s prize pool has insufficient funds, causing a fatal error. Mapping: - address: The address of the ERC20 token contract. - bool: A flag where true indicates a fatal insufficient prize pool error for that token.

METAORACLY_CONTRACT

address METAORACLY_CONTRACT

Immutable address of the MetaOracly contract, which serves as a registry of all games within the Oracly protocol.

This immutable variable stores the address of the MetaOracly contract. Once set, it cannot be modified, ensuring the integrity of the contract registry across the protocol. This contract registry allows interaction with all possible games on the protocol.

constructor

constructor(address metaoracly_address) internal

Initializes the OraclyV1Core contract by setting the MetaOracly contract address.

This constructor is essential as the MetaOracly contract acts as the source for retrieving game data, price feeds, and other relevant information critical to the OraclyV1Core functionality.

Parameters

Name Type Description
metaoracly_address address The address of the MetaOracly contract that serves as the data provider for the game.

getPrediction

function getPrediction(bytes32 predictionid) external view returns (struct Prediction prediction)

Fetches a specific Prediction based on the provided prediction ID.

Returns a Prediction struct that contains details about the prediction. Useful for retrieving prediction information like the predicted outcome, amount deposited, and bettor details.

Parameters

Name Type Description
predictionid bytes32 The unique ID of the prediction to retrieve.

Return Values

Name Type Description
prediction struct Prediction A Prediction struct containing details such as the prediction position, bettor, and deposited amount.

getRound

function getRound(bytes32 roundid) external view returns (struct Round round, uint256[4] prizepools, uint256[4] bettors, uint256[4] predictions)

Retrieves details about a specific prediction round.

This function provides detailed information about a given round, including: - Round data (Round memory) - Total prize pools for the round and individual outcomes [Total, Down, Up, Zero] (uint[4]) - Total number of bettors for the round and individual outcomes [Total, Down, Up, Zero] (uint[4]) - Total number of predictions for the round and individual outcomes [Total, Down, Up, Zero] (uint[4]) Requirements: - The roundid must be valid and correspond to an existing round.

Parameters

Name Type Description
roundid bytes32 The unique identifier of the prediction round.

Return Values

Name Type Description
round struct Round Information about the round as a Round struct.
prizepools uint256[4] Array of four uint values: [0]: Total deposited amount in the ERC20 token. [1]: Deposited amount for the Down outcome. [2]: Deposited amount for the Up outcome. [3]: Deposited amount for the Zero outcome.
bettors uint256[4] Array of four uint values: [0]: Total number of participants in the round. [1]: Number of participants who predicted Down. [2]: Number of participants who predicted Up. [3]: Number of participants who predicted Zero.
predictions uint256[4] Array of four uint values: [0]: Total number of predictions made. [1]: Number of predictions for Down. [2]: Number of predictions for Up. [3]: Number of predictions for Zero.

getGameRounds

function getGameRounds(bytes32 gameid, uint256 offset) external view returns (bytes32[] roundids, uint256 size)

Retrieves a paginated list of Round IDs for a specified game. This function is useful for fetching game round IDs in batches.

This function returns an array of round IDs and the total number of rounds associated with the given game. The returned array contains at most 20 round IDs starting from the specified offset to support pagination.

Parameters

Name Type Description
gameid bytes32 The unique identifier for the game.
offset uint256 The starting index from which round IDs will be fetched (for pagination).

Return Values

Name Type Description
roundids bytes32[] An array of up to 20 round IDs starting from the given offset.
size uint256 The total number of rounds in the game, which is helpful for paginating through all rounds.

getRoundPredictions

function getRoundPredictions(bytes32 roundid, uint8 position, uint256 offset) external view returns (struct Prediction[] predictions, uint256 size)

Retrieves a paginated list of predictions for a specific round and position.

Returns up to 20 Prediction structs starting from the specified offset. If position is set to 0, predictions for all positions are retrieved. Also returns the total number of predictions matching the criteria.

Parameters

Name Type Description
roundid bytes32 The unique identifier for the round to retrieve predictions from.
position uint8 The prediction position to filter by (1 for Down, 2 for Up, 3 for Zero). A value of 0 retrieves predictions for all positions.
offset uint256 The starting index for pagination. Use this to fetch predictions in batches.

Return Values

Name Type Description
predictions struct Prediction[] An array of Prediction structs representing the matching predictions.
size uint256 The total number of predictions available for the specified round and position.

getBettorPredictions

function getBettorPredictions(address bettor, uint8 position, uint256 offset) external view returns (struct Prediction[] predictions, uint256 size)

Retrieves a paginated list of a bettor’s predictions for a specific position.

Returns up to 20 Prediction structs starting from the specified offset. If position is set to 0, predictions for all positions are retrieved. Also returns the total number of predictions matching the criteria.

Parameters

Name Type Description
bettor address The address of the bettor whose predictions are being queried.
position uint8 The predicted outcome (1 for Down, 2 for Up, 3 for Zero). A value of 0 retrieves predictions for all positions.
offset uint256 The starting index for pagination of the results.

Return Values

Name Type Description
predictions struct Prediction[] An array of Prediction structs limited to 20 entries.
size uint256 The total number of predictions for the bettor and specified position.

isBettorInRound

function isBettorInRound(address bettor, bytes32 roundid) external view returns (bool inround)

Checks whether a specific bettor has participated in a given round. This function is used to verify if the bettor has placed a prediction in the provided round.

This function checks participation in a specific prediction round using the bettor’s address and the unique round ID.

Parameters

Name Type Description
bettor address The address of the bettor to check for participation.
roundid bytes32 The unique identifier of the round.

Return Values

Name Type Description
inround bool true if the bettor participated in the round, false otherwise.

getBettor

function getBettor(address bettor, address erc20) external view returns (address bettorid, uint256[4] predictions, uint256[4] deposits, uint256[4] payouts)

Retrieves information about a specific bettor’s activity for a given ERC20 token.

This function provides detailed information about the bettor’s predictions, including: - Bettor’s address (bettorid) if found. - Total number of predictions and individual outcomes [Total, Up, Down, Zero] (uint[4]). - Total deposited amounts for predictions and individual outcomes [Total, Up, Down, Zero] (uint[4]). - Total payouts received for predictions and individual outcomes [Total, Up, Down, Zero] (uint[4]). - If bettor have never interacted with the provided erc20 token for predictions deposits and payouts returns zeros. - If bettor have never interacted with the cotract it returns zeros.

Parameters

Name Type Description
bettor address The address of the bettor to query.
erc20 address The address of the ERC20 token used for the bettor’s predictions.

Return Values

Name Type Description
bettorid address The address of the bettor (or zero address if no predictions are found).
predictions uint256[4] Array of four uint values: [0]: Total number of predictions made. [1]: Number of predictions for Up. [2]: Number of predictions for Down. [3]: Number of predictions for Zero.
deposits uint256[4] Array of four uint values: [0]: Total amount deposited using the ERC20 token. [1]: Amount deposited for Up predictions. [2]: Amount deposited for Down predictions. [3]: Amount deposited for Zero predictions.
payouts uint256[4] Array of four uint values: [0]: Total payout amount received for the ERC20 token. [1]: Payout amount received for Up predictions. [2]: Payout amount received for Down predictions. [3]: Payout amount received for Zero predictions.

_updatePrediction

function _updatePrediction(struct Game game, bytes32 roundid, uint8 position, uint256 amount, address bettor) internal

Updates the bettor’s prediction or creates a new one if it doesn’t exist for the current game round.

This function handles both creating new predictions and updating existing ones. It adjusts the bettor’s token deposit for their prediction and ensures that internal mappings remain consistent. It also emits an event when a prediction is created or updated. Requirements: - The bettor’s address must not be zero. - amount must be greater than zero. Emits: - PredictionCreated event if a new prediction is created. - IncreasePredictionDeposit event if the bettor’s prediction is updated.

Parameters

Name Type Description
game struct Game The game structure associated with the prediction.
roundid bytes32 The unique identifier of the round within the game.
position uint8 The predicted outcome for the round (1 for Down, 2 for Up, 3 for Zero).
amount uint256 The amount of tokens being deposited for the prediction.
bettor address The address of the bettor making the prediction.

_updateRound

function _updateRound(struct Game game, bytes32 roundid, uint8 position, uint256 amount) internal

Updates a round’s state by creating a new round if necessary and updating its prize pool.

This function checks if the round already exists; if not, it initializes a new round. Then, based on the provided position and amount, it increments the respective prize pool. The position represents the bettor’s predicted price movement direction (1 for Down, 2 for Up, 3 for Zero) within the round. The prize pool is updated accordingly based on the amount wagered for the specified position. Emits: - RoundCreated event upon successful creation of the round. - RoundPrizepoolAdd event to signal that the prize pool has been updated.

Parameters

Name Type Description
game struct Game The struct representing the game associated with the round.
roundid bytes32 The unique identifier for the round to be updated.
position uint8 The prediction position chosen by the bettor (1 for Down, 2 for Up, 3 for Zero).
amount uint256 The amount of tokens being wagered on the position.

_isResolved

function _isResolved(bytes32 roundid) internal view returns (bool resolved)

Checks whether a specific prediction round has been resolved.

This function checks the status of a round using its unique ID. It is marked as internal, so it can only be accessed within this contract or derived contracts. The status of resolution implies that the round’s outcome have been settled.

Parameters

Name Type Description
roundid bytes32 The unique identifier (ID) of the round to check.

Return Values

Name Type Description
resolved bool Returns true if the round is resolved, meaning outcome have been settled, otherwise returns false.

_resolve

function _resolve(bytes32 roundid, uint80 exitPriceid) internal

Resolves an round by determining the final outcome based on the provided exit price.

This function calculates the outcome of a prediction round using the given exitPriceid, which must be fetched from an external oracle. Possible outcomes: - Down: The outcome is resolved as “Down” if the Exit Price is lower than the Entry Price. This indicates a price decrease during the round. - Up: The outcome is resolved as “Up” if the Exit Price is higher than the Entry Price, indicating a price increase during the round. - Zero: The outcome is resolved as “Zero” if the Exit Price is equal to the Entry Price - No Contest: All participants predicted the same outcome (either all Up, all Down, or all Zero), making it impossible to determine winners. - No Contest: None of the participants correctly predicted the outcome. - No Contest: The round was not resolved within the allowed time limit. This function permanently finalizes the state of the round and should only be called when the round is in settlement phase and unresolved. Requirements: - The round must be unresolved state. - The exitPriceid must be valid and Exit Price from the oracle. Emits: - RoundResolvedNoContest: If the round concludes with a “No Contest” outcome. - RoundResolved: If the round ends with a valid outcome: Down, Up, or Zero.

Parameters

Name Type Description
roundid bytes32 The unique identifier of the round being resolved.
exitPriceid uint80 The ID representing the price used to determine the final outcome of the round.

_computeRoundid

function _computeRoundid(uint16 phaseId, uint64 aggregatorRoundId) internal pure returns (uint80 roundId)

Computes a unique round ID by combining a phase ID with an aggregator round ID. This ensures that the round ID is unique across different phases of the price feed aggregator.

The round ID is computed by shifting the 16-bit phaseId left by 64 bits and then adding the 64-bit aggregatorRoundId. This results in a single 80-bit value representing the unique round ID. The left shift ensures that the phaseId occupies the higher bits and does not overlap with the aggregatorRoundId.

Parameters

Name Type Description
phaseId uint16 The 16-bit ID representing the phase of the price feed aggregator. Each phase consists of multiple rounds.
aggregatorRoundId uint64 The 64-bit round ID provided by the underlying price feed aggregator for a specific phase.

Return Values

Name Type Description
roundId uint80 A unique 80-bit round ID that is a combination of the phase and aggregator round IDs.

_claimPrediction

function _claimPrediction(bytes32 roundid, bytes32 predictionid, address erc20) internal returns (uint256 payout, uint256 commission)

Claims the payout for a bettor’s prediction in a specific round with a given ERC20 token.

This function ensures that all necessary checks are performed before allowing a claim: - Verifies that claimd ERC20 matches round ERC20 address. - Ensures the provided prediction ID related the round ID. - Checks that the prediction is associated with the round. - Confirms the caller is the original bettor who made the prediction. - Ensures the prediction hasn’t already been claimed. - Validates that the round has been resolved. - Confirms that the prediction’s position matches the final resolution of the round or handles a “No Contest” scenario. If all validations pass, the function calculates the payout and the commission, updates the prediction’s status to claimed, and returns both the payout and commission values. Emits: - PredictionClaimed event emitted when a bettor claims the payout for prediction. - RoundPrizepoolReleased event on a successful prize pool release. - RoundArchived event once the round is archived.

Parameters

Name Type Description
roundid bytes32 The unique identifier of the round to which the prediction belongs.
predictionid bytes32 The unique identifier of the prediction for which the payout is claimed.
erc20 address The address of the ERC20 token in which the payout is requested.

Return Values

Name Type Description
payout uint256 The amount awarded to the bettor based on the prediction.
commission uint256 The commission deducted from the payout for stakers and mentors.

RoundResolvedNoContest

event RoundResolvedNoContest(bytes32 roundid, address resolvedBy, uint256 resolvedAt, uint8 resolution)

Emitted when a round is resolved as a “No Contest”, allowing participants to reclaim their funds.

This event is triggered when the outcome of a round cannot be determined due to conditions that prevent a clear resolution.

Parameters

Name Type Description
roundid bytes32 The unique identifier of the round that has been resolved as “No Contest”.
resolvedBy address The address of the EOA that initiated the resolution of the round.
resolvedAt uint256 The Unix timestamp at which the round was resolved.
resolution uint8 The constant value representing the “No Contest” outcome, a predefined value (4 for No Contest).

RoundResolved

event RoundResolved(bytes32 roundid, struct Price exitPrice, address resolvedBy, uint256 resolvedAt, uint8 resolution)

Emitted when a prediction round is resolved and its outcome is determined.

This event logs important information about the resolution of a round, including the round ID, the exit price, the bettor who triggered the resolution, and the final outcome of the round.

Parameters

Name Type Description
roundid bytes32 The unique identifier of the resolved prediction round.
exitPrice struct Price The price used to calculate the result of the round, fetched from Chainlink’s price feed.
resolvedBy address The address of the bettor that triggered the resolution of the round.
resolvedAt uint256 The timestamp (in seconds) when the round was resolved.
resolution uint8 The outcome of the round: (1 for Down, 2 for Up, 3 for Zero)

RoundArchived

event RoundArchived(bytes32 roundid, uint256 archivedAt)

This event logs the archival of the round, marking the end of the round’s lifecycle.

Emitted when a round is archived.

Parameters

Name Type Description
roundid bytes32 The unique identifier of the archived round.
archivedAt uint256 The timestamp when the round was archived.

RoundCreated

event RoundCreated(bytes32 roundid, bytes32 gameid, address openedBy, address erc20, address pricefeed, struct Price entryPrice, uint256 startDate, uint256 lockDate, uint256 endDate, uint256 expirationDate, uint256 openedAt)

Emitted when a new prediction round is created.

This event indicates the creation of a new prediction round within the ongoing game. It includes essential details such as the round ID, associated game, the ERC20 token for predictions, the price feed contract for asset price, and the timestamps defining round phases.

Parameters

Name Type Description
roundid bytes32 The unique identifier of the created round.
gameid bytes32 The unique identifier of the game to which the round is linked.
openedBy address The address of the entity EOA that initiated the round creation.
erc20 address The address of the ERC20 token contract used for placing predictions in the round.
pricefeed address The address of the price feed contract used to retrieve the asset price for predictions.
entryPrice struct Price The initial price of the asset at the start of the round, retrieved from the price feed.
startDate uint256 The timestamp (in seconds since Unix epoch) when the round starts.
lockDate uint256 The timestamp when the prediction phase ends and no more entries can be placed.
endDate uint256 The timestamp when the round ends and the outcome of the price movement can be determined.
expirationDate uint256 The deadline timestamp by which the round must be settled, or else it defaults to ‘No Contest’.
openedAt uint256 The timestamp when the round was created (when first prediction entered the round).

RoundPrizepoolAdd

event RoundPrizepoolAdd(bytes32 roundid, address erc20, uint8 position, uint256 amount)

Emitted when funds are added to a specific position’s prize pool for a given round. This event tracks the addition of tokens to a prize pool, which is associated with a particular round and a specific position (Down, Up, Zero).

The position can have three possible values: (1 for Down, 2 for Up, 3 for Zero)

Parameters

Name Type Description
roundid bytes32 The ID of the round to which the prize pool is associated.
erc20 address The address of the ERC20 token that is being added to the prize pool.
position uint8 The position (Down, Up, or Zero) in the prize pool where the tokens are added.
amount uint256 The amount of tokens being added to the prize pool for the given position.

RoundPrizepoolReleased

event RoundPrizepoolReleased(bytes32 roundid, uint256 payout, uint256 commission)

Emitted when funds are released to a bettor for a given round. This event tracks the release of tokens from the prize pool for a particular round, including the bettor’s payout and any commission.

The payout includes the bettor’s share of the prize pool, which is calculated proportional to their contribution. The commission is a amount deducted from the prize, which is allocated to stakers and mentors. The event helps to audit the flow of funds for transparency and tracking of prize distribution.

Parameters

Name Type Description
roundid bytes32 The ID of the round from which the funds are being released.
payout uint256 The total payout being released to the bettor, after deducting the commission.
commission uint256 The commission amount deducted from the prize, allocated to stakers and mentors.

PredictionCreated

event PredictionCreated(bytes32 predictionid, bytes32 roundid, address bettor, uint8 position, uint256 createdAt, address erc20, bytes32 gameid)

Emitted when a new prediction is created in the game.

This event is triggered whenever a bettor makes a new prediction. It logs the details such as the round, bettor’s address, and the prediction outcome.

Parameters

Name Type Description
predictionid bytes32 The unique identifier of the created prediction.
roundid bytes32 The ID of the round the prediction belongs to.
bettor address The address of the bettor who created the prediction.
position uint8 The predicted outcome. (1 for Down, 2 for Up, 3 for Zero)
createdAt uint256 The timestamp (in seconds since the Unix epoch) when the prediction was created.
erc20 address The address of the ERC20 token used as deposit for the prediction.
gameid bytes32 The ID of the game instance that the prediction is associated with.

IncreasePredictionDeposit

event IncreasePredictionDeposit(bytes32 predictionid, uint256 deposit)

Emitted when a bettor deposits tokens within the round.

This event is emitted every time a bettor deposits tokens, either by creating a new prediction or increasing an existing one.

Parameters

Name Type Description
predictionid bytes32 The unique identifier (ID) of the prediction being created or increased.
deposit uint256 The amount of tokens deposited.

PredictionClaimed

event PredictionClaimed(bytes32 predictionid, address bettor, address erc20, uint256 payout, uint256 commission)

Emitted when a bettor claims the payout for prediction.

This event is triggered when a prediction is successfully claimed, detailing the bettor, payout, and commission.

Parameters

Name Type Description
predictionid bytes32 The unique identifier of the claimed prediction.
bettor address The address of the bettor who is claiming the prediction payout.
erc20 address The ERC20 token used for both the payout and the commission.
payout uint256 The amount of tokens paid out to the bettor as a reward for the prediction.
commission uint256 The amount of tokens deducted from the payout as commission.

MetaOraclyV1

Serves as the main control point for creating and managing games within the Oracly Protocol.

Provides the Oracly Team with the ability to block abused or manipulated games. Game Registry: Maintains a list of active games along with their parameters (schedule, price feed address). Game Creation: Allows authorized users (the Oracly Team) to create and configure new games. Game Blocking: Enables the Oracly Team to block specific games in case of suspected manipulation or technical issues. IMPORTANT: If a Game is blocked, any Rounds with Unverified Outcomes will automatically be treated as No Contest.

SHORTEST_ROUND

uint256 SHORTEST_ROUND

Defines the minimum duration a round can last.

This constant represents the shortest possible round duration in the game, set to 1 minute.

SHORTEST_POSITIONING

uint256 SHORTEST_POSITIONING

Defines the minimum time required for the positioning phase within a round.

This constant ensures the positioning phase lasts for at least 30 seconds.

SHORTEST_EXPIRATION

uint256 SHORTEST_EXPIRATION

Defines the minimum time before a round can expire after it ends.

This constant enforces a minimum round expiration time of 1 hour.

LONGEST_EXPIRATION

uint256 LONGEST_EXPIRATION

Defines the maximum time before a round can expire after it ends.

This constant enforces a maximum expiration time of 7 days for any round.

constructor

constructor() public

The deployer of this contract will automatically be assigned as the contract owner (Oracly Team), who has the privilege to manage game creation, blocking and unblocking the game.

Initializes the contract by setting the deployer as the initial owner (Oracly Team).

addGame

function addGame(address pricefeed, address erc20, uint16 version, uint256 schedule, uint256 positioning, uint256 expiration, uint256 minDeposit) external

Adds a new game to the Oracly Protocol, linking it to a Chainlink price feed and an ERC20 token for deposits and payouts. Can only be called by the contract owner (Oracly Team).

This function registers a new game configuration with specified parameters, including the price feed, token, game logic version, and timing rules for rounds. Requirements: - Caller must be the contract owner (Oracly Team) (enforced via onlyOwner modifier). Emits a GameAdded event when a new game is successfully added.

Parameters

Name Type Description
pricefeed address The address of the Chainlink price feed used to provide pricing data feed for the game.
erc20 address The address of the ERC20 token used for both deposits and payouts in the game.
version uint16 The version of the Oracly game logic, useful for compatibility and updates.
schedule uint256 The interval in seconds between rounds of the game (e.g., 300 for 5 minutes).
positioning uint256 The duration in seconds for the positioning phase, where bettors place predictions.
expiration uint256 The duration in seconds after which the round expires, and only withdraw deposit actions are allowed.
minDeposit uint256 The minimum deposit required to participate in the round, denoted in the ERC20 token.

getActiveGames

function getActiveGames(address erc20, uint256 offset) external view returns (struct Game[] games, uint256 size)

Retrieves a list of active games that use a specific ERC20 token.

This function returns a paginated list of active Game structs that utilize the specified ERC20 token. The results can be fetched using the provided offset for pagination.

Parameters

Name Type Description
erc20 address The address of the ERC20 token being used by the games.
offset uint256 The starting index for pagination of active games.

Return Values

Name Type Description
games struct Game[] An array of Game structs representing the active games using the given ERC20 token.
size uint256 The total number of active games using the specified ERC20 token.

getGame

function getGame(bytes32 gameid) external view returns (struct Game game)

Retrieves the details of a specific game based on its unique identifier.

This function fetches the game details from internal storage using the provided game ID. The game details include all the relevant information about a specific prediction game.

Parameters

Name Type Description
gameid bytes32 The unique identifier for the game, represented as a bytes32 value.

Return Values

Name Type Description
game struct Game A Game struct containing the metadata of the requested game.

unblockGame

function unblockGame(bytes32 gameid) external

Unblocks a previously blocked game, allowing it to resume normal operation.

Unblocking a game restores its availability for bettors and enables gameplay to continue. Can only be called by the contract owner (Oracly Team). Emits a GameUnblocked event upon successful execution. Requirements: - The game must be in a blocked state. - Can only be called by the contract owner.

Parameters

Name Type Description
gameid bytes32 The unique identifier of the game to be unblocked.

blockGame

function blockGame(bytes32 gameid) external

Blocks a game, preventing new prediction rounds from being initiated and marking unresolved rounds as impacted.

Blocks the specified game, ensuring no new rounds are created and impacting any currently unresolved rounds. Emits a GameBlocked upon successful blocking. Requirements: - This function can only be called by the contract owner (Oracly Team). - The game must exist and not already be blocked.

Parameters

Name Type Description
gameid bytes32 The unique identifier of the game to block.

GameAdded

event GameAdded(bytes32 gameid, address pricefeed, address erc20, uint16 version, uint256 schedule, uint256 positioning, uint256 expiration, uint256 minDeposit)

This event is emitted when a new game is added to the Oracly Protocol.

Captures important parameters such as the Chainlink price feed, ERC20 token used, game version, and round timing details.

Parameters

Name Type Description
gameid bytes32 The unique identifier of the newly added game, used for tracking purposes.
pricefeed address The address of the Chainlink price feed used to provide external data for the game.
erc20 address The address of the ERC20 token used for both deposits and payouts in the game.
version uint16 The version of the Oracly game logic, useful for compatibility and updates.
schedule uint256 The interval in seconds between rounds of the game (e.g., 300 for 5 minutes).
positioning uint256 The duration in seconds for the positioning phase, where bettors place predictions.
expiration uint256 The duration in seconds after which the round expires, and only withdraw deposit actions are allowed.
minDeposit uint256 The minimum deposit required to participate in the round, denoted in the ERC20 token.

GameBlocked

event GameBlocked(bytes32 gameid)

This event is emitted when a game is blocked by the Oracly team. It can signal to external systems or users that a game is no longer available for participation or prediction.

Emitted when a game is blocked by the Oracly Team due to unforeseen issues, violations, or any other reasons defined within the protocol.

Parameters

Name Type Description
gameid bytes32 The unique identifier of the blocked game.

GameUnblocked

event GameUnblocked(bytes32 gameid)

This event is emitted when a previously blocked game is unblocked by the Oracly Team.

Emitted when a previously blocked game is unblocked.

Parameters

Name Type Description
gameid bytes32 The unique identifier of the game that has been unblocked.

Game

Represents a series of prediction rounds where bettors predict cryptocurrency price movements for a chance to win rewards.

The struct defines key parameters for a game instance, including the price feed, token used for rewards, and schedule details. - gameid This is a hashed value of main properites representing the game ID. - pricefeed The price feed provides cryptocurrency price data for bettors to make predictions. - erc20 Participants deposit this token to join the game, and rewards are distributed in the same token. - version Tracks the version of the game to differentiate between various game variants. - scheduled Specifies the start time of the game, which is set during initialization. - positioning Defines the time period before the game locks in which bettors can position their predictions. - expiration The time at which the round expires after it ends, and only withdraw deposit actions are allowed. - minDeposit Specifies the smallest amount of ERC20 tokens that a bettor must deposit to enter the game. - blocked If set to true, the game is blocked and no new actions (such as placing predictions) can be taken.

struct Game {
  bytes32 gameid;
  address pricefeed;
  address erc20;
  uint16 version;
  uint256 schedule;
  uint256 positioning;
  uint256 expiration;
  uint256 minDeposit;
  bool blocked;
}

Round

Represents a self-contained prediction contest where bettors predict whether the price of a selected asset will go Down, Up, or remain the same (Zero) within a short timeframe.

Rounds progress through several distinct phases: - Entry (Positioning): Bettors can place predictions starting at startDate and ending at lockDate. - Round: Begins at lockDate and ends at endDate. - Settlement: Starts at endDate and ends either when the outcome is settled or at expirationDate. If not resolved by expirationDate, the round defaults to “No Contest”. - Payout: Begins at resolvedAt and ends either when the last prediction is claimed at archivedAt. - Archive: Starts at archivedAt and is considered the final phase; no further actions can be taken on the round. Bettors with matching predictions share the prize pool proportionally to their deposit. - roundid This is a hashed value representing the round ID. - gameid Links the round to a specific game instance. - resolution This value reflects the round’s outcome. (0 for Undefined, 1 for Down, 2 for Up, 3 for Zero, 4 for No Contest) - entryPrice The price of the selected asset at the round’s opening, used for determining the outcome. - exitPrice The price of the selected asset by the round’s end time to determine the actual price movement. - startDate Bettors can place predictions once the round has started. - lockDate Bettors must submit predictions before this time. After this, no new entries are allowed. - endDate The round ends at this time, and price movement can be evaluated. - expirationDate After this date, unresolved rounds default to “No Contest”. - resolved This is true if the round outcome has been settled. - resolvedAt This indicates when the round’s outcome was settled. - openedAt Indicates when first bettor entered the round. - erc20 Bettors use this token for betting and receiving payouts. - pricefeed The price feed provides the entry and exit prices used to determine the outcome. - archived Once a round is archived, no further actions can be performed on the round. - archivedAt This timestamp is recorded when the archived status is set to true, marking the end of the round’s lifecycle.

struct Round {
  bytes32 roundid;
  bytes32 gameid;
  uint8 resolution;
  struct Price entryPrice;
  struct Price exitPrice;
  uint256 startDate;
  uint256 lockDate;
  uint256 endDate;
  uint256 expirationDate;
  bool resolved;
  uint256 resolvedAt;
  uint256 openedAt;
  address erc20;
  address pricefeed;
  bool archived;
  uint256 archivedAt;
}

Prediction

Represents a bettor’s choice of outcome (Down, Up, Zero) in a prediction game round.

If the bettor’s prediction aligns with the actual price change, they win a share of the prize pool. - predictionid This is a hashed value representing the prediction ID. - roundid Refers to the specific round within the game. - gameid Links the prediction to a specific game instance. - bettor Represents the bettor’s wallet address. - position This is an unit8 where (1 for Down, 2 for Up, 3 for Zero). - deposit This variable stores the value of the deposit for the prediction in the current round. - claimed This is true if the bettor has successfully claimed their payout after winning. - createdAt Records when the bettor made their prediction. - payout This is the amount the bettor receives from the prize pool upon winning. - commission The commission represents the amount deducted and allocated to stakers and mentors on a winning prediction. - erc20 Bettors use this token for betting and receiving rewards in the game.

struct Prediction {
  bytes32 predictionid;
  bytes32 roundid;
  bytes32 gameid;
  address bettor;
  uint8 position;
  uint256 deposit;
  bool claimed;
  uint256 createdAt;
  uint256 payout;
  uint256 commission;
  address erc20;
}

Price

Represents a price point from the Chainlink price feed, including the value, timestamp, and round ID.

Each price point consists of the value, the timestamp when the price was updated, and the Chainlink round ID. - value This represents the price data from the Chainlink price feed. - timestamp Represents the time when the price was updated on the Chainlink feed. - roundid The round ID provides context on which round the price data was fetched from.

struct Price {
  int256 value;
  uint256 timestamp;
  uint80 roundid;
}

EOutcome

Enum representing the possible outcomes of a prediction round in the game.

Bettors predict whether the price of a selected asset will go Down, Up, or remain the same (Zero). Undefined: Value is the initial state when the outcome is unknown. No Contest: - All participants predicted the same outcome (either all Up, all Down, or all Zero), making it impossible to determine winners. - None of the participants correctly predicted the outcome. - The round was not resolved within the allowed time limit.

enum EOutcome {
  Undefined,
  Down,
  Up,
  Zero,
  NoContest
}

StakingOraclyV1

This contract manages multiple aspects of staking, including: - Epoch Management: Handles the creation and lifecycle of staking epochs, ensuring structured reward distribution cycles. - Deposit Tracking: Manages both pending and active staking deposits, providing transparency about stakers’ locked amounts and statuses. - Reward Mechanics: Calculates staking rewards per epoch based on deposited ORCY token amounts automatically. - Buy4Stake: Allows stakers to acquire ORCY tokens directly for staking through the Buy4Stake process.

This contract implements staking functionality for the Oracly Protocol, allowing ORCY token holders to lock tokens in return for staking rewards. Stakers can claim rewards for each epoch through which their deposit was Staked or in Pending Unstake status. The contract uses the Ownable pattern to restrict administrative functions and the ReentrancyGuard to protect against reentrancy attacks. It also implements the ICommissionCollector interface to manage reward distribution mechanisms. Stakers can stake ORCY tokens, claim rewards, and withdraw their stake.

SCHEDULE

uint32 SCHEDULE

The duration of one staking epoch in days.

A staking epoch is fixed at 7 days. This constant used to calculate staking period durations.

FATAL_INSUFFICIENT_STAKEFUNDS_ERROR

bool __FATAL_INSUFFICIENT_STAKEFUNDS_ERROR__

Signals a fatal error caused by insufficient stake funds in the staking pool.

This flag is set to true when the staking pool lacks sufficient funds to continue normal operations. Once active, it blocks new staking actions, although existing stakes will continue to accrue rewards. This is a critical safeguard to prevent the system from allowing additional stakes into a compromised stake pool.

FATAL_INSUFFICIENT_REWARDFUNDS_ERROR

mapping(address => bool) __FATAL_INSUFFICIENT_REWARDFUNDS_ERROR__

Tracks whether a fatal error has occurred for specific ERC20 tokens due to insufficient reward funds.

This mapping records a boolean flag for each ERC20 token address, indicating if the reward pool has encountered a critical shortage of funds. The flag is set to true when the system detects that there are insufficient ERC20 tokens available to fulfill reward obligations. Once set, the system prevents the token from being used for reward accumulation by the contract to avoid further depletion and losses. The flag signals the necessity for manual intervention by an external authorized entity (EOA) to handle reward distribution. Existing rewards will still be distributed, but no new rewards can be accumulated for this token.

STAKING_ERC20_CONTRACT

address STAKING_ERC20_CONTRACT

The address of the ERC20 contract used as staking tokens. (ORCY)

This is an immutable address, meaning it is set once at contract deployment and cannot be changed.

AUTHORIZED_COMMISSION_GATHERER

address AUTHORIZED_COMMISSION_GATHERER

The address of the authorized funds gatherer for the contract.

This is the address responsible for gathering staking rewards from the bettor’s prize on withdrawal and passing them to the contract for further distribution to stakers.

BUY_4_STAKE_ERC20_CONTRACT

address BUY_4_STAKE_ERC20_CONTRACT

The address of the ERC20 contract used in the Buy4Stake process, enabling participants to acquire ORCY tokens at a 1:1 exchange rate.

The Buy4Stake mechanism uses this ERC20 token as a base for participants to purchase and stake ORCY tokens.

ACTUAL_EPOCH_ID

uint256 ACTUAL_EPOCH_ID

Tracks the current epoch ID used in the staking contract.

This value increments with the beginning of each new staking epoch. It starts at a phantom epoch ‘0’, meaning no staking epochs have been initiated yet. The epoch ID is used in various staking operations to identify the current staking epoch.

BUY_4_STAKEPOOL

uint256 BUY_4_STAKEPOOL

Tracks the total amount of ORCY tokens available for the Buy4Stake pool.

The Buy4Stake pool allows users to purchase ORCY tokens at a 1:1 rate and automatically stake them in a single transaction. This variable represents the total funds currently allocated in the Buy4Stake pool.

constructor

constructor(address erc20, address b4s_erc20) public

The provided addresses for the staking token (erc20) and Buy4Stake token (b4s_erc20) must be valid contract addresses and have non-zero total supplies. The contract deployer is assigned as the owner of this contract.

Initializes the StakingOraclyV1 contract with the given ERC20 token addresses for staking and Buy4Stake mechanisms. This constructor ensures that both token addresses are valid and sets the deployer (Oracly Team) as the owner.

Parameters

Name Type Description
erc20 address The address of the ERC20 token to be used for staking. It must be a valid ERC20 token contract and have a non-zero total supply.
b4s_erc20 address The address of the Buy4Stake ERC20 token. It must be a valid ERC20 token contract and have a non-zero total supply.

getStakeOf

function getStakeOf(address staker) external view returns (uint256 stakeof)

Retrieves the current active stake amount for a given staker.

This function calculates the active stake of a staker by subtracting the total unstaked amount from the total staked amount.

Parameters

Name Type Description
staker address The address of the staker whose active stake is being queried.

Return Values

Name Type Description
stakeof uint256 The amount of active stake held by the staker.

getStakerDeposits

function getStakerDeposits(address staker, uint256 offset) external view returns (struct Deposit[] deposits, uint256 size)

Retrieves a paginated list of deposits made by a specific staker. This function helps avoid gas limitations when querying large data sets by allowing the retrieval of deposits in smaller batches (up to 20 deposits per call).

Implements pagination to efficiently retrieve a manageable number of deposits in each query. It returns a maximum of 20 deposits per call, starting from the specified offset.

Parameters

Name Type Description
staker address The address of the staker whose deposits are being queried.
offset uint256 The starting index for pagination, allowing retrieval of deposits starting from that point.

Return Values

Name Type Description
deposits struct Deposit[] An array of Deposit structs representing the staker’s deposits within the specified range.
size uint256 The total number of deposits made by the staker, regardless of pagination.

getStakerPaidout

function getStakerPaidout(address staker, address erc20) external view returns (uint256 paidout)

Returns the total amount that has been paid out to a specific staker for a given ERC20 token across all staking rewards.

This function provides a read-only view of the total accumulated payouts for a staker across all deposits in the specified ERC20 token.

Parameters

Name Type Description
staker address The address of the staker whose accumulated payouts are being queried.
erc20 address The address of the ERC20 token contract for which the payout is being queried.

Return Values

Name Type Description
paidout uint256 The total amount paid out to the staker in the specified ERC20 token.

getDepositPaidout

function getDepositPaidout(bytes32 depositid, address erc20) external view returns (uint256 paidout)

Retrieves the total amount paid out for a specific deposit and ERC20 token.

This function provides a view into the accumulated payouts for a specific deposit across all staking epochs for a given ERC20 token.

Parameters

Name Type Description
depositid bytes32 The unique identifier of the deposit for which the payout is being queried.
erc20 address The address of the ERC20 token corresponding to the payout.

Return Values

Name Type Description
paidout uint256 The total amount that has been paid out for the specified deposit in the given ERC20 token.

getDepositEpochPaidout

function getDepositEpochPaidout(bytes32 depositid, address erc20, uint256 epochid) external view returns (uint256 paidout)

Retrieves the total amount already paid out for a given deposit, ERC20 token, and epoch.

This function provides a view into the accumulated payouts for a specific deposit in a particular epoch and for a specific ERC20 token.

Parameters

Name Type Description
depositid bytes32 The unique identifier of the deposit for which the payout is being queried.
erc20 address The address of the ERC20 token for which the payout is being queried.
epochid uint256 The identifier of the epoch for which the payout is being checked.

Return Values

Name Type Description
paidout uint256 The total amount paid out for the specified deposit, ERC20 token, and epoch.

getDeposit

function getDeposit(bytes32 depositid) external view returns (struct Deposit deposit)

Retrieves the details of a specific deposit identified by depositid.

Fetches a Deposit struct containing details about the deposit, such as the staker’s address, the amount deposited, entry epoch.

Parameters

Name Type Description
depositid bytes32 The unique identifier of the deposit.

Return Values

Name Type Description
deposit struct Deposit The Deposit struct containing the relevant information associated with the given depositid.

getEpoch

function getEpoch(uint256 epochid, address erc20) external view returns (struct Epoch epoch, uint256[3] stakes, uint256[3] stakepool, uint256[2] rewards)

Retrieves full information about a specific staking epoch.

This function provides a view into the current state of a specific staking epoch, including details about stakes, stakepool, and rewards for a given ERC20 token.

Parameters

Name Type Description
epochid uint256 The unique identifier of the staking epoch.
erc20 address The address of the ERC20 token associated with the epoch (optional for rewards stats).

Return Values

Name Type Description
epoch struct Epoch The Epoch struct containing details such as epochid, start and end dates, and timestamps.
stakes uint256[3] An array containing the total staked amount, pending incoming stakes, and pending outgoing stakes for the epoch.
stakepool uint256[3] An array containing the total stakepool amount, pending incoming stakepool, and pending outgoing stakepool for the epoch.
rewards uint256[2] An array containing the collected and released reward amounts for the epoch with respect to the provided ERC20 token.

buy4stake

function buy4stake(address erc20, uint256 epochid, uint256 amount) external

Allows stakers to purchase ORCY tokens using a specific ERC20 token and automatically stake them in the current epoch.

Validates the ERC20 contract, the staker’s balance, allowance, and ensures the epoch is correct. Releases the ORCY tokens from the BUY_4_STAKEPOOL, Distributes the collected tokens among current stakers and stakes the ORCY tokens on staker’s behalf for the current epoch. Requirements - The erc20 must be the BUY_4_STAKE_ERC20_CONTRACT. - The staker must have sufficient balance and allowance for the ERC20 token. - The epochid must match the current epoch (ACTUAL_EPOCH_ID). - The BUY_4_STAKEPOOL must have enough ORCY tokens to cover the purchase. - The staking contract must hold enough ORCY tokens. - Only externally-owned accounts (EOAs) can call this function via the onlyOffChainCallable modifier. Emits: - FATAL_EVENT_INSUFFICIENT_STAKEFUNDS if the staking contract has insufficient ORCY tokens. - Buy4StakepoolReleased event for off-chain tracking. - NewEpochStarted event to indicate the start of a new epoch. - RewardCollected event when the reward is successfully collected and transferred to the contract. - DepositCreated event upon successful creation of a new deposit. - IncreaseDepositAmount event upon successful staking of tokens.

Parameters

Name Type Description
erc20 address The address of the ERC20 token used for the purchase (must match the designated BUY_4_STAKE_ERC20_CONTRACT).
epochid uint256 The ID of the epoch in which the purchased tokens will be staked (must match the current epoch ACTUAL_EPOCH_ID).
amount uint256 The amount of ERC20 tokens the staker wishes to spend on purchasing ORCY tokens.

donateBuy4stake

function donateBuy4stake(uint256 amount) external

Allows stakers to donate ORCY tokens to the buy4stake pool.

Transfers ORCY tokens from the donator’s wallet to the contract, increasing the buy4stake pool. The transfer will revert if the staker’s balance is insufficient or the allowance granted to this contract is not enough. This function can only be called by off-chain EOA, and it uses a non-reentrant modifier to prevent re-entrancy attacks. Requirements: - The caller must have approved the contract to spend at least amount tokens. - Only externally-owned accounts (EOAs) can call this function via the onlyOffChainCallable modifier. - The function is protected against re-entrancy through the nonReentrant modifier. Emits the Buy4StakepoolIncreased event after successfully increasing the pool.

Parameters

Name Type Description
amount uint256 The amount of ORCY tokens the staker wishes to donate.

setBuy4stakeERC20

function setBuy4stakeERC20(address erc20) external

Sets the accepted ERC20 token contract address for the Buy4Stake functionality. The specified ERC20 token will be used to purchase staking tokens (ORCY) in the Buy4Stake process.

This function ensures that the token contract has a non-zero total supply, confirming it is a valid ERC20 token. It also enforces that only the contract owner (Oracly Team) can invoke this function. The function updates the state variable BUY_4_STAKE_ERC20_CONTRACT with the provided ERC20 contract address. Emits the Buy4StakeAcceptedERC20Set event upon successful execution.

Parameters

Name Type Description
erc20 address The address of the ERC20 token contract that will be accepted for Buy4Stake staking operations.

setGatherer

function setGatherer(address gatherer) external

Updates the authorized gatherer address responsible for collecting staking rewards from bettors’ prizes.

This function can only be called by the contract owner (Oracly Team). It checks that the new gatherer is valid contract address. This function is protected by onlyOwner to ensure that only the contract owner can change the gatherer. Emits AuthorizedGathererSet event upon successful update of the gatherer address.

Parameters

Name Type Description
gatherer address The address to be set as the authorized reward gatherer.

stake

function stake(uint256 epochid, uint256 amount) external

Allows a staker to stake a specified amount of ORCY tokens for a given epoch.

The staker must have a sufficient ORCY token balance and must approve the contract to transfer the specified amount of tokens on their behalf. The function uses the nonReentrant modifier to prevent re-entrancy attacks. Only externally-owned accounts (EOAs) can call this function via the onlyOffChainCallable modifier. Emits: - DepositCreated event upon successful creation of a new deposit. - IncreaseDepositAmount event upon successful staking of tokens.

Parameters

Name Type Description
epochid uint256 The ID of the staking epoch for which the tokens are being staked.
amount uint256 The number of ORCY tokens the staker wishes to stake.

unstake

function unstake(uint256 epochid, bytes32 depositid) external

Initiates the unstaking process for a specific deposit during the current staking epoch. The unstaking process will unlock the staked ORCY tokens in the following epoch. During the current epoch, the stake will continue generating rewards until the next epoch starts.

Implements the unstaking mechanism, ensuring: - The staked deposit exists and is owned by the caller. - The caller is unstaking within the correct epoch. - Prevents reentrancy attacks using the nonReentrant modifier. - Only externally-owned accounts (EOAs) can call this function via the onlyOffChainCallable modifier. Emits a DepositUnstaked event upon successful unstaking, indicating the deposit ID and the staker who unstaked it.

Parameters

Name Type Description
epochid uint256 The ID of the epoch in which the unstaking is initiated.
depositid bytes32 The unique identifier of the deposit to be unstaked.

withdraw

function withdraw(bytes32 depositid) external

Allows a staker to withdraw a previously unstaked deposit.

The function reverts under the following conditions: - The deposit does not exist. - The caller is not the owner of the deposit. - The deposit is still actively staked. - The deposit has already been withdrawn. - The withdrawal is attempted before the deposit’s associated out epoch has ended. Requirements: - Only externally-owned accounts (EOAs) can invoke this function, enforced by the onlyOffChainCallable modifier. - The nonReentrant modifier ensures that the function cannot be called again until the first execution is complete. Emits: - DepositWithdrawn on successful withdrawal of the deposit. - FATAL_EVENT_INSUFFICIENT_STAKEFUNDS if the contract lacks sufficient funds to cover the withdrawal.

Parameters

Name Type Description
depositid bytes32 The unique identifier of the deposit to be withdrawn.

claimReward

function claimReward(uint256 epochid, bytes32 depositid, address erc20) external

Claims the staking reward for a specific deposit within a given epoch.

This function ensures that the reward claim process is secure and valid by performing several checks: - Validates that the provided ERC20 token address corresponds to an allowed reward token. - Ensures that the deposit exists and is owned by the caller. - Verifies that the provided epoch ID is within the valid range and associated with the deposit. - Checks that the reward for this deposit and epoch has not been fully claimed previously. - Confirms that the epoch exists and has been initialized correctly. - Ensures that the contract has sufficient funds to distribute the reward; otherwise, it emits a fatal error event. If all checks pass, the reward is calculated, the deposit is marked as rewarded, and the ERC20 tokens are transferred to the caller. Requirements: - The caller must own the deposit. - The epoch ID must be valid and associated with the deposit. - The epoch must be initialized before claiming rewards. - Can only be called by off-chain EOA (using onlyOffChainCallable). Emits: - RewardClaimed Event emitted when the reward is successfully claimed. - FATAL_EVENT_INSUFFICIENT_REWARDFUNDS Event emitted when the contract lacks sufficient funds to pay the reward.

Parameters

Name Type Description
epochid uint256 The ID of the staking epoch for which the reward is being claimed.
depositid bytes32 The unique identifier of the deposit associated with the staker.
erc20 address The address of the ERC20 token that represents the reward.

collectCommission

function collectCommission(address bettor, address erc20, uint256 commission) external

Allows a designated gatherer to collect staking rewards from a bettor’s prize. This function facilitates the transfer of ERC20 tokens from the gatherer’s balance to the contract and processes the reward distribution.

This function performs several important checks to ensure secure commission collection: - Ensures that the gatherer has a sufficient balance of ERC20 tokens to cover the request for commission collection. - Verifies that the gatherer has approved the contract to transfer at least commission of ERC20 tokens. Requirements: - The caller must be an authorized gatherer (onlyGathererCallable). - The gatherer must have a sufficient balance and allowance for the ERC20 token. - The function is protected against reentrancy attacks using the nonReentrant modifier. Emits: - NewEpochStarted event to indicate the start of a new epoch. - RewardCollected event when the commission is successfully collected and transferred to the contract.

Parameters

Name Type Description
bettor address The address of the bettor who paid the commission.
erc20 address The address of the ERC20 token contract from which tokens will be collected.
commission uint256 The amount of ERC20 tokens to collect for reward distribution.

onlyOffChainCallable

modifier onlyOffChainCallable()

Restricts function execution to external accounts (EOA) only.

This modifier ensures that only EOAs (Externally Owned Accounts) can call functions protected by this modifier, preventing contracts from executing such functions. The check is performed by verifying that the caller has no code associated with it (not a contract) and by comparing tx.origin with _msgSender().

onlyGathereCallable

modifier onlyGathereCallable()

Restricts function execution to the authorized funds gatherer.

This modifier ensures that only the authorized entity, defined by the AUTHORIZED_COMMISSION_GATHERER address, can call functions protected by this modifier. If an unauthorized entity tries to invoke the function, the transaction is reverted.

FATAL_EVENT_INSUFFICIENT_REWARDFUNDS

event FATAL_EVENT_INSUFFICIENT_REWARDFUNDS(address staker, bytes32 depositid, address erc20, uint256 epochid, uint256 payout)

Emitted when there are insufficient reward funds available to fulfill a staker’s reward claim.

Acts as an important signal for stakers, indicating that the contract cannot collect the specific ERC20 token and that a manual EOA (Externally Owned Account) distribution is required.

Parameters

Name Type Description
staker address The address of the staker attempting to claim the reward.
depositid bytes32 The unique identifier of the staker’s deposit.
erc20 address The address of the ERC20 token associated with the reward being claimed.
epochid uint256 The ID of the staking epoch in which the reward being claimed.
payout uint256 The amount of the reward that could not be fulfilled due to insufficient funds.

FATAL_EVENT_INSUFFICIENT_STAKEFUNDS

event FATAL_EVENT_INSUFFICIENT_STAKEFUNDS(address staker, address erc20, uint256 balance, uint256 amount)

Emitted when a staker attempts to withdraw an unstaked deposit, but the contract does not have sufficient balance of the staking token (ORCY) to complete the withdrawal.

This serves as a crucial signal for stakers to know that the contract is blocked, and a manual EOA distribution is required.

Parameters

Name Type Description
staker address The address of the staker attempting to withdraw funds.
erc20 address The address of the ERC20 token in which the staked funds are held.
balance uint256 The current ERC20 token balance held by the contract.
amount uint256 The amount of ERC20 tokens the staker attempted to withdraw, which the contract could not fulfill.

DepositUnstaked

event DepositUnstaked(bytes32 depositid, address staker, uint256 epochid)

Emitted when a staker unstakes a deposit.

This event is triggered when a staker initiates the process of unstaking their deposit from a specific epoch.

Parameters

Name Type Description
depositid bytes32 The unique identifier of the unstaked deposit.
staker address The address of the staker who unstaked the deposit.
epochid uint256 The identifier of the epoch during which the deposit was unstaked.

DepositWithdrawn

event DepositWithdrawn(bytes32 depositid, address staker)

Emitted when a staker successfully withdraws their stake deposit.

This event indicates the complete removal of deposited funds by a staker from the contract.

Parameters

Name Type Description
depositid bytes32 The unique identifier of the withdrawn deposit.
staker address The address of the staker who initiated the withdrawal.

RewardClaimed

event RewardClaimed(bytes32 depositid, address staker, address erc20, uint256 epochid, uint256 payout)

Emitted when a staker claims their staking reward for a specific deposit during a particular epoch.

This event is triggered after a successful reward claim by a staker. The event parameters provide detailed information about the deposit, staker, reward token, epoch, and payout amount.

Parameters

Name Type Description
depositid bytes32 The unique identifier of the deposit for which the reward is claimed.
staker address The address of the staker who claimed the reward.
erc20 address The address of the ERC20 token representing the reward.
epochid uint256 The ID of the epoch in which the reward was earned.
payout uint256 The amount of reward claimed by the staker.

CommissionCollected

event CommissionCollected(uint256 epochid, address erc20, address bettor, uint256 commission)

Emitted when staking rewards are collected from a bettor’s paid commission.

This event logs the commission collection for a specific epoch and bettor.

Parameters

Name Type Description
epochid uint256 The identifier of the staking epoch during which the commission is collected.
erc20 address The address of the ERC20 token contract from which tokens are collected.
bettor address The address of the bettor who paid the commission.
commission uint256 The amount of ERC20 tokens collected as commission for reward distribution.

NewEpochStarted

event NewEpochStarted(uint256 epochid, uint256 prevepochid, address erc20, uint256 startedAt, uint256 startDate, uint256 endDate, uint256 stakes, uint256 stakepool)

Emitted when a new staking epoch is initiated, signaling the transition between epochs.

This event provides details about the newly started staking epoch, including its unique identifiers, the ERC20 token being staked, the staking period timestamps, and information about the stakes and stakepool.

Parameters

Name Type Description
epochid uint256 The unique identifier of the newly started staking epoch.
prevepochid uint256 The unique identifier of the epoch that directly preceded the new one.
erc20 address The address of the staking token (ORCY) used for stakepool of the epoch.
startedAt uint256 The timestamp when the new epoch was started.
startDate uint256 The timestamp representing the start of the new epoch’s staking period.
endDate uint256 The timestamp representing the end of the new epoch’s staking period.
stakes uint256 The total amount of deposits staked in new epoch.
stakepool uint256 The total amount of tokens staked in the new epoch.

IncreaseDepositAmount

event IncreaseDepositAmount(bytes32 depositid, address staker, uint256 amount)

Emitted when a staker deposits ORCY tokens into the contract, either by creating a new deposit or increasing an existing one.

This event is emitted every time a staker deposits ORCY tokens into the contract, whether it is a new deposit or an increase to an existing one.

Parameters

Name Type Description
depositid bytes32 The unique identifier of the deposit being created or increased.
staker address The address of the staker making the deposit.
amount uint256 The amount of ORCY tokens deposited.

DepositCreated

event DepositCreated(bytes32 depositid, uint256 epochid, address staker, uint256 createdAt, address erc20)

Emitted when a new stake deposit is created in the contract.

This event is triggered whenever a staker successfully creates a new deposit. It provides details about the deposit including the unique deposit ID, epoch ID, staker’s address, timestamp of creation, and the ERC20 token being staked.

Parameters

Name Type Description
depositid bytes32 Unique identifier for the deposit.
epochid uint256 The ID of the staking epoch in which the deposit is created.
staker address The address of the staker who made the deposit.
createdAt uint256 The timestamp when the deposit is created.
erc20 address The address of the staking token (ORCY) being staked in the deposit.

AuthorizedGathererSet

event AuthorizedGathererSet(address gatherer)

Emitted when a new gatherer is authorized for the contract.

This event is triggered whenever the contract owner (Oracly Team) assigns a new gatherer.

Parameters

Name Type Description
gatherer address The address of the authorized gatherer.

Buy4StakeAcceptedERC20Set

event Buy4StakeAcceptedERC20Set(address erc20)

This event is emitted when the ERC20 token accepted for the Buy4Stake functionality is changed. It indicates that a new ERC20 token will now be used for acquiring ORCY tokens via staking.

This event is critical for tracking updates to the ERC20 token used in Buy4Stake operations.

Parameters

Name Type Description
erc20 address The address of the new ERC20 token that is now accepted for Buy4Stake.

Buy4StakepoolIncreased

event Buy4StakepoolIncreased(address erc20, uint256 stakepool, uint256 amount)

Emitted when the Buy4Stake pool balance is increased.

This event signals that more funds have been added to the Buy4Stake pool. The new total balance of the Buy4Stake pool and the amount that was added.

Parameters

Name Type Description
erc20 address The address of the staking token (ORCY) being added to the Buy4Stake pool.
stakepool uint256 The new balance of the Buy4Stake pool after the increase.
amount uint256 The amount added to the Buy4Stake pool.

Buy4StakepoolReleased

event Buy4StakepoolReleased(address erc20, uint256 stakepool, uint256 amount)

Emitted when funds are released from the Buy4Stake pool.

This event logs the details of funds being released from the Buy4Stake pool, including the updated stake pool balance and the amount released.

Parameters

Name Type Description
erc20 address The address of the staking token (ORCY) associated with the release.
stakepool uint256 The updated balance of the stake pool after the funds are released.
amount uint256 The amount of ERC20 tokens that were released from the pool.

Deposit

Represents a staking deposit of ORCY tokens in the Oracly Staking Contract.

A staker’s deposit is locked for a Staking Epoch, earns rewards, and grants voting power in governance processes. - depositid This is a hashed value representing the deposit ID. - staker This is the wallet address of the staker depositing ORCY tokens. - inEpochid Represents the epoch during which the deposit was created. - createdAt Records the time when the staker deposited ORCY tokens. - amount Specifies the quantity of ORCY tokens deposited into the staking contract. - outEpochid Defines the epoch during which the unstake process was initiated. - unstaked If true, the staker has requested to unlock their staked ORCY tokens. - unstakedAt Records the time when the staker unstake their ORCY tokens from the contract. - withdrawn If true, the staker has successfully withdrawn their tokens after unstaking. - withdrawnAt Records the time when the staker withdrew their ORCY tokens from the contract.

struct Deposit {
  bytes32 depositid;
  address staker;
  uint256 inEpochid;
  uint256 createdAt;
  uint256 amount;
  uint256 outEpochid;
  bool unstaked;
  uint256 unstakedAt;
  bool withdrawn;
  uint256 withdrawnAt;
}

Epoch

Represents a recurring staking period (approximately 7 days) during which the staking pool remains unchanged.

Staking rewards are distributed to stakers proportionally based on Oracly Commissions collected during the epoch. If no stakers register, the start of the epoch is delayed until participation occurs. - epochid This ID is used to track individual epochs. - startDate Indicates when the epoch is set to begin; however, the actual start may be delayed if no stakers participate. - endDate Defines when the staking epoch is expected to conclude, 7 days after the start date. - startedAt This records when the epoch started, which may differ from the scheduled start date due to a delayed start. - endedAt This captures the moment the epoch concluded, and no new staking reward commission is collected into the epoch.

struct Epoch {
  uint256 epochid;
  uint256 startDate;
  uint256 endDate;
  uint256 startedAt;
  uint256 endedAt;
}

MentoringOraclyV1

This contract establishes the mentorship structure, including mentor registration, reward distribution based on Proteges’ success, and relationship tracking within the Oracly Protocol.

Implements a mentorship system within the Oracly Protocol, allowing experienced bettors (Mentors) to guide less experienced bettors (Proteges) through prediction games. The contract manages mentor registrations, tracks mentor-protege relationships, and handles the distribution of Mentoring Rewards. Mentoring Rewards are calculated as a fixed percentage (0.25%) of the Proteges’ winnings from prediction games, encouraging knowledge sharing within the ecosystem.

MENTOR_COMMISSION_PERCENTAGE

uint8 MENTOR_COMMISSION_PERCENTAGE

Percentage of the total Prediction Reward allocated to Mentoring Rewards, expressed in basis points.

The value is set in basis points, where 1% equals 100 basis points. Constant is set to 25 (0.25%) of the commission is allocated to mentoring rewards.

FATAL_INSUFFICIENT_REWARDFUNDS_ERROR

mapping(address => bool) __FATAL_INSUFFICIENT_REWARDFUNDS_ERROR__

Tracks whether the contract is experiencing insufficient reward funds for distribution.

This flag is set to prevent further operations when reward funds are insufficient.

AUTHORIZED_COMMISSION_GATHERER

address AUTHORIZED_COMMISSION_GATHERER

The address of the authorized funds gatherer for the contract.

This is the address responsible for gathering mentoring rewards from the bettor’s prize on withdrawal and passing them to the contract for further distribution to mentors.

constructor

constructor() public

The deployer will automatically be granted the required permissions to gather funds into the contract.

Constructor that initializes the contract, setting the deployer as the owner (Oracly Team) and granting them the role of AUTHORIZED_COMMISSION_GATHERER. The contract deployer is automatically assigned as the owner (Oracly Team) of the contract through the Ownable constructor. Additionally, the deployer is designated as the AUTHORIZED_COMMISSION_GATHERER, a role required for gathering funds.

getMentor

function getMentor(address mentor, address erc20) external view returns (address mentorid, uint256 circle, uint256 rewards, uint256 payouts, uint256 createdAt, uint256 updatedAt)

Retrieves information about a mentor including proteges, rewards, and payout history for a given ERC20 token.

Returns detailed mentor information for the specified ERC20 token, including associated proteges and financial data.

Parameters

Name Type Description
mentor address The address of the mentor.
erc20 address The address of the ERC20 token.

Return Values

Name Type Description
mentorid address the address of the mentor.
circle uint256 The number of proteges associated with the mentor.
rewards uint256 The total rewards earned by the mentor in the specified ERC20 token.
payouts uint256 The total payouts made to the mentor in the specified ERC20 token.
createdAt uint256 The timestamp when the mentor was created.
updatedAt uint256 The timestamp when the mentor’s information was last updated.

getProtege

function getProtege(address protege, address erc20) external view returns (address protegeid, address mentor, uint256 earned, uint256 earnedTotal, uint256 createdAt, uint256 updatedAt)

Retrieves detailed information about a specific Protege, including their mentor, earned rewards for a given ERC20 token, and timestamps for creation and updates.

This function is a view function that returns the following information about the Protege: - Protege’s address - Mentor’s address - Earned rewards for the ERC20 token with the mentor - Total earned rewards for the ERC20 token across all mentors - Timestamps for creation and last update

Parameters

Name Type Description
protege address The address of the Protege whose information is being retrieved.
erc20 address The address of the ERC20 token for which reward details are queried.

Return Values

Name Type Description
protegeid address The Protege’s address, if found.
mentor address The address of the Protege’s mentor.
earned uint256 The rewards earned by the Protege for the specified ERC20 token with their mentor.
earnedTotal uint256 The total rewards earned by the Protege for the specified ERC20 token.
createdAt uint256 The timestamp when the Protege was first created.
updatedAt uint256 The timestamp when the Protege’s information was last updated.

getMentorProteges

function getMentorProteges(address mentor, uint256 offset) external view returns (address[] proteges, uint256 size)

Retrieves a paginated list of Proteges associated with a specific Mentor.

This function returns a list of Protege addresses along with the total number of Proteges linked to the given Mentor. The results can be paginated by specifying an offset.

Parameters

Name Type Description
mentor address The address of the Mentor whose Proteges are being queried.
offset uint256 The starting index for the pagination of the Protege list.

Return Values

Name Type Description
proteges address[] An array of addresses representing the Proteges.
size uint256 The total number of Proteges associated with the Mentor.

getProtegeMentorEarned

function getProtegeMentorEarned(address protege, address erc20, address mentor) external view returns (uint256 earned)

Returns the amount of ERC20 tokens earned by a mentor from a specified protege.

This function retrieves the accumulated earnings a mentor has gained from their protege in the specified ERC20 token.

Parameters

Name Type Description
protege address The address of the protege whose earnings are being queried.
erc20 address The address of the ERC20 token for which the earnings are being checked.
mentor address The address of the mentor who has earned the tokens.

Return Values

Name Type Description
earned uint256 The total amount of ERC20 tokens earned by the mentor from the protege.

setGatherer

function setGatherer(address gatherer) external

Sets the authorized funds gatherer address. Only callable by the contract owner (Oracly Team).

Updates the address authorized to gather funds. This function can only be executed by the contract owner (Oracly Team). It ensures that the new gatherer is valid contract address. Emits AuthorizedGathererSet event upon successful update of the gatherer address. This function is protected by onlyOwner to ensure that only the contract owner can change the gatherer.

Parameters

Name Type Description
gatherer address The new address to be set as the gatherer.

joinMentor

function joinMentor(address mentor) external

Allows a proteges to join a mentor-protege relationship.

This function is external and non-reentrant, ensuring it can only be called from outside the contract and preventing re-entrancy attacks. The onlyOffChainCallable modifier restricts access to off-chain EOA to prevent internal or contract-based invocation. Emits an JoinedMentor event upon successful join.

Parameters

Name Type Description
mentor address The address of the mentor that the protege wants to join.

expelProtege

function expelProtege(address protege) external

Removes a Protege from the Mentor’s circle. This function can only be called by the Mentor who currently mentors the Protege.

Requirements: - The caller of the function (the mentor) must be the current mentor of the protege. - protege must be currently associated with the calling mentor. Emits an ProtegeExpelled event upon successful removal.

Parameters

Name Type Description
protege address The address of the Protege to be expelled from the Mentor’s circle.

transferProtege

function transferProtege(address protege, address mentor) external

Transfers a protege from one mentor to another. The caller must be the current mentor of the protege.

This function ensures that a protege’s mentorship is updated by transferring them from one mentor to another. The transaction is protected against reentrancy attacks and can only be called from an off-chain context. Emits an ProtegeExpelled event upon successful removal from an old mentor. Emits an JoinedMentor event upon successful join to a new mentor.

Parameters

Name Type Description
protege address The address of the protege being transferred.
mentor address The address of the new mentor to which the protege is assigned.

calculateReward

function calculateReward(address protege, uint256 amount) external view returns (uint256 reward)

Calculates the Mentoring Reward for a specific protege based on a provided amount.

This function is an external view override, meaning it can be called externally to view the calculated reward for a protege without any gas fees for state changes.

Parameters

Name Type Description
protege address The address of the protege whose reward is being calculated.
amount uint256 The amount used as the base for the reward calculation.

Return Values

Name Type Description
reward uint256 The calculated Mentoring Reward for the given protege and amount.

collectCommission

function collectCommission(address protege, address erc20, uint256 commission) external

Collects a reward from commission of a protege’s prize and distributes it to the corresponding Mentoring Reward pool. The function facilitates the transfer of rewards from the protege to the mentor’s reward pool using the specified ERC20 token.

Collects a reward from commission of a protege’s prize and distributes it to the associated mentor. Requirements: - protege and sender must be valid. - commission must be greater than zero. - The specified ERC20 token must not be blocked for reward collection. - The caller must have sufficient ERC20 token balance and allowance. - The function ensures reentrancy protection and restricts access using the onlyGathereCallable modifier. Emits a MentorfundsAdded event upon successful reward distribution to the mentor.

Parameters

Name Type Description
protege address The address of the protege, who is receiving mentorship.
erc20 address The address of the ERC20 token used for the reward distribution.
commission uint256 The amount of the ERC20 token to collect and distribute as the reward.

claimReward

function claimReward(address erc20) external

Allows the Mentor (caller) to claim their accumulated Mentoring Reward for a specified ERC20 token.

This function transfers the accumulated Mentoring Reward for the specified ERC20 token to the caller. Requirements: - erc20 must be a valid ERC20 token address. - The caller must have accumulated Mentoring Rewards for the specified ERC20 token. - The contract must hold enough balance of the specified ERC20 token to cover the reward payout. Emits: - MentorRewardPayout event upon a successful claim. - FATAL_EVENT_INSUFFICIENT_REWARDFUNDS event if the contract lacks sufficient funds.

Parameters

Name Type Description
erc20 address The address of the ERC20 token for which the reward is being claimed.

onlyOffChainCallable

modifier onlyOffChainCallable()

Restricts function execution to external accounts (EOA) only.

This modifier ensures that only EOAs (Externally Owned Accounts) can call functions protected by this modifier, preventing contracts from executing such functions. The check is performed by verifying that the caller has no code associated with it (not a contract) and by comparing tx.origin with _msgSender().

onlyGathereCallable

modifier onlyGathereCallable()

Restricts function execution to the authorized funds gatherer.

This modifier ensures that only the authorized entity, defined by the AUTHORIZED_COMMISSION_GATHERER address, can call functions protected by this modifier. If an unauthorized entity tries to invoke the function, the transaction is reverted.

FATAL_EVENT_INSUFFICIENT_REWARDFUNDS

event FATAL_EVENT_INSUFFICIENT_REWARDFUNDS(address mentor, address erc20, uint256 balance, uint256 payout)

Emitted when the reward pool does not have sufficient funds to cover a mentor’s earnings payout. This signals a critical issue as the reward pool is depleted, preventing a successful distribution of rewards.

This event provides transparency on the failure to payout a mentor due to insufficient reward funds. It includes information on the affected mentor, the ERC20 token involved, the current reward fund balance, and the attempted payout amount. It acts as an important signal for mentors to know that the contract is blocked from collecting specific ERC20 tokens and that a manual EOA distribution is required.

Parameters

Name Type Description
mentor address The address of the mentor who should have received the payout.
erc20 address The address of the ERC20 token representing the reward currency.
balance uint256 The current balance of the reward pool for the given ERC20 token.
payout uint256 The intended amount to be paid to the mentor.

JoinedMentor

event JoinedMentor(address protege, address mentor)

Emitted when a protege successfully joins a mentor.

This event is triggered when a protege is associated with a mentor in the Oracly Protocol.

Parameters

Name Type Description
protege address The address of the protege who joins the mentor.
mentor address The address of the mentor that the protege is joining.

ProtegeExpelled

event ProtegeExpelled(address protege, address mentor)

Emitted when a mentor expels a protege.

This event is triggered when a mentor decides to disassociate a protege from their mentorship.

Parameters

Name Type Description
protege address The address of the protege being expelled.
mentor address The address of the mentor performing the expulsion.

MentorfundsAdded

event MentorfundsAdded(address protege, address mentor, address erc20, uint256 reward)

Emitted when a Protege withdraws their prize and 0.25% is assigned to the Mentor’s reward.

This event is triggered whenever a Protege contributes funds to their Mentor.

Parameters

Name Type Description
protege address The address of the Protege who earned the funds.
mentor address The address of the Mentor receiving the reward.
erc20 address The ERC20 token contract address used for the reward transaction.
reward uint256 The amount of Mentor’s reward in ERC20 tokens.

MentorRewardPayout

event MentorRewardPayout(address mentor, address erc20, uint256 payout)

Emitted when a Mentor claims and receives a payout of their accumulated Mentoring Rewards.

This event provides details about the Mentor, the ERC20 token used for the payout, and the payout amount.

Parameters

Name Type Description
mentor address The address of the Mentor who is receiving the payout.
erc20 address The address of the ERC20 token contract used for the payout.
payout uint256 The amount of ERC20 tokens paid to the Mentor.

AuthorizedGathererSet

event AuthorizedGathererSet(address gatherer)

Emitted when a new gatherer is authorized for the contract.

This event is triggered whenever the contract owner (Oracly Team) assigns a new gatherer.

Parameters

Name Type Description
gatherer address The address of the authorized gatherer.

ORCY

The ORCY token is the native token of the Oracly Protocol, enabling staking, governance, and facilitating reward distribution.

This contract implements the standard ERC-20 functionality for the ORCY token, allowing users to transfer ORCY, check balances, and participate in staking and governance. It controls the minting process according to the OraclyV1 Economy, distributing tokens for growth, team, seed, and buy4stake addresses.

TOTAL_SUPPLY

uint256 TOTAL_SUPPLY

Fixed total supply of ORCY tokens, permanently set to 10 million tokens.

The supply is scaled to 18 decimal places (10 million * 1e18).

TOKEN_NAME

string TOKEN_NAME

Official name of the ORCY token, represented as ‘Oracly Glyph’.

This is the full name used in the ERC-20 standard.

TOKEN_SYMBOL

string TOKEN_SYMBOL

The symbol of the ORCY token, denoted as ‘ORCY’.

This symbol will be displayed on exchanges and wallets.

GROWTH_PERCENTAGE

uint8 GROWTH_PERCENTAGE

Percentage of the total token supply allocated for the growth fund.

Set at 10%, this portion is reserved for initiatives that promote ecosystem growth.

TEAM_PERCENTAGE

uint8 TEAM_PERCENTAGE

Percentage of the total token supply allocated for the team.

Set at 10%, this portion is reserved for team members as compensation.

SEED_PERCENTAGE

uint8 SEED_PERCENTAGE

Percentage of the total token supply allocated for seed investors.

Set at 5%, this portion is reserved for early-stage investors who funded the project.

BUY4STAKE_PERCENTAGE

uint8 BUY4STAKE_PERCENTAGE

Percentage of the total token supply allocated for the buy4stake program.

Set at 50%, this portion is reserved for the buy4stake mechanism to incentivize staking.

GROWTH_VESTING_PERCENTAGE

uint8 GROWTH_VESTING_PERCENTAGE

Percentage of the total token supply allocated for growth-related vesting.

Set at 10%, this portion will be unlocked over time to sustain long-term growth initiatives.

TEAM_VESTING_PERCENTAGE

uint8 TEAM_VESTING_PERCENTAGE

Percentage of the total token supply allocated for team vesting.

Set at 10%, this portion will be unlocked gradually for team members as part of their vesting schedule.

SEED_VESTING_PERCENTAGE

uint8 SEED_VESTING_PERCENTAGE

Percentage of the total token supply allocated for seed investors’ vesting.

Set at 5%, this portion will be released over time to early investors in accordance with the vesting schedule.

constructor

constructor(address growth_address, address team_address, address seed_address, address buy4stake_address, address growth_vesting_address, address team_vesting_address, address seed_vesting_address) public

Initializes the ORCY token contract by minting the total supply and distributing it according to the ORCY economy’s token allocation plan.

The total supply of ORCY tokens is minted and allocated across various addresses based on predefined percentages for growth, team, seed investors, and buy4stake mechanisms.

Parameters

Name Type Description
growth_address address Address that receives the portion allocated for growth initiatives (10%).
team_address address Address that receives the portion allocated for the team (10%).
seed_address address Address that receives the portion allocated for seed investors (5%).
buy4stake_address address Address that receives the portion allocated for the buy4stake program (50%).
growth_vesting_address address Address that receives the vesting portion for long-term growth initiatives (10%).
team_vesting_address address Address that receives the vesting portion for team members (10%).
seed_vesting_address address Address that receives the vesting portion for seed investors (5%).

DEMO

Provides a free allocation of DEMO tokens for demonstrating OraclyV1 gameplay.

This contract acts as a faucet, dispensing a controlled amount of DEMO tokens to bettors. Token Allocation: Each eligible request grants 1,000 DEMO tokens. Wallet Limits: No wallet address can request more than 10,000 DEMO tokens in total. ERC-20: Implements basic ERC-20 token functionality for DEMO, allowing transfers and balance checks.

INIT_SUPPLY

uint256 INIT_SUPPLY

Initial supply of DEMO tokens distributed upon contract deployment.

This constant defines the total initial supply of the DEMO tokens (1,000 tokens)

DEMO_SUPPLY

uint256 DEMO_SUPPLY

Amount of DEMO tokens dispensed per mint request

Defines the fixed number of DEMO tokens (1,000 tokens) that can be minted for each minting request.

MAX_ADDRESS_MINT

uint256 MAX_ADDRESS_MINT

Maximum amount of DEMO tokens that a single wallet can mint.

This constant caps the amount of tokens a single wallet can mint (10,000 tokens), ensuring no wallet can exceed this limit.

TOKEN_NAME

string TOKEN_NAME

Official name of the DEMO token, represented as “Oracly Demo”.

This is the full name used in the ERC-20 standard.

TOKEN_SYMBOL

string TOKEN_SYMBOL

The symbol of the DEMO token, denoted as “DEMO”.

This symbol will be displayed on exchanges and wallets.

minted

mapping(address => uint256) minted

Tracks the number of DEMO tokens minted by each bettor.

Maps a bettor’s wallet address to the total number of DEMO tokens they have minted. This mapping is used to enforce minting limits.

constructor

constructor() public

Initializes the contract by minting the initial supply of DEMO tokens to the deployer’s address.

Mints 1,000 DEMO tokens to the deployer’s address upon contract deployment. The ERC20 constructor is called with TOKEN_NAME and TOKEN_SYMBOL as parameters.

mint

function mint() external

Mints 1,000 DEMO tokens to the caller, ensuring the wallet does not exceed the 10,000 DEMO cap.

This function allows the caller to mint 1,000 DEMO tokens at a time, provided they have not reached the maximum cap of 10,000 DEMO tokens per wallet. If minting the tokens would cause the caller’s minted token amount to exceed the cap, the transaction is reverted with MintLimitExceeded. Requirements: - The caller must be an EOA (Externally Owned Account), enforced by the onlyOffChainCallable modifier. - The contract tracks the balance and limits the total mintable tokens to a maximum of 10,000 DEMO per address.

onlyOffChainCallable

modifier onlyOffChainCallable()

Restricts function execution to external accounts (EOA) only.

This modifier ensures that only EOAs (Externally Owned Accounts) can call functions protected by this modifier, preventing contracts from executing such functions. The check is performed by verifying that the caller has no code associated with it (not a contract) and by comparing tx.origin with _msgSender().

VestingOraclyV1

This contract is designed to handle the vesting of ORCY tokens, aligning token release with long-term project goals and incentivizing continued participation.

A vesting contract for ORCY tokens within the Oracly Protocol ecosystem. This contract ensures a gradual and controlled release of ORCY tokens to a designated beneficiary over a 26-month period with a 6-month cliff. The contract overrides the release and receive functions to prevent direct token release or receipt of native tokens.

DURATION

uint64 DURATION

The duration of the vesting period after the cliff, spanning 20 months.

This constant defines the length of time over which the tokens are gradually released after the cliff period.

CLIFF

uint64 CLIFF

The cliff period for the vesting, which lasts 6 months.

No tokens are released during the cliff period. Tokens start releasing only after this period ends.

constructor

constructor(address beneficiary) public

Constructor for VestingOraclyV1 contract.

Initializes the vesting wallet with a predefined cliff period and total duration. Tokens begin vesting after the cliff, and are released gradually over the 20-month duration.

Parameters

Name Type Description
beneficiary address The address of the beneficiary who will receive the vested ORCY tokens.

release

function release() public virtual

Prevents the direct release of native tokens.

Overrides the release function to disable native token release. Only ORCY tokens are managed by this contract.

receive

receive() external payable virtual

Prevents the contract from receiving native tokens.

Overrides the receive function to reject incoming native token transfers.

White Paper

Oracly V1 Protocol

Abstract

Oracly Protocol is a decentralized prediction market maker on the Polygon (PoS) ↗ network. It gamifies the essential skill of trading - forecasting crypto prices - making markets accessible, exciting, and rewarding for everyone.

Players compete in short, dynamic rounds to predict whether the price of an asset will go UP, DOWN, or remain the same (ZERO), directly placing deposits and withdrawing payouts from prize pools. Oracly Protocol utilizes reliable Chainlink ↗ price feeds to create a secure, permissionless, and non-custodial environment.

Introduction

Traditional crypto trading, with its complexities and demanding long-term strategies, can be intimidating for many potential users. Oracly Protocol breaks down these barriers by transforming crypto trading into an engaging and accessible prediction game. Its simplified format, centered around three core choices, opens the world of crypto to a much wider audience.

  • Complexity vs Gamification: Instead of complex and long-term trading routines and strategies, Oracly Protocol offers short rounds where you predict if an asset’s price will go UP, DOWN, or stay the same (ZERO). Players directly contribute to prize pools, and winners withdraw their rewards at the end of each round.

  • Volatility vs Prediction: Oracly Protocol turns market volatility into the focus of the game. Payouts are determined by the direction of price change, not the size of the movement.

  • Security plus Transparency: Powered by the Polygon (PoS) ↗ blockchain, all game rules, predictions, and payouts are transparent and unchangeable. Chainlink Price Feeds ↗ ensure reliable real-time data, guaranteeing fair outcomes for everyone.

Gameplay

Oracly Protocol offers a unique prediction game with continuous rounds. Players predict asset price movements and win a share of the Prize Pool if their predictions are correct.

Round

A self-contained prediction contest where players predict whether the price of a selected asset will go UP, DOWN, or remain the same (ZERO) within a short timeframe. Rounds progress through Entry, Round, Settlement, Payout, and Archive phases. At the end of the short round Player with Prediction matching actual price movement share the Prize Pool proportionally to their deposit.

Entry Phase: (1 minute)

Players place their Predictions (UP, DOWN, ZERO) with deposits for the selected asset’s price movement. This phase determines the Entry Price that all predictions are based on, and the minimum deposit size depends on the Game Level.

  • Begins at the Start Date.
  • Ends at the Lock Date.
  • Player makes deposits for chosen outcomes:
  • IMPORTANT:
    • Players can make multiple deposits for their chosen outcome, increasing their share of the Prize Pool in case of victory.
    • Players can make deposits per each outcome, increasing their probability of victory.
    • Minimum deposit amounts are determined by Game Level:
      Game Level Minimum Deposit
      Bronze 1 USDC
      Silver 10 USDC
      Gold 100 USDC
    • Maximum deposit amounts is unlimited.
    • Players cannot place a Prediction on the NO CONTEST outcome.

Entry Price

  • The asset’s price captured from the Feed latest prices during this phase, serving as the reference point for Predictions.
  • Set by the first player to place a Prediction from Feed latest price, if valid.
  • IMPORTANT: To be valid, the latest price must meet these criteria:
    1. Dated on or after the Round’s Start Date.
    2. Dated before the Round’s Lock Date.
    3. Has a value greater than zero. Oracly Risks Mitigation

Exit Price

  • The final asset price point within a Round Phase determines the Outcome.
  • Verified by the first player to withdraw reward or refund providing Feed’s final price point of the Round, if valid.
  • IMPORTANT: To be valid, the price point must meet criteria:
    1. Dated before the round’s End Date.
    2. Dated on or after the round’s Lock Date.
    3. Has the next sequential price point from the Feed dated on or after the round’s End Date.
    4. Comes from the same Chainlink Aggregator as the Entry Price.
    5. Is less than double the value of the Entry Price.
    6. Is less than double the value of the next sequential price point from the Feed. Oracly Risks Mitigation
    7. Has a value greater than zero. Oracly Risks Mitigation
    8. Oracly Protocol’s design ensures that there will be either one valid price point from the Feed per round to determine the Outcome or none (resulting in a NO CONTEST). Oracly Risks Mitigation

Round Phase: (1 minute, 2 minutes, 3 minutes, 5 minutes)

During the Round Phase, funds is locked and players wait for the Outcome. Predictions can’t be changed. The Prize Pool is finalized, and Players await the Feed to publish the final price point of the phase, which will determine the round’s Outcome.

  • Starts at the Lock Date.
  • Ends:
    • When the Feed publishes the final price point by the End Date.
    • Immediately if a NO CONTEST occurred. (all predicts the same Outcome)
    • After 24 hours with no new price points published by the Feed, resulting in NO CONTEST. Oracly Risks Mitigation
  • Players’ deposits are locked-in, forming the Prize Pool. No more deposits can be made.
  • Players await the Feed to publish the final price point of the phase to determine the round’s Outcome and withdraw their Prediction Reward or Refund.
  • IMPORTANT:
    • To confirm a price point as the final one by the End Date:
      • It must be dated before the round’s End Date
      • The next sequential price point from the Feed must be dated on or after the round’s End Date.
    • A Round is considered NO CONTEST at the beginning of this phase if all Predictions are for the same Outcome. In this scenario, deposits becomes claimable for Refund.
    • The round is considered NO CONTEST if the Feed fails to publish a price within 24 hours. Oracly Risks Mitigation

Settlement Phase: (limited to 24 hours)

The Feed publishes final price point of the Round Phase and the Outcome becomes publicly known. However, Outcome requires protocol’s verification to become permanent. The first player to withdraw their Prediction Reward or Refund performs this verification.

Payout Phase (not limited in time)

Players with winning predictions withdraw their share of the Prize Pool, with payouts based on their deposit size. Protocol collects 1% of Oracly Commission. If the round was NO CONTEST, players withdraw Refunds.

Archive Phase (permanent)

Once a round enters the Archive Phase, it’s permanently closed, signifying the end of its lifecycle. All outcomes, predictions, and payouts are finalized and recorded on the blockchain for transparency and historical reference.

Oracly Protocol Contracts


OraclyV1 ↗: 0xf41c3bec833bf3b05834b8459ee70816d167cf37

MetaOraclyV1 ↗: 0x9acff323637f765fa770c3d1cdbc76bfbfdb4fa8

StakingOraclyV1 ↗: 0x55135638b6301a700070bf08c9b0ef67caf875e4

MentoringOraclyV1 ↗: 0xda4a5d10fd2525b83558f66a24c0c012d67d45a5

ORCY ↗: 0x8def651cbf7deaa35835ed6d4a4d4daabb8b898b

DEMO ↗: 0xde41431172704248b723a36d00044f8132fa444e

Vesting Growth ↗: 0x39ee332b91dc58d6ca668bf874df539cae158016

Vesting Team ↗: 0xd8708ea8214da5a170edac19d9a50c0fffd1b5dc

Vesting Seed ↗: 0xdd084b37837eb0da72abd817375045d22bf73e93


OraclyV1.sol

This contract is the core of the Oracly Protocol’s decentralized prediction game.

  • Rounds Genesis: Creates Rounds, defining their Start Date and End Date, tracks player predictions, and current phases (Entry, Round, Settlement, Payout, Archive).
  • Chainlink Integration: Communicates with the Feeds to securely obtain real-time asset prices, which are used to determine Outcomes.
  • Round Settlement: Verifies Outcomes of each round (UP, DOWN, ZERO, or NO CONTEST) based on comparing Entry Price and Exit Price from the Chainlink Feed.
  • Payout & Refund Logic: Calculates players’ winnings based on their deposits and the round Outcome. Facilitates refunds in the event of a NO CONTEST scenario.

MetaOraclyV1.sol

Serves as the control point for creating new games in the Oracly Protocol. Provides the Oracly Team with the ability to block abused games.

  • Game Registry: Maintains a list of active games with their parameters (schedule, price feed address).
  • Game Creation: Provides functionality for authorized users the Oracly Team to create and configure new games.
  • Game Blocking: Allows the Oracly Team to block specific games in cases of suspected manipulation or technical issues.

IMPORTANT

StakingOraclyV1.sol

Facilitates the core staking functionality of the Oracly Protocol, enabling ORCY token holders to lock their tokens for Staking Reward.

  • Epoch Management: Defines and tracks staking periods (epochs), ensuring structured reward distribution cycles.
  • Deposit Tracking: Manages pending and active stake deposits, providing clarity for Stakers regarding their status.
  • Reward Mechanics: Calculates Staking Reward based on deposited amounts and distributes them to Stakers.
  • ORCY Acquisition: Enabling users to acquire ORCY tokens for staking purposes through the Buy4Stake functionality.

MentoringOraclyV1.sol

Establishes a mentorship system within the Oracly Protocol, connecting experienced players (Mentors) with those seeking guidance (Proteges). Incentivizes skilled players to share their knowledge by offering Mentoring Rewards based on their Proteges’ winnings.

DEMO.sol

The DEMO contract acts as a faucet, dispensing a free allotment of DEMO tokens for demonstration of gameplay. It implements a limit to prevent abuse.

  • Token Allocation: Distributes a fixed amount of 1,000 DEMO tokens per eligible request.
  • Wallet Limits: Enforces a maximum cap of 10,000 DEMO tokens per wallet address to maintain balance.
  • ERC-20: Provides basic ERC-20 ↗ token functionality for the DEMO token, enabling users to transfer it to other wallets and check their balances.

ORCY.sol

The ORCY token is native token of the Oracly Protocol, enabling staking, governance, and facilitating reward distribution. Enables users to lock their ORCY tokens, earning a share of the protocol’s collected Oracly Commissions. Empowers ORCY holders to vote on proposals that shape the future direction of the protocol. Implements the standard ERC-20 ↗ functionality, allowing for seamless transfers and management of ORCY tokens.

  • Staking: ORCY holders can lock their tokens in the Oracly Staking Platform for Staking Rewards.
  • Governance: Empowers holders to propose and vote on key decisions, enabling decentralized governance and shaping the evolution of Oracly Protocol.
  • Minting: Controls the creation of ORCY tokens according to the ORCY Economy, maintaining value for holders.
  • ERC-20: Provides basic ERC-20 token functionality for the ORCY token, enabling users to transfer ORCY to other wallets and check their balances.

VestingOraclyV1.sol

This contract implements a vesting mechanism for the ORCY token within the Oracly Protocol ecosystem. It ensures a gradual and controlled release of ORCY tokens to a designated beneficiary over a predefined vesting period. It ensures that key contributors or stakeholders receive their allocated ORCY tokens in a manner that aligns with the long-term goals of the project. This approach helps to foster commitment, incentivize continued participation, and maintain the stability of the ORCY token’s value.

  • Vesting Duration: The complete vesting period spans 26 months.
  • Cliff Period: A 6-month cliff is enforced, during which no tokens are released to the beneficiary.
  • Gradual Release: After the cliff period, tokens are released linearly over the remaining 20 months.

Oracly Team

The Oracly Team is a dedicated group of engineers and visionaries behind the creation of the Oracly Protocol. Their expertise and passion drive the development and growth of our innovative prediction platform.

Mykhailo Nakonechnyi (Core Contributor): Leads the strategic direction of the Oracly Protocol, ensuring its vision aligns with market needs and technological advancements.

Romain Potochevscky (Core Contributor): Shapes the visual identity and user experience of Oracly, creating an engaging and intuitive platform.

Dmitry Kondratenko (Core Contributor): Translates Oracly’s concepts into robust code, ensuring the platform’s functionality, security, and scalability.

ORCY Token

ORCY is the staking and governance token of the Oracly Protocol, empowering community participation and profit distribution within the platform.

Staking

Oracly Protocol offers a rewarding staking mechanism for ORCY token holders. By locking their ORCY tokens in the Staking Contract, Stakers earn a share of collected Oracly Commissions and gain voting power to shape the protocol’s future:

  • Rewards: Stakers earn a share of the USDC (Oracly Commissions) collected by the protocol. Staking Rewards are distributed proportionally based on the size of a Staking Deposit relative to the overall Staking Pool.
  • Flexibility: Users can withdraw their staked ORCY following an Staking Epoch (7 days) after initiating an unstaking request.
  • Governance: Stakers gain voting power to participate in decisions that shape the Oracly Protocol’ future. Stakers with at least 1% of the ORCY total supply staked are able to join the Presidium and gain the right to submit proposals.

Staking Process

  1. Staking:
  2. Increase (Optional): Stakers can add ORCY to their pending Staking Deposit at any time during Entry Epoch.
  3. Withdraw (Optional): Stakers can withdraw their pending Staking Deposit at any time during Entry Epoch.
  4. Rewards: Stakers starts earning Staking Rewards in USDC from Staking Epoch following Entry Epoch. Stakers can withdraw accrued rewards each Staking Epoch while their stake remains active.
  5. Unstake: An unstaking request can be submitted during any Staking Epoch, this epoch is deposit’ Exit Epoch. Staking Epoch remains active, and the user can continue withdrawing rewards until the end of the epoch.
  6. Withdraw ORCY: Stakers can withdraw their unstaked ORCY deposit.

IMPORTATNT: Oracly Risks Mitigation - Staker can withdraw their pending ORCY deposit at any time. - Staker cannot stake a new deposit in the same Staking Epoch in which a pending deposit was unstaked.

Governance

Stakers gain voting power to participate in decisions that shape the Oracly Protocol’ future. Stakers with at least 1% of the ORCY total supply staked are able to join the Presidium and gain the right to submit proposals.

Voting: All Stakers have a 48-hour window to vote on proposals submitted by Councilors.

Proposals: Only Stakers holding 1% or more of the total ORCY supply may join the Presidium as Councilors, gaining the right to submit proposals.

Execution: A proposal with more Support than Oppose votes after 48 hours and exceeding the quorum requirement is considered Approved by Stakers and ready for execution by Presidium.

Acquiring ORCY

The Oracly Protocol offers a streamlined process to purchase ORCY and immediately begin staking through the Buy4Stake feature on the Oracly Staking Platform

Buy4Stake Process

  • Buy: User pays the Oracly Commissions in USDC, calculated as a 1:1 ratio against the desired ORCY deposit amount. The ORCY tokens are sourced from a dedicated Buy4Stake pool of 5,000,000 ORCY (50% of the total supply), allocated at the time of token generation.
  • Stake: The Staking Contract automatically stakes the acquired ORCY deposit from the Buy4Stake pool.
  • Rewards: Rewards start accruing following the Entry Epoch (approx. 7 days) and can be withdrawn at any time thereafter, as Oracly Commissions are collected.

ORCY Economy

Total Supply: 10,000,000 ORCY (100%)

  • Growth Fund (20%)
    • Staked: 1,000,000 ORCY
    • Vesting: 1,000,000 ORCY
  • Team Fund (20%)
    • Paid Out: 1,000,000 ORCY
    • Vesting: 1,000,000 ORCY
  • Seed Investors (10%)
    • Paid Out: 500,000 ORCY
    • Vesting: 500,000 ORCY
  • Public Sale - Buy4Stake (50%)
    • Available: 5,000,000 ORCY

Growth Fund (20%)

This fund is strategically allocated to fuel initiatives that drive the Oracly Protocol long-term growth, stability, and market reach.

  • Essential Infrastructure: Covering core operational costs such as servers and domains to ensure platform reliability.
  • Protocol Development: Funding continuous upgrades, new features, and enhancements that improve user experience and expand protocol capabilities.
  • Tech Support: Maintaining a robust support system to address user needs and ensure a seamless experience.
  • Strategic Partnerships: Establishing collaborations and integrations that extend Oracly’s ecosystem and increase its value proposition.
  • Marketing and Outreach: Raising awareness, attracting new users, and fostering a vibrant community around the protocol.

Unlocking Schedule:

  • 50% (1,000,000 ORCY) is immediately staked in the Oracly Staking Platform upon token generation. This generates rewards, creating a self-sustaining funding source for growth initiatives.
  • 50% (1,000,000 ORCY) unlocks gradually over 20 months (50,000 ORCY/month), ensuring a steady flow of resources.

Team Reward (20%)

This allocation recognizes the Oracly Team for their exceptional work in conceptualizing and successfully launching the Oracly Protocol V1. Their dedication and passion over the past two years were instrumental in bringing this project to fruition.

Unlocking Schedule:

  • 50% (1,000,000 ORCY) unlocks immediately upon token generation, acknowledging the team’s significant efforts leading up to the protocol’s launch.
  • 50% (1,000,000 ORCY) of the Team Reward unlocks monthly over 20 month (50,000 ORCY / month).

Seed Investors (10%)

This allocation is reserved for strategic partners who played a pivotal role in the Oracly Protocol’s early development. Their support extends beyond financial investments.

  • Industry Expertise: Deep knowledge and insights to guide strategic decisions.
  • Valuable Connections: Extensive networks to facilitate partnerships and collaborations.
  • Mentorship: Guidance and support to accelerate the Oracly Protocol’s growth trajectory.

Unlocking Schedule:

  • 50% (500,000 ORCY) of the Seed Investors allocation unlocks immediately upon token generation.
  • 50% (500,000 ORCY) unlocks gradually over 20 months (25,000 ORCY/month), ensuring a long-term alignment of interests between the seed investors and the Oracly Protocol.

Public Sale “Buy4Stake” (50%)

A significant 5,000,000 ORCY (50% of the total supply) is dedicated to the Buy4Stake feature, offering a streamlined path to acquiring ORCY and becoming part of the Oracly Protocol ecosystem.

Buy4Stake Process:

  • Buy: User pays the Oracly Commissions in USDC, calculated as a 1:1 ratio against the desired ORCY deposit amount. The ORCY tokens are sourced from a dedicated Buy4Stake pool of 5,000,000 ORCY (50% of the total supply), allocated at the time of token generation.
  • Stake: The Staking Contract automatically stakes the acquired ORCY deposit from the Buy4Stake pool.
  • Rewards: Rewards start accruing following the Entry Epoch (approx. 7 days) and can be withdrawn at any time thereafter, as Oracly Commissions are collected.

Unlocking Schedule:

  • 100% (5,000,000 ORCY) is available immediately upon token generation, ensuring accessibility for interested participants.

Oracly Risks Mitigation

Oracly Protocol prioritizes security and fairness, so implemented a multi-faceted approach to mitigation. The protocol implements cirtain measures to address potential risks, ensuring the platform’s integrity.

False Outcome

A malicious player could attempt to manipulate a round’s Outcome by submitting a false price point. This undermines the fairness of the Oracly Protocol.

Mitigation

  • Price Autentication: Verifuies price autenticity with Chainlink Aggregator.
  • Date Validation: Only the final price point within the round’s Lock Date and End Date is valid.
  • Realistic Value Checks: Verifies that price points fall within expected ranges for the asset, filtering out potentially erroneous data.
  • Sequential Consistency: Guarantees price points are sequentially increasing within the same underlying Chainlink Aggregator.
  • Zero-Value Protection: Non-zero price points are enforced, preventing erroneous submissions that could disrupt calculations.

Price Feed Validity

External price feeds could become inaccurate or manipulated. False or corrupted price point data could be received as a valid price point from the Feed.

Mitigation

Underlying Price Feed Aggregator Swap

Chainlink Aggregators can occasionally undergo swaps due to maintenance, updates, or unforeseen circumstances. This could lead to inconsistencies if the Oracly Protocol switches to a new aggregator mid-round.

Mitigation

  • Aggregator Consistency: The Oracly Protocol mitigates this risk by recording the initial Chainlink Aggregators at the start of each round. Even if a swap occurs, the protocol continues to use the original aggregator for all price calculations within that round. This ensures all price points used to determine the Outcome come from a single, consistent source.

L2 Sequencer Outage (Polygon)

Temporary outages on the Polygon PoS L2 Sequencer could interrupt the flow of updated price data from Chainlink Price Feeds. This stale data creates a risk of unreliable outcomes in Oracly Protocol rounds.

Mitigation

  • NO CONTEST Declaration: If Chainlink Price Feeds stale, any unverified rounds will automatically be considered NO CONTEST. This ensures that no player’s predictions are unfairly affected by inaccurate data.
  • 24-Hour Timeframe: The NO CONTEST declaration will occur within 24 hours after a round’s scheduled End Date if price data remains unavailable.

IMPORTANT: In the event of a NO CONTEST, all player deposits within that round become eligible for Refunds.

Fatal Errors

Fatal errors represent a severe mismatch between Oracly Protocol’ expected state and the actual funds within its contracts. These errors jeopardize the security and reliability of the platform.

Potential Causes:

  • Calculation Errors: Miscalculations in reward distribution or payout amounts.
  • External Exploit: A vulnerability in the code is exploited leading to a discrepancy in funds.
  • Unexpected Conditions: Unforeseen events in the L1 blockchain (Ethereum) or L2 (Polygon) that interfere with fund tracking.

Error Events:

  • OraclyV1.sol FATAL_EVENT_INSUFFICIENT_PRIZEFUNDS - Not enough funds to cover player payout or refund.
  • MentoringOraclyV1.sol FATAL_EVENT_INSUFFICIENT_PRIZEFUNDS - Not enough funds to cover mentor rewards.
  • StakingOraclyV1.sol FATAL_EVENT_INSUFFICIENT_REWARDFUNDS - Not enough funds to distribute staking rewards. FATAL_EVENT_INSUFFICIENT_STAKEFUNDS - Not enough funds to process a staked token withdrawal.

Mitigation

Immediate Blocking: Affected contracts automatically block further user deposits, preventing the situation from worsening. Transparent Communication: The protocol emits clear FATAL_EVENT_* signals, enabling users and developers to understand the specific error and its potential impact. NO CONTEST: In the event of a Fatal Error affecting a game round, the affected rounds are automatically declared NO CONTEST. This ensures that no player’s predictions are unfairly impacted due to the error.

Delayed Epoch Start

If no stakers register for a newly scheduled Staking Epoch, Oracly Protocol delays the epoch’s start indefinitely until Stakers participate.

Mitigation

  1. Withdraw Pending Deposits: Allowing users to withdraw their pending ORCY deposits in case they can’t wait for an uncertain start date.
  2. One Deposit Per Epoch: Limiting users to making a single deposit within a staking Epoch prevents potential exploits by blocking the re-stake of the same deposit.
  3. Continue Existing Rewards: Ensuring Stakers with active deposits continue to earn Staking Rewards prevents them from being unfairly affected by a delayed start.

Circular Mentoring

The mentoring system could potentially allow for circular relationships, where a mentor becomes the protege of their own protege (directly or indirectly), creating a loop. This could potentially lead to abuse.

Mitigation

  • Role Restriction: The Oracly Protocol explicitly prevents Mentors from becoming Proteges. This rule eliminates the possibility of circular mentoring relationships.

Audits History

Oracly Rewards Formulas

Reward Formulas

These formulas help to calculate exact amount of Prediction Reward before reward withdrawl. By calculating the Reward (R(d)) and Profit Percentage (PP(d)), Player knows the exact amount of his Prediction Reward payout.

Reward (R(d))

R(d)=Pdp(1C)
  • P (Prize Pool): The total amount of deposited funds from all players in the round.
  • p (Positional Pool): The sum of deposits for the specific Outcome (UP, DOWN, ZERO) player predicting.
  • d (Deposit): The amount of USDC palyer are considering depositing.
  • C (Oracly Commission): The percentage fee (1%) Oracly Protocol takes from winning payouts.

Profit Percentage (PP(d))

PP(d)=R(d)d1
  • d (Deposit): The amount of USDC palyer deposited.
  • R (Reward): per deposit amount

Example:

  • Prize Pool ( P ): 1000 USDC
  • Positional Pool UP ( p ): 200 USDC
  • Deposit ( d ): 50 USDC
  • Commission ( C ): 0.01 (1%)
PR(50) = 1000 * 50 / 200 * (1 - 0.01) = 247.5 USDC
PPP(50) = 247.5 / 50 - 1 = 3.95 = 395%

Deposit: 50 USDC Reward: 247.5 USDC +395%

Potential Reward Formulas

These formulas help to estimate potential Prediction Reward per deposit amount before entering the round. By calculating the Potential Reward (PR(d)) and Potential Profit Percentage (PPP(d)), Player can make more informed decisions about deposit amount and prediction choices.

Potential Reward (PR(d))

PR(d)=(P+d)dp+d(1C)
  • P (Prize Pool): The total amount of deposited funds from all players in the round.
  • p (Positional Pool): The sum of deposits for the specific Outcome (UP, DOWN, ZERO) player predicting.
  • d (Deposit): The amount of USDC palyer are considering depositing.
  • C (Oracly Commission): The percentage fee (1%) Oracly Protocol takes from winning payouts.

Potential Profit Percentage (PPP(d))

PPP(d)=PR(d)d1
  • d (Deposit): The amount of USDC palyer are considering depositing.
  • PR (Potential Reward): per deposit

Example:

  • Prize Pool ( P ): 1000 USDC
  • Positional Pool UP ( p ): 200 USDC
  • Deposit ( d ): 50 USDC
  • Commission ( C ): 0.01 (1%)
PR(50) = (1000 + 50) * 50 / (200 + 50) * (1 - 0.01) = 207.9 USDC
PPP(50) = 207.9 / 50 - 1 = 3.158 = 315.8%

Deposit: 50 USDC Potential Reward: 207.9 USDC +315.8%


Example: A Full Round Scenario

This example illustrates a complete Oracly Protocol Round with four players, demonstrating how predictions, deposits, and rewards work. It also highlights the flow of information in simplified terms, focusing on player actions and blockchain confirmations.

We’ll refer to the confirmed state of the blockchain as “Public Information.”

Round:

  • Asset: BTC/USD (the price of Bitcoin in US Dollars)
  • Duration: 1 minute
  • Game Level: Silver (minimum deposit 10 USDC)
  • Start Date: May 1st, 2024 at 10:00:00 AM
  • Lock Date: May 1st, 2024 at 10:01:00 AM
  • End Date: May 1st, 2024 at 10:02:00 AM

Players:

  • UpBob
  • UpInna
  • DownOw
  • ZeroIda

The following timeline will show how the round progresses, with each player’s prediction, deposit amount, and the resulting impact on potential rewards for each Outcome (UP, DOWN, ZERO).

Entry Phase (60 seconds)

Start Date: May 1st, 2024 at 10:00:00 AM

May 1st, 2024 at 10:00:10 AM

UpBob cannot estimate Potential Reward, the Prize Pool is empty. UpBob places minimum deposit 10 USDC predicting UP. UpBob’s prediction will confirm Entry Price of the Round.

Public Information

Prize Pool:    0 USDC (total)
  - UP:        0 USDC
  - DOWN:      0 USDC
  - ZERO:      0 USDC

May 1st, 2024 at 10:00:20 AM

UpBob’s prediction becomes public, altering the round’s dynamic. Other players must now factor in his prediction and the Entry Price when making their own choices.

  • The latest parice point of the Feed confirmed as Entry Price at 99,999.99999999 USD/BTC

Public Information

Predictions:
    - UpBob:   10 USDC (UP)

Prize Pool:    10 USDC (total)
    - UP:      10 USDC
    - DOWN:     0 USDC
    - ZERO:     0 USDC

Entry Price:   $99,999.99999999

Potential Reward per minuimum deposit (10 USDC)

Outcome Deposit Potential Reward Potential Profit Percentage
UP 10 10 (*) 0%
DOWN 10 19.8 +98%
ZERO 10 19.8 +98%
  • 10 (*): prediction of UP outcome will result on NO CONTEST and Refund.

May 1st, 2024 at 10:00:21 AM

DownOw decided to deposit 50 USDC predicting DOWN.

Public Information

Predictions:
    - UpBob:   10 USDC (UP)

Prize Pool:    10 USDC (total)
    - UP:      10 USDC
    - Down:     0 USDC
    - Zero:     0 USDC

Entry Price:   $99,999.99999999

Potential Reward per DownOw’ deposit (50 USDC)

Outcome Deposit Potential Reward Potential Profit Percentage
UP 50 50 (*) 0%
DOWN 50 59.4 +18.7%
ZERO 50 59.4 +18.7%
  • 50 (*): prediction of UP outcome will result on NO CONTEST and Refund.

May 1st, 2024 at 10:00:31 AM

DownOw’s prediction becomes public, altering the round’s rewards again.

Public Information

Predictions:
    - DownOw:  50 USDC (DOWN)
    - UpBob:   10 USDC (UP)

Prize Pool:    60 USDC (total)
    - UP:      10 USDC
    - Down:    50 USDC
    - Zero:     0 USDC

Entry Price:   $99,999.99999999

Potential Reward per minimum (10 USDC) deposit baised on Public Information

Outcome Deposit Potential Reward Potential Profit Percentage
UP 10 34.65 +246.5%
DOWN 10 11.55 +15.5%
ZERO 10 69.3 +593%

May 1st, 2024 at 10:00:45 AM

UpInna decided to deposit 15 USDC predicting UP.

Public Information

Predictions:
    - DownOw:  50 USDC (DOWN)
    - UpBob:   10 USDC (UP)

Prize Pool:    60 USDC (total)
    - UP:      10 USDC
    - DOWN:    50 USDC
    - ZERO:     0 USDC

Entry Price:   $99,999.99999999

Potential Reward per UpInna’ (15 USDC) deposit:

Outcome Deposit Potential Reward Potential Profit Percentage
UP 15 44.55 +197%
DOWN 15 17.134 +14.2%
ZERO 15 74.25 +395%

May 1st, 2024 at 10:00:55 AM

UpInna’s prediction becomes public altering the round’s rewards.

Public Information

Predictions:
    - UpInna:  15 USDC (UP)
    - DownOw:  50 USDC (DOWN)
    - UpBob:   10 USDC (UP)

Prize Pool:    75 USDC (total)
    - UP:      25 USDC
    - DOWN:    50 USDC
    - ZERO:     0 USDC

Entry Price:   $99,999.99999999

Potential Reward per minimum (10 USDC) deposit:

Outcome Deposit Potential Reward Potential Profit Percentage
UP 10 24.042 +140.4%
DOWN 10 14.025 +40.2%
ZERO 10 84.15 +741.5%

May 1st, 2024 at 10:00:56 AM

ZeroIda decided to deposit 10 USDC predicting ZERO.

Public Information

Predictions:
    - UpInna:  15 USDC  (UP)
    - DownOw:  50 USDC  (DOWN)
    - UpBob:   10 USDC  (UP)

Prize Pool:    75 USDC (total)
    - UP:      25 USDC
    - DOWN:    50 USDC
    - ZERO:     0 USDC

Entry Price:   $99,999.99999999

Potential Reward per ZeroIda’s (10 USDC) deposit:

Outcome Deposit Potential Reward Potential Profit Percentage
UP 10 24.042 +140.4%
DOWN 10 14.025 +40.2%
ZERO 10 84.15 +741.5%

May 1st, 2024 at 10:00:59 AM

ZeroIda’s prediction becomes public altering the round’s rewards.

Public Information

Predictions:
    - ZeroIda: 10 USDC (ZERO)
    - UpInna:  15 USDC (UP)
    - DownOw:  50 USDC (DOWN)
    - UpBob:   10 USDC (UP)

Prize Pool:    85 USDC (total)
    - UP:      25 USDC
    - DOWN:    50 USDC
    - ZERO:    10 USDC

Entry Price:   $99,999.99999999

Potential Reward per minimum (10 USDC) deposit:

Outcome Deposit Potential Reward Potential Profit Percentage
UP 10 26.871 +168.7%
DOWN 10 15.675 +56.7%
ZERO 10 47.025 +370.2%

Round Phase (60 seconds)

Lock Date: May 1st, 2024 at 10:01:00 AM

Funds is locked and UpBob, UpInna, DownOw, ZeroIda wait for the Outcome. Predictions can’t be changed. The Prize Pool is finalized, and Players await the Feed to publish the final price point within the phase, which will determine the round’s Outcome.

Public Information

Predictions:
    - ZeroIda: 10 USDC (ZERO)
    - UpInna:  15 USDC (UP)
    - DownOw:  50 USDC (DOWN)
    - UpBob:   10 USDC (UP)

Prize Pool:    85 USDC (total)
    - UP:      25 USDC
    - DOWN:    50 USDC
    - ZERO:    10 USDC

Entry Price:   $99,999.99999999

Prediction Rewards in case of currect prediction.

Player Outcome Deposit Reward Profit Percentage
ZeroIda Zero 10 84.15 +741.5%
UpInna Up 15 50.49 +236.6%
DownOw Down 50 84.15 +68.3%
UpBob Up 10 33.66 +236.6%

Settlment Phase (limited at 24 hours)

May 1st, 2024 at 10:02:10 AM

The Feed publishes the final price point of the Round, publicly revealing the round’s Outcome. While the final price of $100,000.00 per 1 BTC becomes the potential Exit Price, it remains Unverified by the protocol and therefore not yet permanent.

Public Information

Predictions:
    - ZeroIda: 10 USDC (ZERO)
    - UpInna:  15 USDC (UP)
    - DownOw:  50 USDC (DOWN)
    - UpBob:   10 USDC (UP)

Prize Pool:    85 USDC (total)
    - UP:      25 USDC
    - DOWN:    50 USDC
    - ZERO:    10 USDC

Entry Price:    $99,999.99999999
Exit Price:    $100,000.00000000 (Unverified)

Outcome:       UP (Unverified)

Payout Phase (not limited in time)

May 1st, 2024 at 10:02:25 AM

UpBob withdraw his Prediction Reward providing the final price point ($100,000.00 per 1 BTC) of the Feed within the Round Phase for verification. The potential Exit Price remains Unverified until confirmed by the protocol.

Public Information

Predictions:
    - ZeroIda: 10 USDC (ZERO)
    - UpInna:  15 USDC (UP)
    - DownOw:  50 USDC (DOWN)
    - UpBob:   10 USDC (UP)

Prize Pool:    85 USDC (total)
    - UP:      25 USDC
    - DOWN:    50 USDC
    - ZERO:    10 USDC

Entry Price:    $99,999.99999999
Exit Price:    $100,000.00000000 (Unverified)

Outcome:       UP (Unverified)

Prediction Rewards (Unverified)

Player Prediction Deposit Payout Profit Percentage
UpInna UP 15 USDC 50.49 USDC +236.6%
UpBob UP 10 USDC 33.66 USDC +236.6%

May 1st, 2024 at 10:02:35 AM

UpBob’s verification is confirmed, finalizing the Outcome. The final price point is verified as the Exit Price. This signifies the Outcome as permanent on the blockchain.

Public Information

Payouts:
   - UpBob:    33.66 USDC (commission: 0.33 USDC)

Predictions:
   - ZeroIda:  10 USDC (ZERO)
   - UpInna:   15 USDC (UP)
   - DownOw:   50 USDC (DOWN)
   - UpBob:    10 USDC (UP)

Prize Pool:    85 USDC (total)
   - UP:       25 USDC
   - DOWN:     50 USDC
   - ZERO:     10 USDC

Entry Price:    $99,999.99999999
Exit Price:    $100,000.00000000

Outcome:       UP

Rewards

Player Prediction Deposit Payout Profit Percentage
UpInna UP 15 USDC 50.49 USDC +236.6%
UpBob UP 10 USDC 33.66 USDC +236.6%

May 11st, 2024 at 10:02:45 AM

UpInna’s decited to withdraw her reward after 10 days delay.

UpBob’s verification of the Outcome within the first 24 hours permanently confirmed it on the blockchain. This crucial step enabled UpInna to execute her delayed claim of the Prediction Reward.

Archive Phase (permanent)

May 11st, 2024 at 10:02:55 AM

UpInna’s withdrawal, published on the blockchain, marks the completion of the Round and the start of the Archive Phase. With all rewards claimed, the Round becomes immutable, forever recorded on the blockchain.

Public Information (Archived)

Payouts:
   - UpInna:   50.49 USDC (commission: 0.51 USDC)
   - UpBob:    33.66 USDC (commission: 0.33 USDC)

Predictions:
   - ZeroIda:  10 USDC (ZERO)
   - UpInna:   15 USDC (UP)
   - DownOw:   50 USDC (DOWN)
   - UpBob:    10 USDC (UP)

Prize Pool:    85 USDC (total)
   - UP:       25 USDC
   - DOWN:     50 USDC
   - ZERO:     10 USDC

Entry Price:    $99,999.99999999 per BTC
Exit Price:    $100,000.00000000 per BTC

Outcome:       UP

Prediction Rewards

Player Prediction Deposit Payout Profit Percentage
UpInna UP 15 USDC 50.49 USDC +236.6%
UpBob UP 10 USDC 33.66 USDC +236.6%

Glossary

Game

A nonstop series of prediction rounds where players predict cryptocurrency price movements for a chance to win rewards.


Round

A self-contained prediction contest where players predict whether the price of a selected asset will go UP, DOWN, or remain the same (ZERO) within a short timeframe. Rounds progress through Entry, Round, Settlement, Payout, and Archive phases. At the end of the short round Player with Prediction matching actual price movement share the Prize Pool proportionally to their deposit.


Entry Phase

Players place their Predictions (UP, DOWN, ZERO) with deposits for the selected asset’s price movement. This phase determines the Entry Price that all predictions are based on, and the minimum deposit size depends on the Game Level.

  • Begins at the Start Date.
  • Ends at the Lock Date.
  • Player makes deposits for chosen outcomes:
  • IMPORTANT:
    • Players can make multiple deposits for their chosen outcome, increasing their share of the Prize Pool in case of victory.
    • Minimum deposit amounts are determined by Game Level:
      Game Level Minimum Deposit
      Bronze 1 USDC
      Silver 10 USDC
      Gold 100 USDC
    • Maximum deposit amounts is unlimited.
    • Players cannot place a Prediction on the NO CONTEST outcome.

Round Phase

During the Round Phase, funds is locked and players wait for the Outcome. Predictions can’t be changed. The Prize Pool is finalized, and Players await the Feed to publish the final price point of the phase, which will determine the round’s Outcome.

  • Starts at the Lock Date.
  • Ends:
    • When the Feed publishes the final price point by the End Date.
    • Immediately if a NO CONTEST occurred. (all predicts the same Outcome)
    • After 24 hours with no new price points published by the Feed, resulting in NO CONTEST. Oracly Risks Mitigation
  • Players’ deposits are locked-in, forming the Prize Pool. No more deposits can be made.
  • Players await the Feed to publish the final price point of the phase to determine the round’s Outcome and withdraw their Prediction Reward or Refund.
  • IMPORTANT:
    • To confirm a price point as the final one by the End Date:
      • It must be dated before the round’s End Date
      • The next sequential price point from the Feed must be dated on or after the round’s End Date.
    • A Round is considered NO CONTEST at the beginning of this phase if all Predictions are for the same Outcome. In this scenario, deposits becomes claimable for Refund.
    • The round is considered NO CONTEST if the Feed fails to publish a price within 24 hours. Oracly Risks Mitigation

Settlement Phase

The Feed publishes final price point of the Round Phase and the Outcome becomes publicly known. However, Outcome requires protocol’s verification to become permanent. The first player to withdraw their Prediction Reward or Refund performs this verification.


Payout Phase

Players with winning predictions withdraw their share of the Prize Pool, with payouts based on their deposit size. Protocol collects 1% of Oracly Commission. If the round was NO CONTEST, players withdraw Refunds.


Archive Phase (permanent)

Once a round enters the Archive Phase, it’s permanently closed, signifying the end of its lifecycle. All outcomes, predictions, and payouts are finalized and recorded on the blockchain for transparency and historical reference.


Prize Pool

The sum of all player deposits that will be distributed to winners at the end of a Round.


Oracly Commission

Funds that was collected from the Oracly Protocol and distributed as rewards for Stakers and Mentors:

  • Mentor Share: 0.25% of the payout is distributed to a winning player’s Mentor, if applicable
  • Stakers’ Share: 0.75% of the payout is distributed to stakers.
  • IMPORTANT:
    • If a player has no Mentor, Stakers receive the entire 1% commission.

Oracly Protocol utilizes two types of commissions:

  • Withdrawal Commission (1%): Players pay a 1% commission on the withdrawal of rewards earned from correct predictions. This commission is collected in USDC.
  • Buy4Stake Commission (1:1): When acquire ORCY tokens for staking through the Oracly Staking Platform, users pay a commission in USDC, calculated as a 1:1 ratio against the desired ORCY deposit amount.

Prediction Reward

The payout a player earns if they correctly predict whether an asset’s price will go UP, DOWN, or stay the same (ZERO) within a game round. The larger the deposit, and the smaller the amount of funds deposited by who picked the same outcome, the bigger potential reward.

Prediction Reward can be calcualted using Reward (R(d)).

Oracly Protocol takes 1% commission on withdrwas of reward for prediction.

Example: In a round with a 1000 USDC Prize Pool, Where 200 USDC was deposited on the winning UP outcome, The deposit of 50 USDC, could earn 247.5 USDC reward.


Refund

A Refund is the full return of a player’s deposit when a round is declared NO CONTEST.

Refund mechanism ensures that players do not lose their deposited funds due to unforeseen circumstances or technical issues affecting the Outcome. Oracly Protocol does not collect any commission in a NO CONTEST scenario.

Refund Occurs:

A NO CONTEST round, and subsequent Refunds, can be triggered by various events, such as:

  • No Valid Predictions: If all predictions within a round are for the same Outcome.
  • No Valid Winning: If no a prediction within a round is for the actual Outcome.
  • Price Feed Failure: If the Chainlink Price Feed fails to provide a valid price point within 24 hours.
  • Technical Issues: Any unforeseen disruptions that prevent the fair determination of a round’s Outcome or Prediction Reward distribution.

Outcome

The actual change in the selected asset’s price between Entry Price and Exit Price of the Round, as published by the Chainlink Price Feed. Outcome can be UP, DOWN, ZERO, or NO CONTEST.

IMPORTANT Precision of the price points in the Feed is 8 decimals. Scenarios of NO CONTEST resolution:

  1. All Predictions in a Round are on the same Outcome.
  2. No Predictions match the actual Outcome.
  3. The Feed doesn’t publish an Exit Price within 24 hours.
  4. No Players withdraw rewards or refunds within 24 hours.

Entry Price

  • The asset’s price captured from the Feed latest prices during this phase, serving as the reference point for Predictions.
  • Set by the first player to place a Prediction from Feed latest price, if valid.
  • IMPORTANT: To be valid, the latest price must meet these criteria:
    1. Dated on or after the Round’s Start Date.
    2. Dated before the Round’s Lock Date.
    3. Has a value greater than zero. Oracly Risks Mitigation

Exit Price

  • The final asset price point within a Round Phase determines the Outcome.
  • Verified by the first player to withdraw reward or refund providing Feed’s final price point of the Round, if valid.
  • IMPORTANT: To be valid, the price point must meet criteria:
    1. Dated before the round’s End Date.
    2. Dated on or after the round’s Lock Date.
    3. Has the next sequential price point from the Feed dated on or after the round’s End Date.
    4. Comes from the same Chainlink Aggregator as the Entry Price.
    5. Is less than double the value of the Entry Price.
    6. Is less than double the value of the next sequential price point from the Feed. Oracly Risks Mitigation
    7. Has a value greater than zero. Oracly Risks Mitigation
    8. Oracly Protocol’s design ensures that there will be either one valid price point from the Feed per round to determine the Outcome or none (resulting in a NO CONTEST). Oracly Risks Mitigation

The Chainlink network operates as a decentralized network of oracles, which are crucial in fetching and delivering external data to blockchain smart contracts. This decentralized arrangement enhances the reliability and security of the data, as it minimizes the risks associated with data manipulation by ensuring no single point of failure. This structure is particularly important because it helps maintain the integrity and accuracy of the data fed into smart contracts, which are foundational for Oracly Protocol.

Chainlink’s network consists of numerous independent nodes, known as oracles, that collectively work to fetch data from various external sources. These nodes are incentivized to perform accurately and reliably to maintain their reputation and effectiveness within the network. By aggregating data from multiple sources, Chainlink ensures that the final data provided to the smart contracts is well-rounded and robust against potential data-specific risks or inaccuracies.

Chainlink Web3 Platform.


An aggregator is the contract that receives periodic data updates from the Chainlink oracle network. Aggregators store aggregated data onchain so that consumers can retrieve it and act upon it within the same transaction.

The 3 Levels of Data Aggregation in Chainlink Price Feeds ↗


Price Feeds ↗ provide data that is aggregated from many data sources by a decentralized set of independent node operators. The Decentralized Data Model ↗ describes this in detail. Oracly Protocol uses Low Market Risk ↗ feeds to ensure consistent, accurate, and manipulation-resistant price data for fair outcomes.

Feed price points genesis mechanism Offchain Reporting (OCR) Tech Deep Dive: OCR Protocol Paper


Unverified Round

A round of the game where the Outcome is publicly known (the asset’s price movement) but not yet verified and confirmed by Oracly Procotol contracts and therefore not yet permanent. While the Outcome is typically confirmed, there’s a possibility it could change if the protocol detects discrepancies in the Price Data.


Mentors

Player who mentor Proteges. Mentor rewarded with 0.25% of each win payout to their Protege in currency of the payout.


Mentoring Reward

A reward earned by Mentors within the Oracly Protocol ecosystem.

  • Mentors receive a percentage (0.25%) of every winning payout earned by their Proteges.
  • This reward incentivizes experienced players to find and support newer players on the protocol.
  • To become a Mentors, players can generate invitation link within the Oracly Protocol.

Example

  1. Alice (Mentor) guides Bob (Protege) on Oracly strategies.
  2. Bob wins a round and earns a payout of 100 USDC.
  3. Alice automatically receives a Mentoring Reward of 0.25 USDC (0.25% of Bob’s payout).

Protege

A player who receives guidance and support from a more experienced player Mentors. Proteges benefit from their mentor’s knowledge, gaining valuable insights into crypto realm and the Oracly Protocol’ prediction game.


Polygon (PoS)

Polygon is a “layer two” or “sidechain” scaling solution that runs alongside the Ethereum blockchain — allowing for speedy transactions and low fees. MATIC is the network’s native cryptocurrency, which is used for gas fees on the platform.


MATIC

MATIC is the native cryptocurrency of the Polygon (PoS) network. It’s primarily used to pay for transaction fees (gas fees) on the platform.


Prediction

A player’s choice of Outcome (UP, DOWN, ZERO) within a round. If the prediction aligns with the actual price change, the player wins a share of the Prize Pool.


Game Level

Determines the minimum amount player can deposit on a prediction within a single round. Oracly Protocol offers different Game Levels to cater to various player preferences and risk appetites.

Game Level Minimum Deposit
Bronze 1 USDC
Silver 10 USDC
Gold 100 USDC

DEMO

A special-purpose token used exclusively within the Oracly Protocol’s demonstration environment. It allows players to experience the gameplay and mechanics of the platform without risking real assets.


ORCY

The native token of the Oracly Protocol.

  • Staking: ORCY holders can lock their tokens in the Oracly Staking Platform for Staking Rewards.
  • Governance: Empowers Stakers to propose and vote on key decisions, enabling decentralized governance and shaping the evolution of Oracly Protocol.

Oracly Staking Platform

The Oracly Staking Platform is a gateway to earning share of system income and becoming an integral part of the Oracly Protocol ecosystem. By staking ORCY tokens, Staker not only receive a share of the Oracly Commissions, but also gain the power to vote on proposals that shape the protocol’s future.


Buy4Stake

A unique feature within the Oracly Protocol that streamlines the process of acquiring ORCY tokens and immediately participating in staking. A significant 5,000,000 ORCY (50% of the total supply) is dedicated to the Buy4Stake feature, allocated at the time of ORCY token generation.

Buy4Stake Process

  • Buy: User pays the Oracly Commissions in USDC, calculated as a 1:1 ratio against the desired ORCY deposit amount. The ORCY tokens are sourced from a dedicated Buy4Stake pool.
  • Stake: The Staking Contract automatically stakes the acquired ORCY deposit from the Buy4Stake pool.
  • Rewards: Rewards start accruing following the Entry Epoch (approx. 7 days) and can be withdrawn at any time thereafter, as Oracly Commissions are collected.

Staking Pool

A pool of ORCY tokens within the Oracly Protocol where holders can securely lock their tokens for an arbitrary period.

  • Reward Distribution: Stakers claims a share of the Oracly Commissions based on the size of a Staking Deposit relative to the overall Staking Pool.
  • Governance: Stakers gain voting power to participate in key decisions that shape the future of the Oracly Protocol.

Staking Rewards

Rewards earned by ORCY token holders who lock their tokens in the Oracly Staking Contract. Stakers claims a share of the Oracly Commissions based on the size of a Staking Deposit relative to the overall Staking Pool.


Staking Epoch

A recurring period (approximately 7 days) during which the staking pool remains unchanged. Staking Rewards are distributed as Oracly Commissions collected throughout the epoch are distributed proportionally to Stakers. Epochs ensure predictable staking cycles for Stakers.

IMPORTANT

  • Delayed Epoch Start: If no stakers register for a newly scheduled Staking Epoch, Oracly Protocol delays the epoch’s start indefinitely until Stakers participate. Delayed Epoch Start
  • Flexibility: Users can request to exit epoch by unstaking ORCY deposit. User can withrawd ORCY deposit following an Staking Epoch (approx. 7 days) after initiating an unstaking request.

Staker

An ORCY holder who locks their tokens in the Oracly Staking Contract to earn Staking Rewards and participate in Oracly Protocol’ governance.

  • Earning Rewards: Stakers receive a share of the Oracly Commissions. Rewards are distributed in USDC.
  • Flexible Staking: Stakers can withdraw staked ORCY after a Staking Epoch (approximately 7 days) following an unstake request.
  • Governance Power: Stakers gain voting power to participate in key decisions that shape the future of the protocol.
  • Presidium Membership: Stakers holding at least 1% of the total ORCY supply staked gain the right to submit proposals for the protocol’s growth.

Presidium

The governing council within the Oracly Protocol. Presidium members is Stakers who hold at least 1% of the total ORCY supply staked and expricitly join Presidium community of Councilors, gaining the right to submit proposals. Presidium responsible for creating and executing proposals.


Councilor

A Councilor is a member of the Presidium who holds at least 1% of the total ORCY supply staked. Councilors have the exclusive right to submit proposals for consideration by the Stakers, playing a crucial role in shaping the future direction of the platform through decentralized governance.


Entry Epoch

The initial staking period (approx. 7 days) during which a staker’s ORCY deposit is pending. Stakers cannot earn rewards in the Entry Epoch, but they can increase or withdraw their deposit. Staking Rewards begin in the epoch immediately following the Entry Epoch.


Staking Deposit

The specific quantity of ORCY tokens that a user commits to the Oracly Staking Contract. This deposit is locked for a Stakign Epoch and earns rewards based on its size relative to the total amount staked in the system. Staking Deposits also grant the user voting power in the protocol’s governance processes.


Unverified (Outcome)

A state in a round where the Outcome (UP, DOWN, ZERO) is publicly known based on the Chainlink Price Feeds data, but not yet verified as Exit Price by the Oracly Protocol contracts. This is a temporary state that ensures the Outcome is accurate and hasn’t been tampered with before payouts are made.


May 10, 2024 (@metaferryman)