use crate::error::StreakError;
use steel::*;
use super::{market_pda, Position, StreakAccount};
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct Market {
pub period: u64,
pub series_id: u16,
pub _pad_series: [u8; 6],
pub open_ts: i64,
pub close_ts: i64,
pub rules_hash: [u8; 32],
pub total_up: u64,
pub total_down: u64,
pub loser_pot: u64,
pub reward_pool: u64,
pub winning_total: u64,
pub pyth_price_feed: Pubkey,
pub open_ref_price: i64,
pub open_ref_publish_time: i64,
pub open_ref_expo: i32,
pub _pad_expo: [u8; 4],
pub outcome: u8,
pub status: u8,
pub _pad_pre_commit: [u8; 6],
pub committed_up: u64,
pub committed_down: u64,
}
impl Market {
pub const SIDE_UP: u8 = 0;
pub const SIDE_DOWN: u8 = 1;
pub const OUTCOME_UNSET: u8 = 255;
pub const STATUS_OPEN: u8 = 0;
pub const STATUS_SETTLED: u8 = 1;
pub fn pda(series_id: u16, period: u64) -> (Pubkey, u8) {
market_pda(series_id, period)
}
pub fn init_open(
series_id: u16,
period: u64,
open_ts: i64,
close_ts: i64,
pyth_price_feed: Pubkey,
rules_hash: [u8; 32],
) -> Self {
Self {
period,
series_id,
_pad_series: [0; 6],
open_ts,
close_ts,
rules_hash,
total_up: 0,
total_down: 0,
loser_pot: 0,
reward_pool: 0,
winning_total: 0,
pyth_price_feed,
open_ref_price: 0,
open_ref_publish_time: 0,
open_ref_expo: 0,
_pad_expo: [0; 4],
outcome: Self::OUTCOME_UNSET,
status: Self::STATUS_OPEN,
_pad_pre_commit: [0; 6],
committed_up: 0,
committed_down: 0,
}
}
#[inline(always)]
pub fn has_open_oracle_snapshot(&self) -> bool {
self.open_ref_publish_time != 0
}
pub fn merge_committed_preopen_into_pool(&mut self, pos: &mut Position) -> Result<(), StreakError> {
if pos.state != Position::STATE_COMMITTED_PREOPEN {
return Err(StreakError::BadMarketState);
}
let s = pos.stake;
if s == 0 {
return Err(StreakError::BadMarketState);
}
match pos.side {
Self::SIDE_UP => {
self.committed_up = self
.committed_up
.checked_sub(s)
.ok_or(StreakError::Overflow)?;
self.total_up = self.total_up.checked_add(s).ok_or(StreakError::Overflow)?;
}
Self::SIDE_DOWN => {
self.committed_down = self
.committed_down
.checked_sub(s)
.ok_or(StreakError::Overflow)?;
self.total_down = self.total_down.checked_add(s).ok_or(StreakError::Overflow)?;
}
_ => return Err(StreakError::BadMarketState),
}
pos.state = Position::STATE_PENDING;
Ok(())
}
}
account!(StreakAccount, Market);