#![deny(rustdoc::all)]
#![allow(rustdoc::missing_doc_code_examples)]
#![allow(deprecated)]
use anchor_lang::prelude::*;
use quarry_mine::{Quarry, Rewarder};
use vipers::prelude::*;
mod account_validators;
mod instructions;
mod macros;
mod state;
use instructions::*;
pub use state::*;
declare_id!("QoP6NfrQbaGnccXQrMLUkog2tQZ4C1RFgJcwDnT8Kmz");
#[cfg(not(feature = "no-entrypoint"))]
solana_security_txt::security_txt! {
name: "Quarry Operator",
project_url: "https://quarry.so",
contacts: "email:team@quarry.so",
policy: "https://github.com/QuarryProtocol/quarry/blob/master/SECURITY.md",
source_code: "https://github.com/QuarryProtocol/quarry",
auditors: "Quantstamp"
}
#[program]
pub mod quarry_operator {
use super::*;
#[deprecated(since = "5.0.0", note = "Use `create_operator_v2` instead.")]
#[access_control(ctx.accounts.validate())]
pub fn create_operator(ctx: Context<CreateOperator>, _bump: u8) -> Result<()> {
instructions::create_operator::handler(ctx)
}
#[access_control(ctx.accounts.validate())]
pub fn create_operator_v2(ctx: Context<CreateOperator>) -> Result<()> {
instructions::create_operator::handler(ctx)
}
#[access_control(ctx.accounts.validate())]
pub fn set_admin(ctx: Context<SetRole>) -> Result<()> {
let operator = &mut ctx.accounts.operator;
operator.admin = ctx.accounts.delegate.key();
operator.record_update()?;
Ok(())
}
#[access_control(ctx.accounts.validate())]
pub fn set_rate_setter(ctx: Context<SetRole>) -> Result<()> {
let operator = &mut ctx.accounts.operator;
operator.rate_setter = ctx.accounts.delegate.key();
operator.record_update()?;
Ok(())
}
#[access_control(ctx.accounts.validate())]
pub fn set_quarry_creator(ctx: Context<SetRole>) -> Result<()> {
let operator = &mut ctx.accounts.operator;
operator.quarry_creator = ctx.accounts.delegate.key();
operator.record_update()?;
Ok(())
}
#[access_control(ctx.accounts.validate())]
pub fn set_share_allocator(ctx: Context<SetRole>) -> Result<()> {
let operator = &mut ctx.accounts.operator;
operator.share_allocator = ctx.accounts.delegate.key();
operator.record_update()?;
Ok(())
}
#[access_control(ctx.accounts.validate())]
pub fn delegate_set_annual_rewards(
ctx: Context<DelegateSetAnnualRewards>,
new_rate: u64,
) -> Result<()> {
let operator = &ctx.accounts.with_delegate.operator;
let signer_seeds: &[&[&[u8]]] = &[gen_operator_signer_seeds!(operator)];
quarry_mine::cpi::set_annual_rewards(
CpiContext::new_with_signer(
ctx.accounts
.with_delegate
.quarry_mine_program
.to_account_info(),
quarry_mine::cpi::accounts::SetAnnualRewards {
auth: ctx.accounts.with_delegate.to_auth_accounts(),
},
signer_seeds,
),
new_rate,
)?;
Ok(())
}
#[access_control(ctx.accounts.validate())]
pub fn delegate_create_quarry(ctx: Context<DelegateCreateQuarry>, _bump: u8) -> Result<()> {
instructions::delegate_create_quarry::handler(ctx)
}
#[access_control(ctx.accounts.validate())]
pub fn delegate_create_quarry_v2(ctx: Context<DelegateCreateQuarryV2>) -> Result<()> {
instructions::delegate_create_quarry_v2::handler(ctx)
}
#[access_control(ctx.accounts.validate())]
pub fn delegate_set_rewards_share(
ctx: Context<DelegateSetRewardsShare>,
new_share: u64,
) -> Result<()> {
let operator = &ctx.accounts.with_delegate.operator;
let signer_seeds: &[&[&[u8]]] = &[gen_operator_signer_seeds!(operator)];
quarry_mine::cpi::set_rewards_share(
CpiContext::new_with_signer(
ctx.accounts
.with_delegate
.quarry_mine_program
.to_account_info(),
quarry_mine::cpi::accounts::SetRewardsShare {
auth: ctx.accounts.with_delegate.to_auth_accounts(),
quarry: ctx.accounts.quarry.to_account_info(),
},
signer_seeds,
),
new_share,
)?;
Ok(())
}
#[access_control(ctx.accounts.validate())]
pub fn delegate_set_famine(ctx: Context<DelegateSetFamine>, famine_ts: i64) -> Result<()> {
let operator = &ctx.accounts.with_delegate.operator;
let signer_seeds: &[&[&[u8]]] = &[gen_operator_signer_seeds!(operator)];
quarry_mine::cpi::set_famine(
CpiContext::new_with_signer(
ctx.accounts
.with_delegate
.quarry_mine_program
.to_account_info(),
quarry_mine::cpi::accounts::SetFamine {
auth: ctx.accounts.with_delegate.to_readonly_auth_accounts(),
quarry: ctx.accounts.quarry.to_account_info(),
},
signer_seeds,
),
famine_ts,
)
}
}
#[derive(Accounts)]
pub struct SetRole<'info> {
#[account(mut)]
pub operator: Account<'info, Operator>,
pub admin: Signer<'info>,
pub delegate: UncheckedAccount<'info>,
}
#[derive(Accounts)]
pub struct DelegateSetAnnualRewards<'info> {
pub with_delegate: WithDelegate<'info>,
}
#[derive(Accounts)]
pub struct DelegateSetRewardsShare<'info> {
pub with_delegate: WithDelegate<'info>,
#[account(
mut,
constraint = quarry.rewarder == with_delegate.rewarder.key()
)]
pub quarry: Account<'info, Quarry>,
}
#[derive(Accounts)]
pub struct DelegateSetFamine<'info> {
pub with_delegate: WithDelegate<'info>,
#[account(
mut,
constraint = quarry.rewarder == with_delegate.rewarder.key()
)]
pub quarry: Account<'info, Quarry>,
}
#[derive(Accounts, Clone)]
pub struct WithDelegate<'info> {
#[account(mut, has_one = rewarder)]
pub operator: Account<'info, Operator>,
pub delegate: Signer<'info>,
#[account(
mut,
constraint = rewarder.authority == operator.key() @ ErrorCode::OperatorNotRewarderAuthority
)]
pub rewarder: Account<'info, Rewarder>,
pub quarry_mine_program: Program<'info, quarry_mine::program::QuarryMine>,
}
impl<'info> WithDelegate<'info> {
pub fn to_auth_accounts(
&self,
) -> quarry_mine::cpi::accounts::MutableRewarderWithAuthority<'info> {
quarry_mine::cpi::accounts::MutableRewarderWithAuthority {
authority: self.operator.to_account_info(),
rewarder: self.rewarder.to_account_info(),
}
}
pub fn to_readonly_auth_accounts(
&self,
) -> quarry_mine::cpi::accounts::ReadOnlyRewarderWithAuthority<'info> {
quarry_mine::cpi::accounts::ReadOnlyRewarderWithAuthority {
authority: self.operator.to_account_info(),
rewarder: self.rewarder.to_account_info(),
}
}
}
#[error_code]
pub enum ErrorCode {
#[msg("Signer is not authorized to perform this action.")]
Unauthorized,
#[msg("Pending authority must be set to the created operator.")]
PendingAuthorityNotSet,
#[msg("Operator is not the Rewarder authority.")]
OperatorNotRewarderAuthority,
}