diff --git a/Cargo.lock b/Cargo.lock index c98ade4..d4bd11f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1299,6 +1299,36 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "ore-delegate-api" +version = "3.7.0" +dependencies = [ + "bytemuck", + "const-crypto", + "mpl-token-metadata", + "num_enum", + "solana-program", + "spl-associated-token-account", + "spl-token 4.0.2", + "steel", + "thiserror 1.0.69", +] + +[[package]] +name = "ore-delegate-program" +version = "3.7.0" +dependencies = [ + "bincode", + "mpl-token-metadata", + "ore-delegate-api", + "rand 0.8.5", + "solana-program", + "spl-associated-token-account", + "spl-token 4.0.2", + "spl-token-2022 7.0.0", + "steel", +] + [[package]] name = "ore-program" version = "3.7.0" diff --git a/Cargo.toml b/Cargo.toml index 5416108..1c3e69a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["api", "program"] +members = ["ore/*", "ore-delegate/*"] [workspace.package] version = "3.7.0" @@ -21,7 +21,8 @@ bytemuck_derive = "1.7.0" const-crypto = "0.1.0" mpl-token-metadata = "5.1" num_enum = "0.7.2" -ore-api = { path = "api" } +ore-api = { path = "./ore/api" } +ore-delegate-api = { path = "./ore-delegate/api" } ore-boost-api = "4.0.0-alpha" solana-account-decoder = "^2.1" solana-program = "^2.1" diff --git a/README.md b/README.md index 93183f6..70d8066 100644 --- a/README.md +++ b/README.md @@ -2,37 +2,6 @@ **Mine blockspace. Trade hashpower. Win rewards.** -## API -- [`Consts`](api/src/consts.rs) – Program constants. -- [`Error`](api/src/error.rs) – Custom program errors. -- [`Event`](api/src/error.rs) – Custom program events. -- [`Instruction`](api/src/instruction.rs) – Declared instructions and arguments. - -## Instructions - -- [`Open`](program/src/open.rs) - Open a new block. -- [`Close`](program/src/close.rs) - Close a block and pay out the reward. -- [`Mine`](program/src/mine.rs) - Mine the current block. -- [`Swap`](program/src/swap.rs) - Trade in a hashpower market. - -## State -- [`Block`](api/src/state/block.rs) - A period of time for mining. -- [`Config`](api/src/state/config.rs) - Global program configuration. -- [`Market`](api/src/state/market.rs) - Hashpower market for a given block. -- [`Miner`](api/src/state/miner.rs) - Tracks a miner state and history. -- [`Treasury`](api/src/state/treasury.rs) - The mint authority of the ORE token. - - -## Tests - -To run the test suite, use the Solana toolchain: - -``` -cargo test-sbf -``` - -For line coverage, use llvm-cov: - -``` -cargo llvm-cov -``` +## Programs +- [`ore`](ore/README.md.rs) – ORE mining program. +- [`ore-delegate`](ore-delegate/README.md.rs) – Delegate mining to another party. diff --git a/ore-delegate/README.md b/ore-delegate/README.md new file mode 100644 index 0000000..60493e5 --- /dev/null +++ b/ore-delegate/README.md @@ -0,0 +1,33 @@ +# ORE Delegate + +**Delegate mining to another party.** + +## API +- [`Consts`](api/src/consts.rs) – Program constants. +- [`Error`](api/src/error.rs) – Custom program errors. +- [`Event`](api/src/error.rs) – Custom program events. +- [`Instruction`](api/src/instruction.rs) – Declared instructions and arguments. + +## Instructions +- [`Deposit`](program/src/deposit.rs) - Deposit hash tokens. +- [`Withdraw`](program/src/withdraw.rs) - Withdraw hash tokens. +- [`Crank`](program/src/crank.rs) - Crank mine instructions. +- [`Payout`](program/src/payout.rs) - Payout mining rewards. + +## State +- [`Delegate`](api/src/state/delegate.rs) - Escrows hash tokens on behalf of a miner. + + +## Tests + +To run the test suite, use the Solana toolchain: + +``` +cargo test-sbf +``` + +For line coverage, use llvm-cov: + +``` +cargo llvm-cov +``` diff --git a/ore-delegate/api/Cargo.toml b/ore-delegate/api/Cargo.toml new file mode 100644 index 0000000..ab83669 --- /dev/null +++ b/ore-delegate/api/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "ore-delegate-api" +description.workspace = true +version.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +documentation.workspace = true +repository.workspace = true +keywords.workspace = true + +[dependencies] +bytemuck.workspace = true +const-crypto.workspace = true +mpl-token-metadata.workspace = true +num_enum.workspace = true +solana-program.workspace = true +spl-token.workspace = true +spl-associated-token-account.workspace = true +steel.workspace = true +thiserror.workspace = true diff --git a/ore-delegate/api/src/consts.rs b/ore-delegate/api/src/consts.rs new file mode 100644 index 0000000..045c6eb --- /dev/null +++ b/ore-delegate/api/src/consts.rs @@ -0,0 +1,2 @@ +/// The seed of the delegate account PDA. +pub const DELEGATE: &[u8] = b"delegate"; diff --git a/ore-delegate/api/src/error.rs b/ore-delegate/api/src/error.rs new file mode 100644 index 0000000..ace6867 --- /dev/null +++ b/ore-delegate/api/src/error.rs @@ -0,0 +1,10 @@ +use steel::*; + +#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)] +#[repr(u32)] +pub enum OreError { + #[error("Placeholder error")] + Dummy = 0, +} + +error!(OreError); diff --git a/ore-delegate/api/src/event.rs b/ore-delegate/api/src/event.rs new file mode 100644 index 0000000..ee7f90d --- /dev/null +++ b/ore-delegate/api/src/event.rs @@ -0,0 +1 @@ +use steel::*; diff --git a/ore-delegate/api/src/instruction.rs b/ore-delegate/api/src/instruction.rs new file mode 100644 index 0000000..9867b14 --- /dev/null +++ b/ore-delegate/api/src/instruction.rs @@ -0,0 +1,37 @@ +use steel::*; + +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)] +pub enum OreDelegateInstruction { + Deposit = 0, + Withdraw = 1, + Crank = 2, + Payout = 3, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct Deposit { + pub amount: [u8; 8], +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct Withdraw { + pub amount: [u8; 8], +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct Crank { + pub amount: [u8; 8], +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct Payout {} + +instruction!(OreDelegateInstruction, Deposit); +instruction!(OreDelegateInstruction, Withdraw); +instruction!(OreDelegateInstruction, Crank); +instruction!(OreDelegateInstruction, Payout); diff --git a/api/src/lib.rs b/ore-delegate/api/src/lib.rs similarity index 100% rename from api/src/lib.rs rename to ore-delegate/api/src/lib.rs diff --git a/ore-delegate/api/src/sdk.rs b/ore-delegate/api/src/sdk.rs new file mode 100644 index 0000000..c25624c --- /dev/null +++ b/ore-delegate/api/src/sdk.rs @@ -0,0 +1,3 @@ +use steel::*; + +use crate::{instruction::*, state::*}; diff --git a/ore-delegate/api/src/state/delegate.rs b/ore-delegate/api/src/state/delegate.rs new file mode 100644 index 0000000..b2c375a --- /dev/null +++ b/ore-delegate/api/src/state/delegate.rs @@ -0,0 +1,21 @@ +use steel::*; + +use super::OreDelegateAccount; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] +pub struct Delegate { + /// The authority of the delegate. + pub authority: Pubkey, + + /// The number of hash tokens deposited for mining. + pub balance: u64, + + /// The block these hash tokens are associated with. + pub block_id: u64, + + /// The fee to payout per crank (lamports). + pub fee: u64, +} + +account!(OreDelegateAccount, Delegate); diff --git a/ore-delegate/api/src/state/mod.rs b/ore-delegate/api/src/state/mod.rs new file mode 100644 index 0000000..5c2c8f2 --- /dev/null +++ b/ore-delegate/api/src/state/mod.rs @@ -0,0 +1,20 @@ +mod delegate; + +pub use delegate::*; + +use crate::consts::*; + +use steel::*; + +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)] +pub enum OreDelegateAccount { + Delegate = 100, +} + +pub fn delegate_pda(authority: Pubkey, block_id: u64) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[DELEGATE, &authority.to_bytes(), &block_id.to_le_bytes()], + &crate::ID, + ) +} diff --git a/ore-delegate/program/Cargo.toml b/ore-delegate/program/Cargo.toml new file mode 100644 index 0000000..e6541c6 --- /dev/null +++ b/ore-delegate/program/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "ore-delegate-program" +description.workspace = true +version.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +documentation.workspace = true +repository.workspace = true +readme.workspace = true +keywords.workspace = true + +[lib] +crate-type = ["cdylib", "lib"] +name = "ore_delegate" + +[features] +default = [] + +[dependencies] +bincode.workspace = true +mpl-token-metadata.workspace = true +ore-delegate-api.workspace = true +solana-program.workspace = true +spl-token.workspace = true +spl-token-2022.workspace = true +spl-associated-token-account.workspace = true +steel.workspace = true + +[dev-dependencies] +rand = "0.8.5" diff --git a/ore-delegate/program/src/crank.rs b/ore-delegate/program/src/crank.rs new file mode 100644 index 0000000..20a5cbb --- /dev/null +++ b/ore-delegate/program/src/crank.rs @@ -0,0 +1,155 @@ +use ore_delegate_api::prelude::*; +use solana_program::program_pack::Pack; +use spl_token_2022::instruction::AuthorityType; +use steel::*; + +/// Cranks a mining transaction. +pub fn process_crank(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { + // Parse data. + let args = Crank::try_from_bytes(data)?; + // let id = u64::from_le_bytes(args.id); + + // Load accounts. + // let [signer_info, block_info, market_info, mint_base_info, mint_quote_info, system_program, vault_base_info, vault_quote_info, token_program, associated_token_program, rent_sysvar] = + // accounts + // else { + // return Err(ProgramError::NotEnoughAccountKeys); + // }; + // signer_info.is_signer()?; + // block_info + // .is_empty()? + // .is_writable()? + // .has_seeds(&[BLOCK, &id.to_le_bytes()], &ore_api::ID)?; + // market_info + // .is_empty()? + // .is_writable()? + // .has_seeds(&[MARKET, &id.to_le_bytes()], &ore_api::ID)?; + // mint_base_info + // .is_empty()? + // .is_writable()? + // .has_seeds(&[MINT, &id.to_le_bytes()], &ore_api::ID)?; + // mint_quote_info.has_address(&MINT_ADDRESS)?.as_mint()?; + // system_program.is_program(&system_program::ID)?; + // token_program.is_program(&spl_token::ID)?; + // associated_token_program.is_program(&spl_associated_token_account::ID)?; + // rent_sysvar.is_sysvar(&sysvar::rent::ID)?; + + // // Initialize config. + // create_program_account::( + // block_info, + // system_program, + // signer_info, + // &ore_api::ID, + // &[BLOCK, &id.to_le_bytes()], + // )?; + // let block = block_info.as_account_mut::(&ore_api::ID)?; + // block.best_hash = [0; 32]; + // block.best_miner = Pubkey::default(); + // block.id = id; + // block.reward = ONE_ORE * 10; + // block.slot_hash = [0; 32]; + // block.start_slot = 1500 * id; + + // // Initialize market. + // create_program_account::( + // market_info, + // system_program, + // signer_info, + // &ore_api::ID, + // &[MARKET, &id.to_le_bytes()], + // )?; + // let market = market_info.as_account_mut::(&ore_api::ID)?; + // market.base = TokenParams { + // mint: *mint_base_info.key, + // balance: HASH_TOKEN_SUPPLY, + // balance_virtual: 0, + // }; + // market.quote = TokenParams { + // mint: *mint_quote_info.key, + // balance: 0, + // balance_virtual: ONE_ORE, + // }; + // market.fee = FeeParams { + // rate: FEE_RATE_BPS, + // uncollected: 0, + // cumulative: 0, + // }; + // market.snapshot = Snapshot { + // enabled: 1, + // base_balance: 0, + // quote_balance: 0, + // slot: 0, + // }; + // market.id = id; + + // // Initialize hash token mint. + // allocate_account( + // mint_base_info, + // system_program, + // signer_info, + // spl_token::state::Mint::LEN, + // &spl_token::ID, + // &[MINT, &id.to_le_bytes()], + // )?; + // initialize_mint_signed( + // mint_base_info, + // block_info, + // None, + // token_program, + // rent_sysvar, + // 0, + // &[MINT, &id.to_le_bytes()], + // )?; + + // // TODO Initialize hash token metadata. + + // // Initialize vault token accounts. + // if vault_base_info.data_is_empty() { + // create_associated_token_account( + // signer_info, + // market_info, + // vault_base_info, + // mint_base_info, + // system_program, + // token_program, + // associated_token_program, + // )?; + // } else { + // vault_base_info.as_associated_token_account(market_info.key, mint_base_info.key)?; + // } + // if vault_quote_info.data_is_empty() { + // create_associated_token_account( + // signer_info, + // market_info, + // vault_quote_info, + // mint_quote_info, + // system_program, + // token_program, + // associated_token_program, + // )?; + // } else { + // vault_quote_info.as_associated_token_account(market_info.key, mint_quote_info.key)?; + // } + + // // Mint hash tokens to market. + // mint_to_signed( + // mint_base_info, + // vault_base_info, + // block_info, + // token_program, + // HASH_TOKEN_SUPPLY, + // &[BLOCK, &id.to_le_bytes()], + // )?; + + // // Burn mint authority. + // set_authority_signed( + // mint_base_info, + // block_info, + // None, + // AuthorityType::MintTokens, + // token_program, + // &[BLOCK, &id.to_le_bytes()], + // )?; + + Ok(()) +} diff --git a/ore-delegate/program/src/deposit.rs b/ore-delegate/program/src/deposit.rs new file mode 100644 index 0000000..8e45aaa --- /dev/null +++ b/ore-delegate/program/src/deposit.rs @@ -0,0 +1,69 @@ +use ore_delegate_api::prelude::*; +use steel::*; + +/// Deposits hash tokens for cranking. +pub fn process_deposit(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { + // Load accounts. + // let clock = Clock::get()?; + // let [signer_info, block_info, market_info, mint_base_info, mint_quote_info, recipient_info, treasury_info, vault_base_info, vault_quote_info, system_program, token_program] = + // accounts + // else { + // return Err(ProgramError::NotEnoughAccountKeys); + // }; + // signer_info.is_signer()?; + // let block = block_info + // .as_account_mut::(&ore_api::ID)? + // .assert_mut(|b| clock.slot >= b.start_slot + 1500)?; + // let market = market_info + // .as_account_mut::(&ore_api::ID)? + // .assert_mut(|m| m.id == block.id)?; + // mint_base_info.has_address(&market.base.mint)?.as_mint()?; + // mint_quote_info.has_address(&market.quote.mint)?.as_mint()?; + // let vault_base = + // vault_base_info.as_associated_token_account(market_info.key, mint_base_info.key)?; + // let vault_quote = + // vault_quote_info.as_associated_token_account(market_info.key, mint_quote_info.key)?; + // system_program.is_program(&system_program::ID)?; + // token_program.is_program(&spl_token::ID)?; + + // // Payout block reward. + // if block.best_miner != Pubkey::default() { + // recipient_info.as_associated_token_account(&block.best_miner, &MINT_ADDRESS)?; + // mint_to_signed( + // mint_quote_info, + // recipient_info, + // treasury_info, + // token_program, + // block.reward, + // &[TREASURY], + // )?; + // } + + // // Burn base liquidity. + // burn_signed( + // vault_base_info, + // mint_base_info, + // market_info, + // token_program, + // vault_base.amount(), + // &[MARKET, &market.id.to_le_bytes()], + // )?; + + // // Burn quote liquidity. + // burn_signed( + // vault_quote_info, + // mint_quote_info, + // market_info, + // token_program, + // vault_quote.amount(), + // &[MARKET, &market.id.to_le_bytes()], + // )?; + + // // Close block. + // block_info.close(signer_info)?; + + // // Close market. + // market_info.close(signer_info)?; + + Ok(()) +} diff --git a/ore-delegate/program/src/lib.rs b/ore-delegate/program/src/lib.rs new file mode 100644 index 0000000..05e5ea3 --- /dev/null +++ b/ore-delegate/program/src/lib.rs @@ -0,0 +1,31 @@ +mod crank; +mod deposit; +mod payout; +mod withdraw; + +use crank::*; +use deposit::*; +use payout::*; +use withdraw::*; + +use ore_delegate_api::instruction::*; +use steel::*; + +pub fn process_instruction( + program_id: &Pubkey, + accounts: &[AccountInfo], + data: &[u8], +) -> ProgramResult { + let (ix, data) = parse_instruction(&ore_delegate_api::ID, program_id, data)?; + + match ix { + OreDelegateInstruction::Deposit => process_deposit(accounts, data)?, + OreDelegateInstruction::Withdraw => process_withdraw(accounts, data)?, + OreDelegateInstruction::Crank => process_crank(accounts, data)?, + OreDelegateInstruction::Payout => process_payout(accounts, data)?, + } + + Ok(()) +} + +entrypoint!(process_instruction); diff --git a/ore-delegate/program/src/payout.rs b/ore-delegate/program/src/payout.rs new file mode 100644 index 0000000..482097b --- /dev/null +++ b/ore-delegate/program/src/payout.rs @@ -0,0 +1,99 @@ +use ore_delegate_api::prelude::*; +use steel::*; + +/// Payouts a block reward. +pub fn process_payout(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { + // Parse args. + // let args = Payout::try_from_bytes(data)?; + // let amount = u64::from_le_bytes(args.amount); + // let direction = PayoutDirection::try_from(args.direction).unwrap(); + // let precision = PayoutPrecision::try_from(args.precision).unwrap(); + + // // Load accounts. + // let clock = Clock::get()?; + // let [signer_info, block_info, market_info, mint_base_info, mint_quote_info, tokens_base_info, tokens_quote_info, vault_base_info, vault_quote_info, system_program, token_program] = + // accounts + // else { + // return Err(ProgramError::NotEnoughAccountKeys); + // }; + // signer_info.is_signer()?; + // let block = block_info + // .as_account_mut::(&ore_api::ID)? + // .assert_mut(|b| clock.slot >= b.start_slot + 1500)?; + // let market = market_info + // .as_account_mut::(&ore_api::ID)? + // .assert_mut(|m| m.id == block.id)? + // .assert_mut_err( + // |m| m.base.liquidity() > 0, + // OreError::InsufficientLiquidity.into(), + // )? + // .assert_mut_err( + // |m| m.quote.liquidity() > 0, + // OreError::InsufficientLiquidity.into(), + // )?; + // mint_base_info.has_address(&market.base.mint)?.as_mint()?; + // mint_quote_info.has_address(&market.quote.mint)?.as_mint()?; + // tokens_base_info + // .is_writable()? + // .as_associated_token_account(signer_info.key, mint_base_info.key)?; + // tokens_quote_info + // .is_writable()? + // .as_associated_token_account(signer_info.key, mint_quote_info.key)?; + // vault_base_info + // .is_writable()? + // .as_associated_token_account(market_info.key, mint_base_info.key)?; + // vault_quote_info + // .is_writable()? + // .as_associated_token_account(market_info.key, mint_quote_info.key)?; + // system_program.is_program(&system_program::ID)?; + // token_program.is_program(&spl_token::ID)?; + + // // Update market state. + // let swap_result = market.swap(amount, direction, precision, clock)?; + // swap_result.log_return(); + + // // Get transfer amounts and accounts. + // let (in_amount, in_from, in_to, out_amount, out_from, out_to) = match direction { + // SwapDirection::Buy => ( + // swap_result.quote_to_transfer, + // tokens_quote_info, + // vault_quote_info, + // swap_result.base_to_transfer, + // vault_base_info, + // tokens_base_info, + // ), + // SwapDirection::Sell => ( + // swap_result.base_to_transfer, + // tokens_base_info, + // vault_base_info, + // swap_result.quote_to_transfer, + // vault_quote_info, + // tokens_quote_info, + // ), + // }; + + // // Transfer tokens. + // transfer(signer_info, in_from, in_to, token_program, in_amount)?; + // transfer_signed( + // market_info, + // out_from, + // out_to, + // token_program, + // out_amount, + // &[ + // MARKET, + // market.base.mint.as_ref(), + // market.quote.mint.as_ref(), + // market.id.to_le_bytes().as_ref(), + // ], + // )?; + + // // Validate vault reserves. + // let vault_base = + // vault_base_info.as_associated_token_account(market_info.key, mint_base_info.key)?; + // let vault_quote = + // vault_quote_info.as_associated_token_account(market_info.key, mint_quote_info.key)?; + // market.check_vaults(&vault_base, &vault_quote)?; + + Ok(()) +} diff --git a/ore-delegate/program/src/withdraw.rs b/ore-delegate/program/src/withdraw.rs new file mode 100644 index 0000000..9495d05 --- /dev/null +++ b/ore-delegate/program/src/withdraw.rs @@ -0,0 +1,79 @@ +use ore_delegate_api::prelude::*; +use solana_program::keccak; +use steel::*; + +/// Withdraws hash tokens from the delegate. +pub fn process_withdraw(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { + // Parse data. + let args = Withdraw::try_from_bytes(data)?; + let amount = u64::from_le_bytes(args.amount); + + // Load accounts. + // let clock = Clock::get()?; + // let [signer_info, block_info, market_info, miner_info, mint_info, sender_info, system_program, token_program] = + // accounts + // else { + // return Err(ProgramError::NotEnoughAccountKeys); + // }; + // signer_info.is_signer()?; + // let block = block_info + // .as_account_mut::(&ore_api::ID)? + // .assert_mut(|b| clock.slot >= b.start_slot)? + // .assert_mut(|b| clock.slot < b.start_slot + 1500)?; + // let market = market_info + // .as_account::(&ore_api::ID)? + // .assert(|m| m.id == block.id)?; + // mint_info.has_address(&market.base.mint)?.as_mint()?; + // sender_info + // .is_writable()? + // .as_associated_token_account(signer_info.key, &mint_info.key)? + // .assert(|t| t.amount() >= amount)?; + // system_program.is_program(&system_program::ID)?; + // token_program.is_program(&spl_token::ID)?; + + // // Load miner account. + // let miner = if miner_info.data_is_empty() { + // create_program_account::( + // miner_info, + // system_program, + // signer_info, + // &ore_api::ID, + // &[MINER, &signer_info.key.to_bytes()], + // )?; + // let miner = miner_info.as_account_mut::(&ore_api::ID)?; + // miner.authority = *signer_info.key; + // miner.block_id = 0; + // miner.hash = [0; 32]; + // miner.total_hashes = 0; + // miner.total_rewards = 0; + // miner + // } else { + // miner_info + // .as_account_mut::(&ore_api::ID)? + // .assert_mut(|m| m.authority == *signer_info.key)? + // }; + + // // Reset miner hash if mining new block. + // if miner.block_id != block.id { + // miner.block_id = block.id; + // miner.hash = + // keccak::hashv(&[block.slot_hash.as_ref(), miner.authority.as_ref()]).to_bytes(); + // } + + // // Mine. + // for _ in 0..amount { + // miner.hash = keccak::hashv(&[miner.hash.as_ref()]).to_bytes(); + // if miner.hash < block.best_hash { + // block.best_hash = miner.hash; + // block.best_miner = miner.authority; + // } + // } + + // // Update miner stats. + // miner.total_hashes += amount; + + // // Burn hash tokens. + // burn(sender_info, mint_info, signer_info, token_program, amount)?; + + Ok(()) +} diff --git a/ore/README.md b/ore/README.md new file mode 100644 index 0000000..93183f6 --- /dev/null +++ b/ore/README.md @@ -0,0 +1,38 @@ +# ORE + +**Mine blockspace. Trade hashpower. Win rewards.** + +## API +- [`Consts`](api/src/consts.rs) – Program constants. +- [`Error`](api/src/error.rs) – Custom program errors. +- [`Event`](api/src/error.rs) – Custom program events. +- [`Instruction`](api/src/instruction.rs) – Declared instructions and arguments. + +## Instructions + +- [`Open`](program/src/open.rs) - Open a new block. +- [`Close`](program/src/close.rs) - Close a block and pay out the reward. +- [`Mine`](program/src/mine.rs) - Mine the current block. +- [`Swap`](program/src/swap.rs) - Trade in a hashpower market. + +## State +- [`Block`](api/src/state/block.rs) - A period of time for mining. +- [`Config`](api/src/state/config.rs) - Global program configuration. +- [`Market`](api/src/state/market.rs) - Hashpower market for a given block. +- [`Miner`](api/src/state/miner.rs) - Tracks a miner state and history. +- [`Treasury`](api/src/state/treasury.rs) - The mint authority of the ORE token. + + +## Tests + +To run the test suite, use the Solana toolchain: + +``` +cargo test-sbf +``` + +For line coverage, use llvm-cov: + +``` +cargo llvm-cov +``` diff --git a/api/Cargo.toml b/ore/api/Cargo.toml similarity index 100% rename from api/Cargo.toml rename to ore/api/Cargo.toml diff --git a/api/src/consts.rs b/ore/api/src/consts.rs similarity index 100% rename from api/src/consts.rs rename to ore/api/src/consts.rs diff --git a/api/src/error.rs b/ore/api/src/error.rs similarity index 100% rename from api/src/error.rs rename to ore/api/src/error.rs diff --git a/api/src/event.rs b/ore/api/src/event.rs similarity index 100% rename from api/src/event.rs rename to ore/api/src/event.rs diff --git a/api/src/instruction.rs b/ore/api/src/instruction.rs similarity index 100% rename from api/src/instruction.rs rename to ore/api/src/instruction.rs diff --git a/ore/api/src/lib.rs b/ore/api/src/lib.rs new file mode 100644 index 0000000..7c83341 --- /dev/null +++ b/ore/api/src/lib.rs @@ -0,0 +1,18 @@ +pub mod consts; +pub mod error; +pub mod event; +pub mod instruction; +pub mod sdk; +pub mod state; + +pub mod prelude { + pub use crate::consts::*; + pub use crate::error::*; + pub use crate::event::*; + pub use crate::instruction::*; + pub use crate::state::*; +} + +use steel::*; + +declare_id!("oreV2ZymfyeXgNgBdqMkumTqqAprVqgBWQfoYkrtKWQ"); diff --git a/api/src/sdk.rs b/ore/api/src/sdk.rs similarity index 100% rename from api/src/sdk.rs rename to ore/api/src/sdk.rs diff --git a/api/src/state/block.rs b/ore/api/src/state/block.rs similarity index 100% rename from api/src/state/block.rs rename to ore/api/src/state/block.rs diff --git a/api/src/state/config.rs b/ore/api/src/state/config.rs similarity index 100% rename from api/src/state/config.rs rename to ore/api/src/state/config.rs diff --git a/api/src/state/market/buy_exact_in.rs b/ore/api/src/state/market/buy_exact_in.rs similarity index 100% rename from api/src/state/market/buy_exact_in.rs rename to ore/api/src/state/market/buy_exact_in.rs diff --git a/api/src/state/market/buy_exact_out.rs b/ore/api/src/state/market/buy_exact_out.rs similarity index 100% rename from api/src/state/market/buy_exact_out.rs rename to ore/api/src/state/market/buy_exact_out.rs diff --git a/api/src/state/market/curve.rs b/ore/api/src/state/market/curve.rs similarity index 100% rename from api/src/state/market/curve.rs rename to ore/api/src/state/market/curve.rs diff --git a/api/src/state/market/fees.rs b/ore/api/src/state/market/fees.rs similarity index 100% rename from api/src/state/market/fees.rs rename to ore/api/src/state/market/fees.rs diff --git a/api/src/state/market/market.rs b/ore/api/src/state/market/market.rs similarity index 100% rename from api/src/state/market/market.rs rename to ore/api/src/state/market/market.rs diff --git a/api/src/state/market/mod.rs b/ore/api/src/state/market/mod.rs similarity index 100% rename from api/src/state/market/mod.rs rename to ore/api/src/state/market/mod.rs diff --git a/api/src/state/market/sell_exact_in.rs b/ore/api/src/state/market/sell_exact_in.rs similarity index 100% rename from api/src/state/market/sell_exact_in.rs rename to ore/api/src/state/market/sell_exact_in.rs diff --git a/api/src/state/market/sell_exact_out.rs b/ore/api/src/state/market/sell_exact_out.rs similarity index 100% rename from api/src/state/market/sell_exact_out.rs rename to ore/api/src/state/market/sell_exact_out.rs diff --git a/api/src/state/market/swap.rs b/ore/api/src/state/market/swap.rs similarity index 100% rename from api/src/state/market/swap.rs rename to ore/api/src/state/market/swap.rs diff --git a/api/src/state/market/vaults.rs b/ore/api/src/state/market/vaults.rs similarity index 100% rename from api/src/state/market/vaults.rs rename to ore/api/src/state/market/vaults.rs diff --git a/api/src/state/market/virtual_limit_order.rs b/ore/api/src/state/market/virtual_limit_order.rs similarity index 100% rename from api/src/state/market/virtual_limit_order.rs rename to ore/api/src/state/market/virtual_limit_order.rs diff --git a/api/src/state/miner.rs b/ore/api/src/state/miner.rs similarity index 100% rename from api/src/state/miner.rs rename to ore/api/src/state/miner.rs diff --git a/api/src/state/mod.rs b/ore/api/src/state/mod.rs similarity index 100% rename from api/src/state/mod.rs rename to ore/api/src/state/mod.rs diff --git a/api/src/state/treasury.rs b/ore/api/src/state/treasury.rs similarity index 100% rename from api/src/state/treasury.rs rename to ore/api/src/state/treasury.rs diff --git a/program/Cargo.toml b/ore/program/Cargo.toml similarity index 100% rename from program/Cargo.toml rename to ore/program/Cargo.toml diff --git a/program/src/close.rs b/ore/program/src/close.rs similarity index 100% rename from program/src/close.rs rename to ore/program/src/close.rs diff --git a/program/src/lib.rs b/ore/program/src/lib.rs similarity index 100% rename from program/src/lib.rs rename to ore/program/src/lib.rs diff --git a/program/src/mine.rs b/ore/program/src/mine.rs similarity index 100% rename from program/src/mine.rs rename to ore/program/src/mine.rs diff --git a/program/src/open.rs b/ore/program/src/open.rs similarity index 100% rename from program/src/open.rs rename to ore/program/src/open.rs diff --git a/program/src/swap.rs b/ore/program/src/swap.rs similarity index 100% rename from program/src/swap.rs rename to ore/program/src/swap.rs diff --git a/security/fuzzland-audit.pdf b/security/fuzzland-audit.pdf deleted file mode 100644 index 0ba7d6e..0000000 Binary files a/security/fuzzland-audit.pdf and /dev/null differ diff --git a/security/ottersec-audit.pdf b/security/ottersec-audit.pdf deleted file mode 100644 index 05e1235..0000000 Binary files a/security/ottersec-audit.pdf and /dev/null differ