diff --git a/Anchor.toml b/Anchor.toml index e69f6f9f..4d612b9a 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -29,6 +29,9 @@ assign-permissionless-account = "yarn run tsx scripts/assignPermissionlessAccoun create-v04-proposal = "yarn run tsx scripts/createV04Proposal.ts" initialize-launch = "yarn run tsx scripts/initializeLaunch.ts" test = "npx mocha --import=tsx --bail tests/main.test.ts" +execute-spending-limit = "yarn run tsx scripts/executeSpendingLimit.ts" +upgrade-dao = "yarn run tsx scripts/upgradeDao.ts" +convert = "yarn run tsx scripts/convertpk.ts" [test] startup_wait = 5000 diff --git a/programs/autocrat/src/error.rs b/programs/autocrat/src/error.rs index f0a8be96..d9944bb0 100644 --- a/programs/autocrat/src/error.rs +++ b/programs/autocrat/src/error.rs @@ -34,4 +34,6 @@ pub enum AutocratError { QuestionMustBeBinary, #[msg("Squads proposal must be in Draft status")] InvalidSquadsProposalStatus, + #[msg("This Squads transaction should only contain calls to update spending limits")] + InvalidTransaction, } diff --git a/programs/autocrat/src/instructions/execute_spending_limit_change.rs b/programs/autocrat/src/instructions/execute_spending_limit_change.rs new file mode 100644 index 00000000..58adf293 --- /dev/null +++ b/programs/autocrat/src/instructions/execute_spending_limit_change.rs @@ -0,0 +1,91 @@ +use super::*; + +use anchor_lang::Discriminator; +use squads_multisig_program::program::SquadsMultisigProgram; + +#[derive(Accounts)] +#[event_cpi] +pub struct ExecuteSpendingLimitChange<'info> { + #[account( + mut, has_one = dao, has_one = squads_proposal, + )] + pub proposal: Box>, + #[account(mut, has_one = squads_multisig)] + pub dao: Box>, + /// CHECK: checked by squads multisig program + #[account(mut)] + pub squads_proposal: Account<'info, squads_multisig_program::Proposal>, + #[account(address = vault_transaction.multisig)] + pub squads_multisig: Account<'info, squads_multisig_program::Multisig>, + pub squads_multisig_program: Program<'info, SquadsMultisigProgram>, + pub vault_transaction: Account<'info, squads_multisig_program::VaultTransaction>, +} + +impl<'info, 'c: 'info> ExecuteSpendingLimitChange<'info> { + pub fn validate(&self) -> Result<()> { + require_eq!(self.proposal.state, ProposalState::Passed); + + Ok(()) + } + + pub fn handle(ctx: Context<'_, '_, 'c, 'info, Self>) -> Result<()> { + let Self { + proposal: _, + dao, + squads_proposal, + squads_multisig, + squads_multisig_program, + vault_transaction, + event_authority: _, + program: _, + } = ctx.accounts; + + let message = &vault_transaction.message; + + // it would be bad if we signed with the Dao and then they ran off and did something else + // with it. so we verify that the only instructions are calls to update spending limits on + // the squads program + let squads_program_key_index: u8 = message + .account_keys + .iter() + .position(|key| key == &squads_multisig_program.key()) + .ok_or(error!(AutocratError::InvalidTransaction))? + .try_into() + .or_else(|_| Err(error!(AutocratError::InvalidTransaction)))?; + + for instruction in message.instructions.iter() { + require_eq!( + instruction.program_id_index, + squads_program_key_index, + AutocratError::InvalidTransaction + ); + + let discriminator: [u8; 8] = instruction.data[0..8].try_into().unwrap(); + if discriminator != squads_multisig_program::instruction::MultisigAddSpendingLimit::DISCRIMINATOR && + discriminator != squads_multisig_program::instruction::MultisigRemoveSpendingLimit::DISCRIMINATOR { + return Err(error!(AutocratError::InvalidTransaction)); + } + } + + let dao_nonce = &dao.nonce.to_le_bytes(); + let dao_creator_key = &dao.dao_creator.as_ref(); + let dao_seeds = &[b"dao".as_ref(), dao_creator_key, dao_nonce, &[dao.pda_bump]]; + let dao_signer = &[&dao_seeds[..]]; + + squads_multisig_program::cpi::vault_transaction_execute( + CpiContext::new_with_signer( + squads_multisig_program.to_account_info(), + squads_multisig_program::cpi::accounts::VaultTransactionExecute { + multisig: squads_multisig.to_account_info(), + proposal: squads_proposal.to_account_info(), + transaction: vault_transaction.to_account_info(), + member: dao.to_account_info(), + }, + dao_signer, + ) + .with_remaining_accounts((&ctx.remaining_accounts).to_vec()), + )?; + + Ok(()) + } +} diff --git a/programs/autocrat/src/instructions/fix_omnipair_spending_limit.rs b/programs/autocrat/src/instructions/fix_omnipair_spending_limit.rs new file mode 100644 index 00000000..58ff16cc --- /dev/null +++ b/programs/autocrat/src/instructions/fix_omnipair_spending_limit.rs @@ -0,0 +1,109 @@ +use super::*; + +use squads_multisig_program::{program::SquadsMultisigProgram, Member, Multisig, MultisigAddSpendingLimitArgs, MultisigRemoveSpendingLimitArgs, Period, Permission, Permissions, SpendingLimit}; + +pub mod kollan_address { + use anchor_lang::prelude::declare_id; + declare_id!("tSTp6B6kE9o6ZaTmHm2ZwnJBBtgd3x112tapxFhmBEQ"); +} + +pub mod omnpair_dao { + use anchor_lang::prelude::declare_id; + + declare_id!("B3AufDZCDtQN8JxZgJ5bSDZaiKCF4vtw7ynN9tuR9pXN"); +} + +pub mod omnipair_spending_limit { + use anchor_lang::prelude::declare_id; + + declare_id!("5gn6mBnPqp4AQUXyanadwcse8eVqUNFxnc2zrKJV8kCn"); +} + +pub mod rakka_address { + use anchor_lang::prelude::declare_id; + + declare_id!("5jRqFejxKHWMfR69dbYF2A9TnpnBPjz7iaRQS44imcMi"); +} + +#[derive(Accounts)] +pub struct FixOmnipairSpendingLimit<'info> { + #[account(mut, has_one = squads_multisig, address = omnpair_dao::id())] + pub dao: Box>, + #[account(mut)] + pub squads_multisig: Account<'info, Multisig>, + pub squads_multisig_program: Program<'info, SquadsMultisigProgram>, + #[account(mut)] + pub rent_payer: Signer<'info>, + pub kollan: Signer<'info>, + #[account(mut, address = omnipair_spending_limit::id())] + pub omnipair_spending_limit: Account<'info, SpendingLimit>, + pub system_program: Program<'info, System>, +} + +impl FixOmnipairSpendingLimit<'_> { + pub fn validate(&self) -> Result<()> { + // #[cfg(feature = "production")] + require_eq!(self.kollan.key(), kollan_address::id()); + + Ok(()) + } + + pub fn handle(ctx: Context) -> Result<()> { + let Self { + dao, + squads_multisig, + squads_multisig_program, + rent_payer, + kollan: _, + system_program, + omnipair_spending_limit, + } = ctx.accounts; + + let dao_nonce = &dao.nonce.to_le_bytes(); + let dao_creator_key = &dao.dao_creator.as_ref(); + let dao_seeds = &[b"dao".as_ref(), dao_creator_key, dao_nonce, &[dao.pda_bump]]; + let dao_signer = &[&dao_seeds[..]]; + + squads_multisig_program::cpi::multisig_remove_spending_limit( + CpiContext::new_with_signer( + squads_multisig_program.to_account_info(), + squads_multisig_program::cpi::accounts::MultisigRemoveSpendingLimit { + multisig: squads_multisig.to_account_info(), + config_authority: dao.to_account_info(), + spending_limit: omnipair_spending_limit.to_account_info(), + rent_collector: rent_payer.to_account_info(), + }, + dao_signer, + ), + MultisigRemoveSpendingLimitArgs { + memo: None, + } + )?; + + squads_multisig_program::cpi::multisig_add_spending_limit( + CpiContext::new_with_signer( + squads_multisig_program.to_account_info(), + squads_multisig_program::cpi::accounts::MultisigAddSpendingLimit { + multisig: squads_multisig.to_account_info(), + config_authority: dao.to_account_info(), + spending_limit: omnipair_spending_limit.to_account_info(), + rent_payer: rent_payer.to_account_info(), + system_program: system_program.to_account_info(), + }, + dao_signer, + ), + MultisigAddSpendingLimitArgs { + memo: None, + create_key: dao.key(), + vault_index: 0, + mint: dao.quote_mint, + amount: 50_000 * 1_000_000, + period: Period::Month, + members: vec![rakka_address::id()], + destinations: vec![], + } + )?; + + Ok(()) + } +} diff --git a/programs/autocrat/src/instructions/mod.rs b/programs/autocrat/src/instructions/mod.rs index ea7c06b4..2abbbf2a 100644 --- a/programs/autocrat/src/instructions/mod.rs +++ b/programs/autocrat/src/instructions/mod.rs @@ -4,8 +4,14 @@ pub mod finalize_proposal; pub mod initialize_dao; pub mod initialize_proposal; pub mod update_dao; +pub mod execute_spending_limit_change; +pub mod upgrade_multisig_dao; +pub mod fix_omnipair_spending_limit; pub use finalize_proposal::*; pub use initialize_dao::*; pub use initialize_proposal::*; pub use update_dao::*; +pub use execute_spending_limit_change::*; +pub use upgrade_multisig_dao::*; +pub use fix_omnipair_spending_limit::*; diff --git a/programs/autocrat/src/instructions/upgrade_multisig_dao.rs b/programs/autocrat/src/instructions/upgrade_multisig_dao.rs new file mode 100644 index 00000000..7b15ffa4 --- /dev/null +++ b/programs/autocrat/src/instructions/upgrade_multisig_dao.rs @@ -0,0 +1,122 @@ +use super::*; + +use squads_multisig_program::{program::SquadsMultisigProgram, Member, MultisigAddMemberArgs, MultisigRemoveMemberArgs, Permission, Permissions, Multisig}; + +pub mod kollan_address { + use anchor_lang::prelude::declare_id; + declare_id!("tSTp6B6kE9o6ZaTmHm2ZwnJBBtgd3x112tapxFhmBEQ"); +} + +#[derive(Accounts)] +pub struct UpgradeMultisigDao<'info> { + #[account(mut, has_one = squads_multisig)] + pub dao: Box>, + #[account(mut)] + pub squads_multisig: Account<'info, Multisig>, + pub squads_multisig_program: Program<'info, SquadsMultisigProgram>, + #[account(mut)] + pub rent_payer: Signer<'info>, + pub system_program: Program<'info, System>, + pub kollan: Signer<'info>, +} + +impl UpgradeMultisigDao<'_> { + pub fn validate(&self) -> Result<()> { + // #[cfg(feature = "production")] + require_eq!(self.kollan.key(), kollan_address::id()); + + Ok(()) + } + + pub fn handle(ctx: Context) -> Result<()> { + let Self { + dao, + squads_multisig, + squads_multisig_program, + rent_payer, + system_program, + kollan: _, + } = ctx.accounts; + + let dao_nonce = &dao.nonce.to_le_bytes(); + let dao_creator_key = &dao.dao_creator.as_ref(); + let dao_seeds = &[b"dao".as_ref(), dao_creator_key, dao_nonce, &[dao.pda_bump]]; + let dao_signer = &[&dao_seeds[..]]; + + squads_multisig_program::cpi::multisig_add_member( + CpiContext::new_with_signer( + squads_multisig_program.to_account_info(), + squads_multisig_program::cpi::accounts::MultisigConfig { + multisig: squads_multisig.to_account_info(), + config_authority: dao.to_account_info(), + rent_payer: Some(rent_payer.to_account_info()), + system_program: Some(system_program.to_account_info()), + }, + dao_signer, + ), + MultisigAddMemberArgs { + new_member: Member { + key: system_program.key(), + permissions: Permissions::from_vec(&[Permission::Vote, Permission::Execute]), + }, + memo: None, + } + )?; + + squads_multisig_program::cpi::multisig_remove_member( + CpiContext::new_with_signer( + squads_multisig_program.to_account_info(), + squads_multisig_program::cpi::accounts::MultisigConfig { + multisig: squads_multisig.to_account_info(), + config_authority: dao.to_account_info(), + rent_payer: Some(rent_payer.to_account_info()), + system_program: Some(system_program.to_account_info()), + }, + dao_signer, + ), + MultisigRemoveMemberArgs { + old_member: dao.key(), + memo: None, + } + )?; + + squads_multisig_program::cpi::multisig_add_member( + CpiContext::new_with_signer( + squads_multisig_program.to_account_info(), + squads_multisig_program::cpi::accounts::MultisigConfig { + multisig: squads_multisig.to_account_info(), + config_authority: dao.to_account_info(), + rent_payer: Some(rent_payer.to_account_info()), + system_program: Some(system_program.to_account_info()), + }, + dao_signer, + ), + MultisigAddMemberArgs { + new_member: Member { + key: dao.key(), + permissions: Permissions::from_vec(&[Permission::Vote, Permission::Execute]), + }, + memo: None, + } + )?; + + squads_multisig_program::cpi::multisig_remove_member( + CpiContext::new_with_signer( + squads_multisig_program.to_account_info(), + squads_multisig_program::cpi::accounts::MultisigConfig { + multisig: squads_multisig.to_account_info(), + config_authority: dao.to_account_info(), + rent_payer: Some(rent_payer.to_account_info()), + system_program: Some(system_program.to_account_info()), + }, + dao_signer, + ), + MultisigRemoveMemberArgs { + old_member: system_program.key(), + memo: None, + } + )?; + + Ok(()) + } +} diff --git a/programs/autocrat/src/lib.rs b/programs/autocrat/src/lib.rs index 09fc11b0..a999cc28 100644 --- a/programs/autocrat/src/lib.rs +++ b/programs/autocrat/src/lib.rs @@ -100,4 +100,21 @@ pub mod autocrat { pub fn update_dao(ctx: Context, dao_params: UpdateDaoParams) -> Result<()> { UpdateDao::handle(ctx, dao_params) } + + #[access_control(ctx.accounts.validate())] + pub fn execute_spending_limit_change<'c: 'info, 'info>( + ctx: Context<'_, '_, 'c, 'info, ExecuteSpendingLimitChange<'info>>, + ) -> Result<()> { + ExecuteSpendingLimitChange::handle(ctx) + } + + #[access_control(ctx.accounts.validate())] + pub fn upgrade_multisig_dao(ctx: Context) -> Result<()> { + UpgradeMultisigDao::handle(ctx) + } + + #[access_control(ctx.accounts.validate())] + pub fn fix_omnipair_spending_limit(ctx: Context) -> Result<()> { + FixOmnipairSpendingLimit::handle(ctx) + } } diff --git a/scripts/executeSpendingLimit.ts b/scripts/executeSpendingLimit.ts new file mode 100644 index 00000000..8c17fe41 --- /dev/null +++ b/scripts/executeSpendingLimit.ts @@ -0,0 +1,152 @@ +import { PublicKey, Transaction } from "@solana/web3.js"; +import * as anchor from "@coral-xyz/anchor"; +import * as multisig from "@sqds/multisig"; +import { AutocratClient } from "../sdk/dist/v0.5/AutocratClient.js"; +import { getProposalAddr } from "../sdk/dist/v0.5/utils/index.js"; +import { AUTOCRAT_PROGRAM_ID } from "../sdk/dist/v0.5/constants.js"; +import { PERMISSIONLESS_ACCOUNT } from "@metadaoproject/futarchy/v0.5"; + +const provider = anchor.AnchorProvider.env(); +const payer = provider.wallet["payer"]; + +const DAO_ADDRESS = new PublicKey("7QbVKbEuqqrEANBaViB1XxoH34hqiroDqf2twkcusnWk"); +// const PROPOSAL_PDA = new PublicKey("Hh11b76gUQTfpuJLJqANxnm73zAHhQcj1MeKU44MJ93f"); + + +// Returns the multisig, spending limit and 0th vault pda for a given dao address +export const getSquadsPdasFromDao = async ( + daoAddress: string | PublicKey, +): Promise<{ + multisigPda: PublicKey; + spendingLimitPda: PublicKey; + vaultPda: PublicKey; +}> => { + const dao = + typeof daoAddress === "string" ? new PublicKey(daoAddress) : daoAddress; + const [multisigPda] = multisig.getMultisigPda({ + createKey: dao, + }); + + const [spendingLimitPda] = multisig.getSpendingLimitPda({ + multisigPda: multisigPda, + createKey: dao, + }); + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda, + index: 0, + }); + + return { + multisigPda, + spendingLimitPda, + vaultPda, + }; +}; + +const SQUADS_PROPOSAL_PDA = new PublicKey( + "Hh11b76gUQTfpuJLJqANxnm73zAHhQcj1MeKU44MJ93f", +); + +export default async function main() { + const autocrat = AutocratClient.createClient({ provider }); + + const dao = await autocrat.getDao(DAO_ADDRESS); + + const { multisigPda } = await getSquadsPdasFromDao(DAO_ADDRESS); + + console.log("multisigPda", multisigPda); + + const [metaDaoProposal] = getProposalAddr( + AUTOCRAT_PROGRAM_ID, + SQUADS_PROPOSAL_PDA, + ); + + console.log("metaDaoProposal", metaDaoProposal); + + + const multisigAccountInfo = + await multisig.accounts.Multisig.fromAccountAddress( + provider.connection, + multisigPda, + ); + + const currentTransactionIndex = Number(multisigAccountInfo.transactionIndex); + + console.log("currentTransactionIndex", currentTransactionIndex); + + const [proposalKey, proposalBump] = multisig.getProposalPda({ + multisigPda, + transactionIndex: BigInt(currentTransactionIndex - 2), + }); + + console.log("proposalKey", proposalKey); + + const metaDAOProposal = new PublicKey("AgzgRxxUU2Xniw2bEp8boBcz56kZmM1Sa7y9qESk5vnV"); + + const storedProposal = await autocrat.getProposal(metaDAOProposal); + + const [vaultTransactionPda] = multisig.getTransactionPda({ + multisigPda: multisigPda, + index: BigInt(currentTransactionIndex - 2), + }); + + console.log("vaultTransactionPda", vaultTransactionPda.toBase58()); + + const transactionAccount = + await multisig.accounts.VaultTransaction.fromAccountAddress( + provider.connection, + vaultTransactionPda, + ); + + console.log("transactionAccount", transactionAccount.vaultIndex); + const [vaultPda] = multisig.getVaultPda({ + multisigPda, + index: transactionAccount.vaultIndex, + programId: multisig.PROGRAM_ID, + }); + + console.log("vaultPda", vaultPda.toBase58()); + + const { accountMetas } = await multisig.utils.accountsForTransactionExecute( + { + connection: provider.connection, + message: transactionAccount.message, + ephemeralSignerBumps: [...transactionAccount.ephemeralSignerBumps], + vaultPda, + transactionPda: vaultTransactionPda, + programId: multisig.PROGRAM_ID, + }, + ); + + console.log("accountMetas", accountMetas); + + const tx = await autocrat.autocrat.methods + .executeSpendingLimitChange() + .accounts({ + squadsMultisig: multisigPda, + proposal: metaDAOProposal, + dao: DAO_ADDRESS, + squadsProposal: SQUADS_PROPOSAL_PDA, + squadsMultisigProgram: multisig.PROGRAM_ID, + vaultTransaction: vaultTransactionPda, + }) + .remainingAccounts( + accountMetas.map((meta) => + meta.pubkey.equals(DAO_ADDRESS) ? { ...meta, isSigner: false } : meta, + ), + ) + .transaction(); + + tx.feePayer = payer.publicKey; + tx.recentBlockhash = ( + await provider.connection.getLatestBlockhash() + ).blockhash; + tx.partialSign(payer); + const txHash = await provider.connection.sendRawTransaction(tx.serialize()); + console.log(`executeSpendingLimitChange transaction sent:`, txHash); + // const tx = await provider.sendAndConfirmTransaction(transaction); + +} + +main(); \ No newline at end of file diff --git a/scripts/upgradeDao.ts b/scripts/upgradeDao.ts new file mode 100644 index 00000000..65057b45 --- /dev/null +++ b/scripts/upgradeDao.ts @@ -0,0 +1,106 @@ +import { PublicKey, Transaction, TransactionMessage } from "@solana/web3.js"; +import * as multisig from "@sqds/multisig"; +import * as anchor from "@coral-xyz/anchor"; +import { AutocratClient } from "../sdk/dist/v0.5/AutocratClient.js"; +import { Keypair } from "@solana/web3.js"; +import fs from 'fs'; + +const provider = anchor.AnchorProvider.env(); +const payer = provider.wallet["payer"]; + +const bytes = JSON.parse(fs.readFileSync('./prop.json', 'utf8')); +const keypair = Keypair.fromSecretKey(new Uint8Array(bytes)); + +const proposer = keypair; + +const autocratClient = AutocratClient.createClient({ provider }); +const daoAddress = new PublicKey('B3AufDZCDtQN8JxZgJ5bSDZaiKCF4vtw7ynN9tuR9pXN') +const squadsPayer = new PublicKey("6awyHMshBGVjJ3ozdSJdyyDE1CTAXUwrpNMaRGMsb4sf") + +const daoUpgrade = async () => { + const dao = + typeof daoAddress === "string" ? new PublicKey(daoAddress) : daoAddress; + + const [multisigPda] = multisig.getMultisigPda({ + createKey: dao, + }); + + const metaDaoUpgradeTxn = await autocratClient.autocrat.methods + .upgradeMultisigDao() + .accounts({ + dao, + squadsMultisig: multisigPda, + squadsMultisigProgram: multisig.PROGRAM_ID, + rentPayer: payer.pubkey, + kollan: payer.pubkey + }).transaction(); + + return metaDaoUpgradeTxn; +} + +const mainWoSquads = async () => { + const metaDaoUpgradeTxn = await daoUpgrade(); + + // const tx = new Transaction().add(metaDaoUpgradeTxn) + + metaDaoUpgradeTxn.feePayer = payer.publicKey; + metaDaoUpgradeTxn.recentBlockhash = ( + await provider.connection.getLatestBlockhash() + ).blockhash; + metaDaoUpgradeTxn.partialSign(payer); + const txHash = await provider.connection.sendRawTransaction(metaDaoUpgradeTxn.serialize()); + console.log(`upgradeDao transaction sent:`, txHash); + +} + +const main = async () => { + + const metaDaoUpgradeTxn = await daoUpgrade(); + + + const transactionMessage = new TransactionMessage({ + payerKey: squadsPayer, + recentBlockhash: (await provider.connection.getLatestBlockhash()).blockhash, + instructions: metaDaoUpgradeTxn.instructions, + }); + + const metaDaoUpgradeMultisigPda = new PublicKey("8N3Tvc6B1wEVKVC6iD4s6eyaCNqX2ovj2xze2q3Q9DWH") + + const multisigAccountInfo = + await multisig.accounts.Multisig.fromAccountAddress( + provider.connection, + metaDaoUpgradeMultisigPda, + ); + + const currentTransactionIndex = Number(multisigAccountInfo.transactionIndex); + + const upgradeViaMultisigTxn = multisig.instructions.vaultTransactionCreate({ + multisigPda: metaDaoUpgradeMultisigPda, + transactionIndex: BigInt(currentTransactionIndex + 1), + creator: proposer.publicKey, + rentPayer: payer.publicKey, + vaultIndex: 0, + ephemeralSigners: 0, + transactionMessage + }); + + const proposalCreateIx = multisig.instructions.proposalCreate({ + multisigPda: metaDaoUpgradeMultisigPda, + transactionIndex: BigInt(currentTransactionIndex + 1), + creator: proposer.publicKey, + rentPayer: payer.publicKey, + isDraft: false, + }); + + const tx = new Transaction().add(upgradeViaMultisigTxn, proposalCreateIx) + + tx.feePayer = payer.publicKey; + tx.recentBlockhash = ( + await provider.connection.getLatestBlockhash() + ).blockhash; + tx.partialSign(payer, proposer); + const txHash = await provider.connection.sendRawTransaction(tx.serialize()); + console.log(`upgradeDao transaction sent:`, txHash); +} + +mainWoSquads(); \ No newline at end of file diff --git a/sdk/src/v0.5/AmmClient.ts b/sdk/src/v0.5/AmmClient.ts index 2dca891d..62b540cb 100644 --- a/sdk/src/v0.5/AmmClient.ts +++ b/sdk/src/v0.5/AmmClient.ts @@ -36,7 +36,7 @@ export class AmmClient { constructor( provider: AnchorProvider, ammProgramId: PublicKey, - luts: AddressLookupTableAccount[] + luts: AddressLookupTableAccount[], ) { this.provider = provider; this.program = new Program(AmmIDL, ammProgramId, provider); @@ -44,7 +44,7 @@ export class AmmClient { } public static createClient( - createAutocratClientParams: CreateAmmClientParams + createAutocratClientParams: CreateAmmClientParams, ): AmmClient { let { provider, ammProgramId: programId } = createAutocratClientParams; @@ -75,7 +75,7 @@ export class AmmClient { quoteMint: PublicKey, twapStartDelaySlots: BN, twapInitialObservation: number, - twapMaxObservationChangePerUpdate?: number + twapMaxObservationChangePerUpdate?: number, ): Promise { if (!twapMaxObservationChangePerUpdate) { twapMaxObservationChangePerUpdate = twapInitialObservation * 0.02; @@ -84,11 +84,11 @@ export class AmmClient { let baseDecimals = unpackMint( baseMint, - await this.provider.connection.getAccountInfo(baseMint) + await this.provider.connection.getAccountInfo(baseMint), ).decimals; let quoteDecimals = unpackMint( quoteMint, - await this.provider.connection.getAccountInfo(quoteMint) + await this.provider.connection.getAccountInfo(quoteMint), ).decimals; let [twapFirstObservationScaled, twapMaxObservationChangePerUpdateScaled] = @@ -96,7 +96,7 @@ export class AmmClient { baseDecimals, quoteDecimals, twapInitialObservation, - twapMaxObservationChangePerUpdate + twapMaxObservationChangePerUpdate, ); await this.initializeAmmIx( @@ -104,7 +104,7 @@ export class AmmClient { quoteMint, twapStartDelaySlots, twapFirstObservationScaled, - twapMaxObservationChangePerUpdateScaled + twapMaxObservationChangePerUpdateScaled, ).rpc(); return amm; @@ -116,7 +116,7 @@ export class AmmClient { quoteMint: PublicKey, twapStartDelaySlots: BN, twapInitialObservation: BN, - twapMaxObservationChangePerUpdate: BN + twapMaxObservationChangePerUpdate: BN, ) { let [amm] = getAmmAddr(this.getProgramId(), baseMint, quoteMint); let [lpMint] = getAmmLpMintAddr(this.getProgramId(), amm); @@ -144,13 +144,13 @@ export class AmmClient { async addLiquidity( amm: PublicKey, quoteAmount?: number, - baseAmount?: number + baseAmount?: number, ) { let storedAmm = await this.getAmm(amm); let lpMintSupply = unpackMint( storedAmm.lpMint, - await this.provider.connection.getAccountInfo(storedAmm.lpMint) + await this.provider.connection.getAccountInfo(storedAmm.lpMint), ).supply; let quoteAmountCasted: BN | undefined; @@ -159,27 +159,27 @@ export class AmmClient { if (quoteAmount != undefined) { let quoteDecimals = unpackMint( storedAmm.quoteMint, - await this.provider.connection.getAccountInfo(storedAmm.quoteMint) + await this.provider.connection.getAccountInfo(storedAmm.quoteMint), ).decimals; quoteAmountCasted = new BN(quoteAmount).mul( - new BN(10).pow(new BN(quoteDecimals)) + new BN(10).pow(new BN(quoteDecimals)), ); } if (baseAmount != undefined) { let baseDecimals = unpackMint( storedAmm.baseMint, - await this.provider.connection.getAccountInfo(storedAmm.baseMint) + await this.provider.connection.getAccountInfo(storedAmm.baseMint), ).decimals; baseAmountCasted = new BN(baseAmount).mul( - new BN(10).pow(new BN(baseDecimals)) + new BN(10).pow(new BN(baseDecimals)), ); } if (lpMintSupply == 0n) { if (quoteAmount == undefined || baseAmount == undefined) { throw new Error( - "No pool created yet, you need to specify both base and quote" + "No pool created yet, you need to specify both base and quote", ); } @@ -192,7 +192,7 @@ export class AmmClient { storedAmm.quoteMint, quoteAmountCasted as BN, baseAmountCasted as BN, - new BN(0) + new BN(0), ).rpc(); } @@ -205,7 +205,7 @@ export class AmmClient { storedAmm.quoteAmount, Number(lpMintSupply), baseAmountCasted, - quoteAmountCasted + quoteAmountCasted, ); await this.addLiquidityIx( @@ -214,7 +214,7 @@ export class AmmClient { storedAmm.quoteMint, sim.quoteAmount, sim.baseAmount, - sim.expectedLpTokens + sim.expectedLpTokens, ).rpc(); } @@ -225,7 +225,7 @@ export class AmmClient { quoteAmount: BN, maxBaseAmount: BN, minLpTokens: BN, - user: PublicKey = this.provider.publicKey + user: PublicKey = this.provider.publicKey, ) { const [lpMint] = getAmmLpMintAddr(this.program.programId, amm); @@ -252,7 +252,7 @@ export class AmmClient { user, userLpAccount, user, - lpMint + lpMint, ), ]); } @@ -263,7 +263,7 @@ export class AmmClient { quoteMint: PublicKey, lpTokensToBurn: BN, minBaseAmount: BN, - minQuoteAmount: BN + minQuoteAmount: BN, ) { const [lpMint] = getAmmLpMintAddr(this.program.programId, ammAddr); @@ -280,17 +280,17 @@ export class AmmClient { userLpAccount: getAssociatedTokenAddressSync( lpMint, this.provider.publicKey, - true + true, ), userBaseAccount: getAssociatedTokenAddressSync( baseMint, this.provider.publicKey, - true + true, ), userQuoteAccount: getAssociatedTokenAddressSync( quoteMint, this.provider.publicKey, - true + true, ), vaultAtaBase: getAssociatedTokenAddressSync(baseMint, ammAddr, true), vaultAtaQuote: getAssociatedTokenAddressSync(quoteMint, ammAddr, true), @@ -301,7 +301,7 @@ export class AmmClient { amm: PublicKey, swapType: SwapType, inputAmount: number, - outputAmountMin: number + outputAmountMin: number, ) { const storedAmm = await this.getAmm(amm); @@ -324,7 +324,7 @@ export class AmmClient { storedAmm.quoteMint, swapType, inputAmountScaled, - outputAmountMinScaled + outputAmountMinScaled, ).rpc(); } @@ -335,7 +335,7 @@ export class AmmClient { swapType: SwapType, inputAmount: BN, outputAmountMin: BN, - user: PublicKey = this.provider.publicKey + user: PublicKey = this.provider.publicKey, ) { const receivingToken = swapType.buy ? baseMint : quoteMint; @@ -359,7 +359,7 @@ export class AmmClient { user, getAssociatedTokenAddressSync(receivingToken, user, true), user, - receivingToken + receivingToken, ), ]); } diff --git a/sdk/src/v0.5/AutocratClient.ts b/sdk/src/v0.5/AutocratClient.ts index 23a703a6..f05795e1 100644 --- a/sdk/src/v0.5/AutocratClient.ts +++ b/sdk/src/v0.5/AutocratClient.ts @@ -79,13 +79,13 @@ export class AutocratClient { autocratProgramId: PublicKey, conditionalVaultProgramId: PublicKey, ammProgramId: PublicKey, - luts: AddressLookupTableAccount[] + luts: AddressLookupTableAccount[], ) { this.provider = provider; this.autocrat = new Program( AutocratIDL, autocratProgramId, - provider + provider, ); this.vaultClient = ConditionalVaultClient.createClient({ provider, @@ -96,7 +96,7 @@ export class AutocratClient { } public static createClient( - createAutocratClientParams: CreateClientParams + createAutocratClientParams: CreateClientParams, ): AutocratClient { let { provider, @@ -112,7 +112,7 @@ export class AutocratClient { autocratProgramId || AUTOCRAT_PROGRAM_ID, conditionalVaultProgramId || CONDITIONAL_VAULT_PROGRAM_ID, ammProgramId || AMM_PROGRAM_ID, - luts + luts, ); } @@ -137,7 +137,7 @@ export class AutocratClient { } async deserializeProposal( - accountInfo: AccountInfo + accountInfo: AccountInfo, ): Promise { return this.autocrat.coder.accounts.decode("proposal", accountInfo.data); } @@ -150,7 +150,7 @@ export class AutocratClient { proposal: PublicKey, baseMint: PublicKey, quoteMint: PublicKey, - dao: PublicKey + dao: PublicKey, ): { question: PublicKey; baseVault: PublicKey; @@ -169,60 +169,60 @@ export class AutocratClient { vaultProgramId, sha256(`Will ${proposal} pass?/FAIL/PASS`), proposal, - 2 + 2, ); const [daoTreasury] = getDaoTreasuryAddr(this.autocrat.programId, dao); const [baseVault] = getVaultAddr( this.vaultClient.vaultProgram.programId, question, - baseMint + baseMint, ); const [quoteVault] = getVaultAddr( this.vaultClient.vaultProgram.programId, question, - quoteMint + quoteMint, ); const [failBaseMint] = getConditionalTokenMintAddr( vaultProgramId, baseVault, - 0 + 0, ); const [failQuoteMint] = getConditionalTokenMintAddr( vaultProgramId, quoteVault, - 0 + 0, ); const [passBaseMint] = getConditionalTokenMintAddr( vaultProgramId, baseVault, - 1 + 1, ); const [passQuoteMint] = getConditionalTokenMintAddr( vaultProgramId, quoteVault, - 1 + 1, ); const [passAmm] = getAmmAddr( this.ammClient.program.programId, passBaseMint, - passQuoteMint + passQuoteMint, ); const [failAmm] = getAmmAddr( this.ammClient.program.programId, failBaseMint, - failQuoteMint + failQuoteMint, ); const [passLp] = getAmmLpMintAddr( this.ammClient.program.programId, - passAmm + passAmm, ); const [failLp] = getAmmLpMintAddr( this.ammClient.program.programId, - failAmm + failAmm, ); return { @@ -339,7 +339,7 @@ export class AutocratClient { descriptionUrl: string, squadsProposal: PublicKey, baseTokensToLP: BN, - quoteTokensToLP: BN + quoteTokensToLP: BN, ): Promise { const storedDao = await this.getDao(dao); @@ -348,7 +348,7 @@ export class AutocratClient { await this.vaultClient.initializeQuestion( sha256(`Will ${proposal} pass?/FAIL/PASS`), proposal, - 2 + 2, ); const { @@ -365,7 +365,7 @@ export class AutocratClient { proposal, storedDao.baseMint, storedDao.quoteMint, - dao + dao, ); // it's important that these happen in a single atomic transaction @@ -379,16 +379,16 @@ export class AutocratClient { passQuoteMint, storedDao.twapStartDelaySlots, storedDao.twapInitialObservation, - storedDao.twapMaxObservationChangePerUpdate + storedDao.twapMaxObservationChangePerUpdate, ), this.ammClient.initializeAmmIx( failBaseMint, failQuoteMint, storedDao.twapStartDelaySlots, storedDao.twapInitialObservation, - storedDao.twapMaxObservationChangePerUpdate - ) - ) + storedDao.twapMaxObservationChangePerUpdate, + ), + ), ) .rpc(); @@ -402,9 +402,9 @@ export class AutocratClient { quoteVault, storedDao.quoteMint, quoteTokensToLP, - 2 - ) - ) + 2, + ), + ), ) .rpc(); @@ -415,7 +415,7 @@ export class AutocratClient { passQuoteMint, quoteTokensToLP, baseTokensToLP, - new BN(0) + new BN(0), ) .postInstructions( await InstructionUtils.getInstructions( @@ -425,9 +425,9 @@ export class AutocratClient { failQuoteMint, quoteTokensToLP, baseTokensToLP, - new BN(0) - ) - ) + new BN(0), + ), + ), ) .rpc(); @@ -442,7 +442,7 @@ export class AutocratClient { storedDao.quoteMint, lpTokens, lpTokens, - question + question, ).rpc(); return proposal; @@ -457,34 +457,34 @@ export class AutocratClient { passLpTokensToLock: BN, failLpTokensToLock: BN, question: PublicKey, - proposer: PublicKey = this.provider.publicKey + proposer: PublicKey = this.provider.publicKey, ) { let [proposal] = getProposalAddr(this.autocrat.programId, squadsProposal); const { baseVault, quoteVault, passAmm, failAmm } = this.getProposalPdas( proposal, baseMint, quoteMint, - dao + dao, ); const [passLp] = getAmmLpMintAddr( this.ammClient.program.programId, - passAmm + passAmm, ); const [failLp] = getAmmLpMintAddr( this.ammClient.program.programId, - failAmm + failAmm, ); const passLpVaultAccount = getAssociatedTokenAddressSync( passLp, proposal, - true + true, ); const failLpVaultAccount = getAssociatedTokenAddressSync( failLp, proposal, - true + true, ); return this.autocrat.methods @@ -507,12 +507,12 @@ export class AutocratClient { passLpUserAccount: getAssociatedTokenAddressSync( passLp, proposer, - true + true, ), failLpUserAccount: getAssociatedTokenAddressSync( failLp, proposer, - true + true, ), passLpVaultAccount, failLpVaultAccount, @@ -530,7 +530,7 @@ export class AutocratClient { storedProposal.dao, storedDao.baseMint, storedDao.quoteMint, - storedProposal.proposer + storedProposal.proposer, ).rpc(); } @@ -540,7 +540,7 @@ export class AutocratClient { dao: PublicKey, daoToken: PublicKey, usdc: PublicKey, - proposer: PublicKey + proposer: PublicKey, ) { let vaultProgramId = this.vaultClient.vaultProgram.programId; const multisigPda = multisig.getMultisigPda({ createKey: dao })[0]; @@ -550,16 +550,16 @@ export class AutocratClient { proposal, daoToken, usdc, - dao + dao, ); const [passLp] = getAmmLpMintAddr( this.ammClient.program.programId, - passAmm + passAmm, ); const [failLp] = getAmmLpMintAddr( this.ammClient.program.programId, - failAmm + failAmm, ); const [vaultEventAuthority] = getEventAuthorityAddr(vaultProgramId); @@ -636,7 +636,7 @@ export class AutocratClient { // there aren't enough proposals on devnet async crankProposalMarkets( proposals: PublicKey[], - priorityFeeMicroLamports: number + priorityFeeMicroLamports: number, ) { const amms: PublicKey[] = []; @@ -655,12 +655,12 @@ export class AutocratClient { let tx = new Transaction(); tx.add( - ComputeBudgetProgram.setComputeUnitLimit({ units: 4_000 * ixs.length }) + ComputeBudgetProgram.setComputeUnitLimit({ units: 4_000 * ixs.length }), ); tx.add( ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priorityFeeMicroLamports, - }) + }), ); tx.add(...ixs); try { diff --git a/sdk/src/v0.5/ConditionalVaultClient.ts b/sdk/src/v0.5/ConditionalVaultClient.ts index ee3f0a36..047e0a46 100644 --- a/sdk/src/v0.5/ConditionalVaultClient.ts +++ b/sdk/src/v0.5/ConditionalVaultClient.ts @@ -42,18 +42,18 @@ export class ConditionalVaultClient { this.vaultProgram = new Program( ConditionalVaultIDL, conditionalVaultProgramId, - provider + provider, ); } public static createClient( - createVaultClientParams: CreateVaultClientParams + createVaultClientParams: CreateVaultClientParams, ): ConditionalVaultClient { let { provider, conditionalVaultProgramId } = createVaultClientParams; return new ConditionalVaultClient( provider, - conditionalVaultProgramId || CONDITIONAL_VAULT_PROGRAM_ID + conditionalVaultProgramId || CONDITIONAL_VAULT_PROGRAM_ID, ); } @@ -66,33 +66,33 @@ export class ConditionalVaultClient { } async deserializeQuestion( - accountInfo: AccountInfo + accountInfo: AccountInfo, ): Promise { return this.vaultProgram.coder.accounts.decode( "question", - accountInfo.data + accountInfo.data, ); } async deserializeVault( - accountInfo: AccountInfo + accountInfo: AccountInfo, ): Promise { return this.vaultProgram.coder.accounts.decode( "conditionalVault", - accountInfo.data + accountInfo.data, ); } initializeQuestionIx( questionId: Uint8Array, oracle: PublicKey, - numOutcomes: number + numOutcomes: number, ) { const [question] = getQuestionAddr( this.vaultProgram.programId, questionId, oracle, - numOutcomes + numOutcomes, ); return this.vaultProgram.methods @@ -109,13 +109,13 @@ export class ConditionalVaultClient { async initializeQuestion( questionId: Uint8Array, oracle: PublicKey, - numOutcomes: number + numOutcomes: number, ): Promise { const [question] = getQuestionAddr( this.vaultProgram.programId, questionId, oracle, - numOutcomes + numOutcomes, ); await this.initializeQuestionIx(questionId, oracle, numOutcomes).rpc(); @@ -127,12 +127,12 @@ export class ConditionalVaultClient { question: PublicKey, underlyingTokenMint: PublicKey, numOutcomes: number, - payer: PublicKey = this.provider.publicKey + payer: PublicKey = this.provider.publicKey, ) { const [vault] = getVaultAddr( this.vaultProgram.programId, question, - underlyingTokenMint + underlyingTokenMint, ); let conditionalTokenMintAddrs = []; @@ -140,7 +140,7 @@ export class ConditionalVaultClient { const [conditionalTokenMint] = getConditionalTokenMintAddr( this.vaultProgram.programId, vault, - i + i, ); conditionalTokenMintAddrs.push(conditionalTokenMint); } @@ -148,7 +148,7 @@ export class ConditionalVaultClient { const vaultUnderlyingTokenAccount = getAssociatedTokenAddressSync( underlyingTokenMint, vault, - true + true, ); return this.vaultProgram.methods @@ -164,7 +164,7 @@ export class ConditionalVaultClient { payer, vaultUnderlyingTokenAccount, vault, - underlyingTokenMint + underlyingTokenMint, ), ]) .remainingAccounts( @@ -174,7 +174,7 @@ export class ConditionalVaultClient { isWritable: true, isSigner: false, }; - }) + }), ); } @@ -183,18 +183,18 @@ export class ConditionalVaultClient { async initializeVault( question: PublicKey, underlyingTokenMint: PublicKey, - numOutcomes: number + numOutcomes: number, ): Promise { const [vault] = getVaultAddr( this.vaultProgram.programId, question, - underlyingTokenMint + underlyingTokenMint, ); await this.initializeVaultIx( question, underlyingTokenMint, - numOutcomes + numOutcomes, ).rpc(); return vault; @@ -203,7 +203,7 @@ export class ConditionalVaultClient { resolveQuestionIx( question: PublicKey, oracle: Keypair, - payoutNumerators: number[] + payoutNumerators: number[], ) { return this.vaultProgram.methods .resolveQuestion({ @@ -222,7 +222,7 @@ export class ConditionalVaultClient { const [conditionalTokenMint] = getConditionalTokenMintAddr( this.vaultProgram.programId, vault, - i + i, ); conditionalTokenMintAddrs.push(conditionalTokenMint); } @@ -231,7 +231,7 @@ export class ConditionalVaultClient { getRemainingAccounts( conditionalTokenMints: PublicKey[], - userConditionalAccounts: PublicKey[] + userConditionalAccounts: PublicKey[], ) { return conditionalTokenMints .concat(userConditionalAccounts) @@ -247,14 +247,14 @@ export class ConditionalVaultClient { vault: PublicKey, numOutcomes: number, user: PublicKey = this.provider.publicKey, - payer: PublicKey = this.provider.publicKey + payer: PublicKey = this.provider.publicKey, ) { const conditionalTokenMintAddrs = this.getConditionalTokenMints( vault, - numOutcomes + numOutcomes, ); const userConditionalAccounts = conditionalTokenMintAddrs.map((mint) => - getAssociatedTokenAddressSync(mint, user, true) + getAssociatedTokenAddressSync(mint, user, true), ); const preInstructions = conditionalTokenMintAddrs.map((mint) => @@ -262,13 +262,13 @@ export class ConditionalVaultClient { payer, getAssociatedTokenAddressSync(mint, user, true), user, - mint - ) + mint, + ), ); const remainingAccounts = this.getRemainingAccounts( conditionalTokenMintAddrs, - userConditionalAccounts + userConditionalAccounts, ); return { userConditionalAccounts, preInstructions, remainingAccounts }; @@ -281,14 +281,14 @@ export class ConditionalVaultClient { amount: BN, numOutcomes: number, user: PublicKey = this.provider.publicKey, - payer: PublicKey = this.provider.publicKey + payer: PublicKey = this.provider.publicKey, ) { const { preInstructions, remainingAccounts } = this.getConditionalTokenAccountsAndInstructions( vault, numOutcomes, user, - payer + payer, ); return this.vaultProgram.methods @@ -300,12 +300,12 @@ export class ConditionalVaultClient { vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( underlyingTokenMint, vault, - true + true, ), userUnderlyingTokenAccount: getAssociatedTokenAddressSync( underlyingTokenMint, user, - true + true, ), }) .preInstructions(preInstructions) @@ -319,17 +319,17 @@ export class ConditionalVaultClient { amount: BN, numOutcomes: number, user: PublicKey = this.provider.publicKey, - payer: PublicKey = this.provider.publicKey + payer: PublicKey = this.provider.publicKey, ) { let conditionalTokenMintAddrs = this.getConditionalTokenMints( vault, - numOutcomes + numOutcomes, ); let userConditionalAccounts = []; for (let conditionalTokenMint of conditionalTokenMintAddrs) { userConditionalAccounts.push( - getAssociatedTokenAddressSync(conditionalTokenMint, user, true) + getAssociatedTokenAddressSync(conditionalTokenMint, user, true), ); } @@ -342,12 +342,12 @@ export class ConditionalVaultClient { vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( underlyingTokenMint, vault, - true + true, ), userUnderlyingTokenAccount: getAssociatedTokenAddressSync( underlyingTokenMint, user, - true + true, ), }) .preInstructions( @@ -356,9 +356,9 @@ export class ConditionalVaultClient { payer, getAssociatedTokenAddressSync(conditionalTokenMint, user, true), user, - conditionalTokenMint + conditionalTokenMint, ); - }) + }), ) .remainingAccounts( conditionalTokenMintAddrs @@ -369,7 +369,7 @@ export class ConditionalVaultClient { isWritable: true, isSigner: false, }; - }) + }), ); return ix; @@ -381,14 +381,14 @@ export class ConditionalVaultClient { underlyingTokenMint: PublicKey, numOutcomes: number, user: PublicKey = this.provider.publicKey, - payer: PublicKey = this.provider.publicKey + payer: PublicKey = this.provider.publicKey, ) { let conditionalTokenMintAddrs = []; for (let i = 0; i < numOutcomes; i++) { const [conditionalTokenMint] = getConditionalTokenMintAddr( this.vaultProgram.programId, vault, - i + i, ); conditionalTokenMintAddrs.push(conditionalTokenMint); } @@ -396,7 +396,7 @@ export class ConditionalVaultClient { let userConditionalAccounts = []; for (let conditionalTokenMint of conditionalTokenMintAddrs) { userConditionalAccounts.push( - getAssociatedTokenAddressSync(conditionalTokenMint, user, true) + getAssociatedTokenAddressSync(conditionalTokenMint, user, true), ); } @@ -409,12 +409,12 @@ export class ConditionalVaultClient { vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( underlyingTokenMint, vault, - true + true, ), userUnderlyingTokenAccount: getAssociatedTokenAddressSync( underlyingTokenMint, user, - true + true, ), }) .preInstructions( @@ -423,9 +423,9 @@ export class ConditionalVaultClient { payer, getAssociatedTokenAddressSync(conditionalTokenMint, user, true), user, - conditionalTokenMint + conditionalTokenMint, ); - }) + }), ) .remainingAccounts( conditionalTokenMintAddrs @@ -436,7 +436,7 @@ export class ConditionalVaultClient { isWritable: true, isSigner: false, }; - }) + }), ); return ix; @@ -448,12 +448,12 @@ export class ConditionalVaultClient { name: string, symbol: string, uri: string, - payer: PublicKey = this.provider.publicKey + payer: PublicKey = this.provider.publicKey, ) { const [conditionalTokenMint] = getConditionalTokenMintAddr( this.vaultProgram.programId, vault, - index + index, ); const [conditionalTokenMetadata] = getMetadataAddr(conditionalTokenMint); diff --git a/sdk/src/v0.5/LaunchpadClient.ts b/sdk/src/v0.5/LaunchpadClient.ts index 5bf90b90..ab1be0db 100644 --- a/sdk/src/v0.5/LaunchpadClient.ts +++ b/sdk/src/v0.5/LaunchpadClient.ts @@ -62,7 +62,7 @@ export class LaunchpadClient { this.launchpad = new Program( LaunchpadIDL, params.launchpadProgramId || LAUNCHPAD_PROGRAM_ID, - this.provider + this.provider, ); this.autocratClient = AutocratClient.createClient({ provider: this.provider, @@ -97,19 +97,19 @@ export class LaunchpadClient { } async fetchFundingRecord( - fundingRecord: PublicKey + fundingRecord: PublicKey, ): Promise { return await this.launchpad.account.fundingRecord.fetchNullable( - fundingRecord + fundingRecord, ); } async deserializeFundingRecord( - accountInfo: AccountInfo + accountInfo: AccountInfo, ): Promise { return this.launchpad.coder.accounts.decode( "fundingRecord", - accountInfo.data + accountInfo.data, ); } @@ -125,23 +125,23 @@ export class LaunchpadClient { monthlySpendingLimitMembers: PublicKey[], launchAuthority: PublicKey = this.provider.publicKey, isDevnet: boolean = false, - payer: PublicKey = this.provider.publicKey + payer: PublicKey = this.provider.publicKey, ) { const [launch] = getLaunchAddr(this.launchpad.programId, baseMint); const [launchSigner] = getLaunchSignerAddr( this.launchpad.programId, - launch + launch, ); const quoteVault = getAssociatedTokenAddressSync( quoteMint, launchSigner, - true + true, ); const baseVault = getAssociatedTokenAddressSync( baseMint, launchSigner, - true + true, ); const [tokenMetadata] = getMetadataAddr(baseMint); @@ -172,7 +172,7 @@ export class LaunchpadClient { payer, getAssociatedTokenAddressSync(quoteMint, launchSigner, true), launchSigner, - quoteMint + quoteMint, ), ]); // .signers([tokenMintKp]); @@ -180,7 +180,7 @@ export class LaunchpadClient { startLaunchIx( launch: PublicKey, - launchAuthority: PublicKey = this.provider.publicKey + launchAuthority: PublicKey = this.provider.publicKey, ) { return this.launchpad.methods.startLaunch().accounts({ launch, @@ -193,28 +193,28 @@ export class LaunchpadClient { amount: BN, funder: PublicKey = this.provider.publicKey, quoteMint: PublicKey, - isDevnet: boolean = false + isDevnet: boolean = false, ) { const USDC = isDevnet ? DEVNET_USDC : MAINNET_USDC; const [launchSigner] = getLaunchSignerAddr( this.launchpad.programId, - launch + launch, ); const launchQuoteVault = getAssociatedTokenAddressSync( quoteMint, launchSigner, - true + true, ); const funderQuoteAccount = getAssociatedTokenAddressSync( quoteMint, funder, - true + true, ); const [fundingRecord] = getFundingRecordAddr( this.launchpad.programId, launch, - funder + funder, ); return this.launchpad.methods.fund(amount).accounts({ @@ -231,23 +231,23 @@ export class LaunchpadClient { launch: PublicKey, quoteMint: PublicKey, baseMint: PublicKey, - isDevnet: boolean = false + isDevnet: boolean = false, ) { const USDC = isDevnet ? DEVNET_USDC : MAINNET_USDC; const [launchSigner] = getLaunchSignerAddr( this.launchpad.programId, - launch + launch, ); const launchQuoteVault = getAssociatedTokenAddressSync( quoteMint, launchSigner, - true + true, ); const launchBaseVault = getAssociatedTokenAddressSync( baseMint, launchSigner, - true + true, ); // const daoKp = Keypair.generate(); @@ -272,7 +272,7 @@ export class LaunchpadClient { poolState.toBuffer(), baseMint.toBuffer(), ], - cpSwapProgramId + cpSwapProgramId, ); const [poolUsdcVault] = PublicKey.findProgramAddressSync( @@ -281,16 +281,16 @@ export class LaunchpadClient { poolState.toBuffer(), USDC.toBuffer(), ], - cpSwapProgramId + cpSwapProgramId, ); const [observationState] = PublicKey.findProgramAddressSync( [anchor.utils.bytes.utf8.encode("observation"), poolState.toBuffer()], - cpSwapProgramId + cpSwapProgramId, ); const [autocratEventAuthority] = getEventAuthorityAddr( - this.autocratClient.getProgramId() + this.autocratClient.getProgramId(), ); const [tokenMetadata] = getMetadataAddr(baseMint); @@ -309,7 +309,7 @@ export class LaunchpadClient { const treasuryQuoteAccount = getAssociatedTokenAddressSync( quoteMint, multisigVault, - true + true, ); return this.launchpad.methods.completeLaunch().accounts({ @@ -322,7 +322,7 @@ export class LaunchpadClient { treasuryLpAccount: getAssociatedTokenAddressSync( lpMint, multisigVault, - true + true, ), quoteMint, baseMint, @@ -367,28 +367,28 @@ export class LaunchpadClient { launch: PublicKey, funder: PublicKey = this.provider.publicKey, quoteMint: PublicKey, - isDevnet: boolean = false + isDevnet: boolean = false, ) { const [launchSigner] = getLaunchSignerAddr( this.launchpad.programId, - launch + launch, ); const [fundingRecord] = getFundingRecordAddr( this.launchpad.programId, launch, - funder + funder, ); const launchQuoteVault = getAssociatedTokenAddressSync( quoteMint, launchSigner, - true + true, ); const funderQuoteAccount = getAssociatedTokenAddressSync( quoteMint, funder, - true + true, ); return this.launchpad.methods.refund().accounts({ @@ -404,16 +404,16 @@ export class LaunchpadClient { claimIx( launch: PublicKey, baseMint: PublicKey, - funder: PublicKey = this.provider.publicKey + funder: PublicKey = this.provider.publicKey, ) { const [launchSigner] = getLaunchSignerAddr( this.launchpad.programId, - launch + launch, ); const [fundingRecord] = getFundingRecordAddr( this.launchpad.programId, launch, - funder + funder, ); return this.launchpad.methods @@ -426,13 +426,13 @@ export class LaunchpadClient { funderTokenAccount: getAssociatedTokenAddressSync( baseMint, funder, - true + true, ), baseMint, launchBaseVault: getAssociatedTokenAddressSync( baseMint, launchSigner, - true + true, ), }) .preInstructions([ @@ -440,7 +440,7 @@ export class LaunchpadClient { this.provider.publicKey, getAssociatedTokenAddressSync(baseMint, funder, true), funder, - baseMint + baseMint, ), ]); } diff --git a/sdk/src/v0.5/SharedLiquidityManagerClient.ts b/sdk/src/v0.5/SharedLiquidityManagerClient.ts index 3602494c..5b44571e 100644 --- a/sdk/src/v0.5/SharedLiquidityManagerClient.ts +++ b/sdk/src/v0.5/SharedLiquidityManagerClient.ts @@ -78,7 +78,7 @@ export class SharedLiquidityManagerClient { SharedLiquidityManagerIDL, params.sharedLiquidityManagerProgramId || SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, - this.provider + this.provider, ); this.autocratClient = AutocratClient.createClient({ provider: this.provider, @@ -89,7 +89,7 @@ export class SharedLiquidityManagerClient { } public static createClient( - params: CreateSharedLiquidityManagerClientParams + params: CreateSharedLiquidityManagerClientParams, ): SharedLiquidityManagerClient { return new SharedLiquidityManagerClient(params); } diff --git a/sdk/src/v0.5/constants.ts b/sdk/src/v0.5/constants.ts index e1b0d3bc..38fd5c39 100644 --- a/sdk/src/v0.5/constants.ts +++ b/sdk/src/v0.5/constants.ts @@ -3,42 +3,42 @@ import * as anchor from "@coral-xyz/anchor"; import { BN } from "bn.js"; export const AUTOCRAT_PROGRAM_ID = new PublicKey( - "auToUr3CQza3D4qreT6Std2MTomfzvrEeCC5qh7ivW5" + "auToUr3CQza3D4qreT6Std2MTomfzvrEeCC5qh7ivW5", ); export const AMM_PROGRAM_ID = new PublicKey( - "AMMJdEiCCa8mdugg6JPF7gFirmmxisTfDJoSNSUi5zDJ" + "AMMJdEiCCa8mdugg6JPF7gFirmmxisTfDJoSNSUi5zDJ", ); export const CONDITIONAL_VAULT_PROGRAM_ID = new PublicKey( - "VLTX1ishMBbcX3rdBWGssxawAo1Q2X2qxYFYqiGodVg" + "VLTX1ishMBbcX3rdBWGssxawAo1Q2X2qxYFYqiGodVg", ); export const LAUNCHPAD_PROGRAM_ID = new PublicKey( - "mooNhciQJi1LqHDmse2JPic2NqG2PXCanbE3ZYzP3qA" + "mooNhciQJi1LqHDmse2JPic2NqG2PXCanbE3ZYzP3qA", ); export const SHARED_LIQUIDITY_MANAGER_PROGRAM_ID = new PublicKey( - "EoJc1PYxZbnCjszampLcwJGYcB5Md47jM4oSQacRtD4d" + "EoJc1PYxZbnCjszampLcwJGYcB5Md47jM4oSQacRtD4d", ); export const MPL_TOKEN_METADATA_PROGRAM_ID = new PublicKey( - "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" + "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s", ); export const RAYDIUM_CP_SWAP_PROGRAM_ID = new PublicKey( - "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C" + "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C", ); export const DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID = new PublicKey( - "CPMDWBwJDtYax9qW7AyRuVC19Cc4L4Vcy4n2BHAbHkCW" + "CPMDWBwJDtYax9qW7AyRuVC19Cc4L4Vcy4n2BHAbHkCW", ); export const META_MINT = new PublicKey( - "3gN1WVEJwSHNWjo7hr87DgZp6zkf8kWgAJD29DmfE2Gr" + "3gN1WVEJwSHNWjo7hr87DgZp6zkf8kWgAJD29DmfE2Gr", ); export const MAINNET_USDC = new PublicKey( - "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", ); export const DEVNET_USDC = new PublicKey( - "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" + "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", ); export const USDC_DECIMALS = 6; @@ -47,16 +47,16 @@ export const AUTOCRAT_LUTS: PublicKey[] = []; export const RAYDIUM_AUTHORITY = PublicKey.findProgramAddressSync( [anchor.utils.bytes.utf8.encode("vault_and_lp_mint_auth_seed")], - RAYDIUM_CP_SWAP_PROGRAM_ID + RAYDIUM_CP_SWAP_PROGRAM_ID, )[0]; export const DEVNET_RAYDIUM_AUTHORITY = PublicKey.findProgramAddressSync( [anchor.utils.bytes.utf8.encode("vault_and_lp_mint_auth_seed")], - DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID + DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID, )[0]; export const LOW_FEE_RAYDIUM_CONFIG = new PublicKey( - "D4FPEruKEHrG5TenZ2mpDGEfu1iUvTiqBxvpU8HLBvC2" + "D4FPEruKEHrG5TenZ2mpDGEfu1iUvTiqBxvpU8HLBvC2", ); export const DEVNET_LOW_FEE_RAYDIUM_CONFIG = PublicKey.findProgramAddressSync( @@ -64,27 +64,27 @@ export const DEVNET_LOW_FEE_RAYDIUM_CONFIG = PublicKey.findProgramAddressSync( anchor.utils.bytes.utf8.encode("amm_config"), new BN(0).toArrayLike(Buffer, "be", 2), ], - DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID + DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID, )[0]; export const RAYDIUM_CREATE_POOL_FEE_RECEIVE = new PublicKey( - "DNXgeM9EiiaAbaWvwjHj9fQQLAX5ZsfHyvmYUNRAdNC8" + "DNXgeM9EiiaAbaWvwjHj9fQQLAX5ZsfHyvmYUNRAdNC8", ); export const DEVNET_RAYDIUM_CREATE_POOL_FEE_RECEIVE = new PublicKey( - "G11FKBRaAkHAKuLCgLM6K6NUc9rTjPAznRCjZifrTQe2" + "G11FKBRaAkHAKuLCgLM6K6NUc9rTjPAznRCjZifrTQe2", ); export const SQUADS_PROGRAM_CONFIG = new PublicKey( - "BSTq9w3kZwNwpBXJEvTZz2G9ZTNyKBvoSeXMvwb4cNZr" + "BSTq9w3kZwNwpBXJEvTZz2G9ZTNyKBvoSeXMvwb4cNZr", ); export const SQUADS_PROGRAM_ID = new PublicKey( - "SQDS4ep65T869zMMBKyuUq6aD6EgTu8psMjkvj52pCf" + "SQDS4ep65T869zMMBKyuUq6aD6EgTu8psMjkvj52pCf", ); export const SQUADS_PROGRAM_CONFIG_TREASURY = new PublicKey( - "5DH2e3cJmFpyi6mk65EGFediunm4ui6BiKNUNrhWtD1b" + "5DH2e3cJmFpyi6mk65EGFediunm4ui6BiKNUNrhWtD1b", ); export const PERMISSIONLESS_ACCOUNT = Keypair.fromSecretKey( @@ -93,5 +93,5 @@ export const PERMISSIONLESS_ACCOUNT = Keypair.fromSecretKey( 161, 209, 65, 217, 199, 121, 0, 250, 3, 203, 133, 138, 141, 112, 243, 38, 198, 205, 120, 222, 160, 224, 151, 190, 84, 254, 127, 178, 224, 195, 130, 243, 145, 73, 20, 91, 9, 69, 222, 184, 23, 1, 2, 196, 202, 206, 153, 192, - ]) + ]), ); diff --git a/sdk/src/v0.5/types/amm.ts b/sdk/src/v0.5/types/amm.ts index 82a44b23..6d36be8d 100644 --- a/sdk/src/v0.5/types/amm.ts +++ b/sdk/src/v0.5/types/amm.ts @@ -64,7 +64,7 @@ export type Amm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -72,7 +72,7 @@ export type Amm = { type: { defined: "CreateAmmArgs"; }; - } + }, ]; }, { @@ -132,7 +132,7 @@ export type Amm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -140,7 +140,7 @@ export type Amm = { type: { defined: "AddLiquidityArgs"; }; - } + }, ]; }, { @@ -200,7 +200,7 @@ export type Amm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -208,7 +208,7 @@ export type Amm = { type: { defined: "RemoveLiquidityArgs"; }; - } + }, ]; }, { @@ -258,7 +258,7 @@ export type Amm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -266,7 +266,7 @@ export type Amm = { type: { defined: "SwapArgs"; }; - } + }, ]; }, { @@ -286,10 +286,10 @@ export type Amm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: []; - } + }, ]; accounts: [ { @@ -350,10 +350,10 @@ export type Amm = { { name: "vaultAtaQuote"; type: "publicKey"; - } + }, ]; }; - } + }, ]; types: [ { @@ -400,7 +400,7 @@ export type Amm = { { name: "seqNum"; type: "u64"; - } + }, ]; }; }, @@ -423,7 +423,7 @@ export type Amm = { name: "minLpTokens"; docs: ["The minimum LP token you will get back"]; type: "u64"; - } + }, ]; }; }, @@ -443,7 +443,7 @@ export type Amm = { { name: "twapStartDelaySlots"; type: "u64"; - } + }, ]; }; }, @@ -463,7 +463,7 @@ export type Amm = { { name: "minBaseAmount"; type: "u64"; - } + }, ]; }; }, @@ -485,7 +485,7 @@ export type Amm = { { name: "outputAmountMin"; type: "u64"; - } + }, ]; }; }, @@ -504,7 +504,7 @@ export type Amm = { "A price is the number of quote units per base unit multiplied by 1e12.", "You cannot simply divide by 1e12 to get a price you can display in the UI", "because the base and quote decimals may be different. Instead, do:", - "ui_price = (price * (10**(base_decimals - quote_decimals))) / 1e12" + "ui_price = (price * (10**(base_decimals - quote_decimals))) / 1e12", ]; type: "u128"; }, @@ -513,7 +513,7 @@ export type Amm = { docs: [ "If we did a raw TWAP over prices, someone could push the TWAP heavily with", "a few extremely large outliers. So we use observations, which can only move", - "by `max_observation_change_per_update` per update." + "by `max_observation_change_per_update` per update.", ]; type: "u128"; }, @@ -533,7 +533,7 @@ export type Amm = { "", "So in the case of an overflow, the aggregator rolls back to 0. It's the", "client's responsibility to sanity check the assets or to handle an", - "aggregator at T2 being smaller than an aggregator at T1." + "aggregator at T2 being smaller than an aggregator at T1.", ]; type: "u128"; }, @@ -550,10 +550,10 @@ export type Amm = { { name: "startDelaySlots"; docs: [ - "Number of slots after amm.created_at_slot to start recording TWAP" + "Number of slots after amm.created_at_slot to start recording TWAP", ]; type: "u64"; - } + }, ]; }; }, @@ -567,10 +567,10 @@ export type Amm = { }, { name: "Sell"; - } + }, ]; }; - } + }, ]; events: [ { @@ -599,7 +599,7 @@ export type Amm = { defined: "SwapType"; }; index: false; - } + }, ]; }, { @@ -636,7 +636,7 @@ export type Amm = { name: "lpTokensMinted"; type: "u64"; index: false; - } + }, ]; }, { @@ -673,7 +673,7 @@ export type Amm = { name: "quoteAmount"; type: "u64"; index: false; - } + }, ]; }, { @@ -720,7 +720,7 @@ export type Amm = { name: "vaultAtaQuote"; type: "publicKey"; index: false; - } + }, ]; }, { @@ -732,9 +732,9 @@ export type Amm = { defined: "CommonFields"; }; index: false; - } + }, ]; - } + }, ]; errors: [ { @@ -826,7 +826,7 @@ export type Amm = { code: 6017; name: "CastingOverflow"; msg: "Casting has caused an overflow"; - } + }, ]; }; diff --git a/sdk/src/v0.5/types/autocrat.ts b/sdk/src/v0.5/types/autocrat.ts index 506bc301..9250f0e0 100644 --- a/sdk/src/v0.5/types/autocrat.ts +++ b/sdk/src/v0.5/types/autocrat.ts @@ -74,7 +74,7 @@ export type Autocrat = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -82,7 +82,7 @@ export type Autocrat = { type: { defined: "InitializeDaoParams"; }; - } + }, ]; }, { @@ -192,7 +192,7 @@ export type Autocrat = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -200,7 +200,7 @@ export type Autocrat = { type: { defined: "InitializeProposalParams"; }; - } + }, ]; }, { @@ -290,7 +290,7 @@ export type Autocrat = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: []; }, @@ -316,7 +316,7 @@ export type Autocrat = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -324,9 +324,91 @@ export type Autocrat = { type: { defined: "UpdateDaoParams"; }; - } + }, ]; - } + }, + { + name: "executeSpendingLimitChange"; + accounts: [ + { + name: "proposal"; + isMut: true; + isSigner: false; + }, + { + name: "dao"; + isMut: true; + isSigner: false; + }, + { + name: "squadsProposal"; + isMut: true; + isSigner: false; + }, + { + name: "squadsMultisig"; + isMut: false; + isSigner: false; + }, + { + name: "squadsMultisigProgram"; + isMut: false; + isSigner: false; + }, + { + name: "vaultTransaction"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + }, + ]; + args: []; + }, + { + name: "upgradeMultisigDao"; + accounts: [ + { + name: "dao"; + isMut: true; + isSigner: false; + }, + { + name: "squadsMultisig"; + isMut: true; + isSigner: false; + }, + { + name: "squadsMultisigProgram"; + isMut: false; + isSigner: false; + }, + { + name: "rentPayer"; + isMut: true; + isSigner: true; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "kollan"; + isMut: false; + isSigner: true; + }, + ]; + args: []; + }, ]; accounts: [ { @@ -391,7 +473,7 @@ export type Autocrat = { "observation of 400 (converted into the AMM prices) and a max observation change per", "update of 8 (also converted into the AMM prices). Observations can be updated once", "a minute, so 2% allows the proposal market to reach double the spot price or 0", - "in 50 minutes." + "in 50 minutes.", ]; type: "u128"; }, @@ -402,7 +484,7 @@ export type Autocrat = { { name: "twapStartDelaySlots"; docs: [ - "Forces TWAP calculation to start after amm.created_at_slot + twap_start_delay_slots" + "Forces TWAP calculation to start after amm.created_at_slot + twap_start_delay_slots", ]; type: "u64"; }, @@ -414,7 +496,7 @@ export type Autocrat = { "", "For example, for META, we can use a `min_quote_futarchic_liquidity` of", "5000 * 1_000_000 (5000 USDC) and a `min_base_futarchic_liquidity` of", - "10 * 1_000_000_000 (10 META)." + "10 * 1_000_000_000 (10 META).", ]; type: "u64"; }, @@ -433,7 +515,7 @@ export type Autocrat = { defined: "InitialSpendingLimit"; }; }; - } + }, ]; }; }, @@ -507,10 +589,10 @@ export type Autocrat = { { name: "squadsProposal"; type: "publicKey"; - } + }, ]; }; - } + }, ]; types: [ { @@ -525,7 +607,7 @@ export type Autocrat = { { name: "unixTimestamp"; type: "i64"; - } + }, ]; }; }, @@ -573,7 +655,7 @@ export type Autocrat = { defined: "InitialSpendingLimit"; }; }; - } + }, ]; }; }, @@ -593,7 +675,7 @@ export type Autocrat = { { name: "failLpTokensToLock"; type: "u64"; - } + }, ]; }; }, @@ -637,7 +719,7 @@ export type Autocrat = { type: { option: "u64"; }; - } + }, ]; }; }, @@ -655,7 +737,7 @@ export type Autocrat = { type: { vec: "publicKey"; }; - } + }, ]; }; }, @@ -672,10 +754,10 @@ export type Autocrat = { }, { name: "Failed"; - } + }, ]; }; - } + }, ]; events: [ { @@ -751,7 +833,7 @@ export type Autocrat = { name: "squadsMultisigVault"; type: "publicKey"; index: false; - } + }, ]; }, { @@ -798,7 +880,7 @@ export type Autocrat = { name: "minBaseFutarchicLiquidity"; type: "u64"; index: false; - } + }, ]; }, { @@ -900,7 +982,7 @@ export type Autocrat = { name: "squadsMultisigVault"; type: "publicKey"; index: false; - } + }, ]; }, { @@ -954,7 +1036,7 @@ export type Autocrat = { name: "squadsMultisig"; type: "publicKey"; index: false; - } + }, ]; }, { @@ -976,9 +1058,9 @@ export type Autocrat = { name: "dao"; type: "publicKey"; index: false; - } + }, ]; - } + }, ]; errors: [ { @@ -1055,7 +1137,12 @@ export type Autocrat = { code: 6014; name: "InvalidSquadsProposalStatus"; msg: "Squads proposal must be in Draft status"; - } + }, + { + code: 6015; + name: "InvalidTransaction"; + msg: "This Squads transaction should only contain calls to update spending limits"; + }, ]; }; @@ -1388,6 +1475,88 @@ export const IDL: Autocrat = { }, ], }, + { + name: "executeSpendingLimitChange", + accounts: [ + { + name: "proposal", + isMut: true, + isSigner: false, + }, + { + name: "dao", + isMut: true, + isSigner: false, + }, + { + name: "squadsProposal", + isMut: true, + isSigner: false, + }, + { + name: "squadsMultisig", + isMut: false, + isSigner: false, + }, + { + name: "squadsMultisigProgram", + isMut: false, + isSigner: false, + }, + { + name: "vaultTransaction", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "upgradeMultisigDao", + accounts: [ + { + name: "dao", + isMut: true, + isSigner: false, + }, + { + name: "squadsMultisig", + isMut: true, + isSigner: false, + }, + { + name: "squadsMultisigProgram", + isMut: false, + isSigner: false, + }, + { + name: "rentPayer", + isMut: true, + isSigner: true, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "kollan", + isMut: false, + isSigner: true, + }, + ], + args: [], + }, ], accounts: [ { @@ -2117,5 +2286,10 @@ export const IDL: Autocrat = { name: "InvalidSquadsProposalStatus", msg: "Squads proposal must be in Draft status", }, + { + code: 6015, + name: "InvalidTransaction", + msg: "This Squads transaction should only contain calls to update spending limits", + }, ], }; diff --git a/sdk/src/v0.5/types/autocrat_migrator.ts b/sdk/src/v0.5/types/autocrat_migrator.ts index 05f5d3fc..676d2df3 100644 --- a/sdk/src/v0.5/types/autocrat_migrator.ts +++ b/sdk/src/v0.5/types/autocrat_migrator.ts @@ -44,7 +44,7 @@ export type AutocratMigrator = { name: "lamportReceiver"; isMut: true; isSigner: false; - } + }, ]; args: []; }, @@ -110,10 +110,10 @@ export type AutocratMigrator = { name: "lamportReceiver"; isMut: true; isSigner: false; - } + }, ]; args: []; - } + }, ]; }; diff --git a/sdk/src/v0.5/types/conditional_vault.ts b/sdk/src/v0.5/types/conditional_vault.ts index fd83c4bf..27c245b7 100644 --- a/sdk/src/v0.5/types/conditional_vault.ts +++ b/sdk/src/v0.5/types/conditional_vault.ts @@ -29,7 +29,7 @@ export type ConditionalVault = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -37,7 +37,7 @@ export type ConditionalVault = { type: { defined: "InitializeQuestionArgs"; }; - } + }, ]; }, { @@ -62,7 +62,7 @@ export type ConditionalVault = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -70,7 +70,7 @@ export type ConditionalVault = { type: { defined: "ResolveQuestionArgs"; }; - } + }, ]; }, { @@ -125,7 +125,7 @@ export type ConditionalVault = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: []; }, @@ -171,13 +171,13 @@ export type ConditionalVault = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { name: "amount"; type: "u64"; - } + }, ]; }, { @@ -222,13 +222,13 @@ export type ConditionalVault = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { name: "amount"; type: "u64"; - } + }, ]; }, { @@ -273,7 +273,7 @@ export type ConditionalVault = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: []; }, @@ -324,7 +324,7 @@ export type ConditionalVault = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -332,9 +332,9 @@ export type ConditionalVault = { type: { defined: "AddMetadataToConditionalTokensArgs"; }; - } + }, ]; - } + }, ]; accounts: [ { @@ -371,7 +371,7 @@ export type ConditionalVault = { { name: "seqNum"; type: "u64"; - } + }, ]; }; }, @@ -397,7 +397,7 @@ export type ConditionalVault = { 'effective, the "effective" outcome would resolve to 0.7 and the "ineffective"', "outcome would resolve to 0.3.", "", - "Once resolved, the sum of all outcome resolutions is exactly 1." + "Once resolved, the sum of all outcome resolutions is exactly 1.", ]; type: { kind: "struct"; @@ -421,10 +421,10 @@ export type ConditionalVault = { { name: "payoutDenominator"; type: "u32"; - } + }, ]; }; - } + }, ]; types: [ { @@ -439,7 +439,7 @@ export type ConditionalVault = { { name: "unixTimestamp"; type: "i64"; - } + }, ]; }; }, @@ -459,7 +459,7 @@ export type ConditionalVault = { { name: "uri"; type: "string"; - } + }, ]; }; }, @@ -481,7 +481,7 @@ export type ConditionalVault = { { name: "numOutcomes"; type: "u8"; - } + }, ]; }; }, @@ -495,7 +495,7 @@ export type ConditionalVault = { type: { vec: "u32"; }; - } + }, ]; }; }, @@ -512,10 +512,10 @@ export type ConditionalVault = { }, { name: "Reverted"; - } + }, ]; }; - } + }, ]; events: [ { @@ -562,7 +562,7 @@ export type ConditionalVault = { name: "seqNum"; type: "u64"; index: false; - } + }, ]; }, { @@ -611,7 +611,7 @@ export type ConditionalVault = { name: "seqNum"; type: "u64"; index: false; - } + }, ]; }, { @@ -645,7 +645,7 @@ export type ConditionalVault = { name: "question"; type: "publicKey"; index: false; - } + }, ]; }, { @@ -701,7 +701,7 @@ export type ConditionalVault = { name: "seqNum"; type: "u64"; index: false; - } + }, ]; }, { @@ -750,7 +750,7 @@ export type ConditionalVault = { name: "seqNum"; type: "u64"; index: false; - } + }, ]; }, { @@ -774,7 +774,7 @@ export type ConditionalVault = { vec: "u32"; }; index: false; - } + }, ]; }, { @@ -830,9 +830,9 @@ export type ConditionalVault = { name: "seqNum"; type: "u64"; index: false; - } + }, ]; - } + }, ]; errors: [ { @@ -919,7 +919,7 @@ export type ConditionalVault = { code: 6016; name: "UnauthorizedConditionalTokenAccount"; msg: "Conditional token account is not owned by the authority"; - } + }, ]; }; diff --git a/sdk/src/v0.5/types/futarchy_amm.ts b/sdk/src/v0.5/types/futarchy_amm.ts index 01c21519..c1aef0d1 100644 --- a/sdk/src/v0.5/types/futarchy_amm.ts +++ b/sdk/src/v0.5/types/futarchy_amm.ts @@ -64,7 +64,7 @@ export type FutarchyAmm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -72,7 +72,7 @@ export type FutarchyAmm = { type: { defined: "CreateAmmArgs"; }; - } + }, ]; }, { @@ -132,7 +132,7 @@ export type FutarchyAmm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -140,7 +140,7 @@ export type FutarchyAmm = { type: { defined: "AddLiquidityArgs"; }; - } + }, ]; }, { @@ -200,7 +200,7 @@ export type FutarchyAmm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -208,7 +208,7 @@ export type FutarchyAmm = { type: { defined: "RemoveLiquidityArgs"; }; - } + }, ]; }, { @@ -258,7 +258,7 @@ export type FutarchyAmm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -266,7 +266,7 @@ export type FutarchyAmm = { type: { defined: "SwapArgs"; }; - } + }, ]; }, { @@ -286,10 +286,10 @@ export type FutarchyAmm = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: []; - } + }, ]; accounts: [ { @@ -350,10 +350,10 @@ export type FutarchyAmm = { { name: "vaultAtaQuote"; type: "publicKey"; - } + }, ]; }; - } + }, ]; types: [ { @@ -400,7 +400,7 @@ export type FutarchyAmm = { { name: "seqNum"; type: "u64"; - } + }, ]; }; }, @@ -423,7 +423,7 @@ export type FutarchyAmm = { name: "minLpTokens"; docs: ["The minimum LP token you will get back"]; type: "u64"; - } + }, ]; }; }, @@ -443,7 +443,7 @@ export type FutarchyAmm = { { name: "twapStartDelaySlots"; type: "u64"; - } + }, ]; }; }, @@ -463,7 +463,7 @@ export type FutarchyAmm = { { name: "minBaseAmount"; type: "u64"; - } + }, ]; }; }, @@ -485,7 +485,7 @@ export type FutarchyAmm = { { name: "outputAmountMin"; type: "u64"; - } + }, ]; }; }, @@ -504,7 +504,7 @@ export type FutarchyAmm = { "A price is the number of quote units per base unit multiplied by 1e12.", "You cannot simply divide by 1e12 to get a price you can display in the UI", "because the base and quote decimals may be different. Instead, do:", - "ui_price = (price * (10**(base_decimals - quote_decimals))) / 1e12" + "ui_price = (price * (10**(base_decimals - quote_decimals))) / 1e12", ]; type: "u128"; }, @@ -513,7 +513,7 @@ export type FutarchyAmm = { docs: [ "If we did a raw TWAP over prices, someone could push the TWAP heavily with", "a few extremely large outliers. So we use observations, which can only move", - "by `max_observation_change_per_update` per update." + "by `max_observation_change_per_update` per update.", ]; type: "u128"; }, @@ -533,7 +533,7 @@ export type FutarchyAmm = { "", "So in the case of an overflow, the aggregator rolls back to 0. It's the", "client's responsibility to sanity check the assets or to handle an", - "aggregator at T2 being smaller than an aggregator at T1." + "aggregator at T2 being smaller than an aggregator at T1.", ]; type: "u128"; }, @@ -550,10 +550,10 @@ export type FutarchyAmm = { { name: "startDelaySlots"; docs: [ - "Number of slots after amm.created_at_slot to start recording TWAP" + "Number of slots after amm.created_at_slot to start recording TWAP", ]; type: "u64"; - } + }, ]; }; }, @@ -567,10 +567,10 @@ export type FutarchyAmm = { }, { name: "Sell"; - } + }, ]; }; - } + }, ]; events: [ { @@ -599,7 +599,7 @@ export type FutarchyAmm = { defined: "SwapType"; }; index: false; - } + }, ]; }, { @@ -636,7 +636,7 @@ export type FutarchyAmm = { name: "lpTokensMinted"; type: "u64"; index: false; - } + }, ]; }, { @@ -673,7 +673,7 @@ export type FutarchyAmm = { name: "quoteAmount"; type: "u64"; index: false; - } + }, ]; }, { @@ -720,7 +720,7 @@ export type FutarchyAmm = { name: "vaultAtaQuote"; type: "publicKey"; index: false; - } + }, ]; }, { @@ -732,9 +732,9 @@ export type FutarchyAmm = { defined: "CommonFields"; }; index: false; - } + }, ]; - } + }, ]; errors: [ { @@ -826,7 +826,7 @@ export type FutarchyAmm = { code: 6017; name: "CastingOverflow"; msg: "Casting has caused an overflow"; - } + }, ]; }; diff --git a/sdk/src/v0.5/types/launchpad.ts b/sdk/src/v0.5/types/launchpad.ts index caddccc2..0af6abd3 100644 --- a/sdk/src/v0.5/types/launchpad.ts +++ b/sdk/src/v0.5/types/launchpad.ts @@ -84,7 +84,7 @@ export type Launchpad = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { @@ -92,7 +92,7 @@ export type Launchpad = { type: { defined: "InitializeLaunchArgs"; }; - } + }, ]; }, { @@ -117,7 +117,7 @@ export type Launchpad = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: []; }, @@ -178,13 +178,13 @@ export type Launchpad = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: [ { name: "amount"; type: "u64"; - } + }, ]; }, { @@ -318,7 +318,7 @@ export type Launchpad = { isMut: true; isSigner: false; docs: [ - "Use the lowest fee pool, can see fees at https://api-v3.raydium.io/main/cpmm-config" + "Use the lowest fee pool, can see fees at https://api-v3.raydium.io/main/cpmm-config", ]; }, { @@ -366,7 +366,7 @@ export type Launchpad = { name: "squadsProgramConfigTreasury"; isMut: true; isSigner: false; - } + }, ]; }, { @@ -378,7 +378,7 @@ export type Launchpad = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: []; }, @@ -434,7 +434,7 @@ export type Launchpad = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: []; }, @@ -500,10 +500,10 @@ export type Launchpad = { name: "program"; isMut: false; isSigner: false; - } + }, ]; args: []; - } + }, ]; accounts: [ { @@ -534,10 +534,10 @@ export type Launchpad = { { name: "seqNum"; docs: [ - "The sequence number of this funding record. Useful for sorting events." + "The sequence number of this funding record. Useful for sorting events.", ]; type: "u64"; - } + }, ]; }; }, @@ -555,7 +555,7 @@ export type Launchpad = { name: "minimumRaiseAmount"; docs: [ "The minimum amount of USDC that must be raised, otherwise", - "everyone can get their USDC back." + "everyone can get their USDC back.", ]; type: "u64"; }, @@ -563,14 +563,14 @@ export type Launchpad = { name: "monthlySpendingLimitAmount"; docs: [ "The monthly spending limit the DAO allocates to the team. Must be", - "less than 1/6th of the minimum raise amount (so 6 months of burn)." + "less than 1/6th of the minimum raise amount (so 6 months of burn).", ]; type: "u64"; }, { name: "monthlySpendingLimitMembers"; docs: [ - "The wallets that have access to the monthly spending limit." + "The wallets that have access to the monthly spending limit.", ]; type: { vec: "publicKey"; @@ -584,7 +584,7 @@ export type Launchpad = { { name: "launchSigner"; docs: [ - "The launch signer address. Needed because Raydium pools need a SOL payer and this PDA can't hold SOL." + "The launch signer address. Needed because Raydium pools need a SOL payer and this PDA can't hold SOL.", ]; type: "publicKey"; }, @@ -596,7 +596,7 @@ export type Launchpad = { { name: "launchQuoteVault"; docs: [ - "The USDC vault that will hold the USDC raised until the launch is over." + "The USDC vault that will hold the USDC raised until the launch is over.", ]; type: "publicKey"; }, @@ -608,7 +608,7 @@ export type Launchpad = { { name: "baseMint"; docs: [ - "The token that will be minted to funders and that will control the DAO." + "The token that will be minted to funders and that will control the DAO.", ]; type: "publicKey"; }, @@ -637,7 +637,7 @@ export type Launchpad = { { name: "seqNum"; docs: [ - "The sequence number of this launch. Useful for sorting events." + "The sequence number of this launch. Useful for sorting events.", ]; type: "u64"; }, @@ -656,15 +656,15 @@ export type Launchpad = { { name: "daoVault"; docs: [ - "The DAO treasury that USDC / LP is sent to, if the launch is complete." + "The DAO treasury that USDC / LP is sent to, if the launch is complete.", ]; type: { option: "publicKey"; }; - } + }, ]; }; - } + }, ]; types: [ { @@ -683,7 +683,7 @@ export type Launchpad = { { name: "launchSeqNum"; type: "u64"; - } + }, ]; }; }, @@ -721,7 +721,7 @@ export type Launchpad = { { name: "tokenUri"; type: "string"; - } + }, ]; }; }, @@ -741,10 +741,10 @@ export type Launchpad = { }, { name: "Refunding"; - } + }, ]; }; - } + }, ]; events: [ { @@ -811,7 +811,7 @@ export type Launchpad = { name: "secondsForLaunch"; type: "u32"; index: false; - } + }, ]; }, { @@ -838,7 +838,7 @@ export type Launchpad = { name: "slotStarted"; type: "u64"; index: false; - } + }, ]; }, { @@ -885,7 +885,7 @@ export type Launchpad = { name: "fundingRecordSeqNum"; type: "u64"; index: false; - } + }, ]; }, { @@ -928,7 +928,7 @@ export type Launchpad = { option: "publicKey"; }; index: false; - } + }, ]; }, { @@ -960,7 +960,7 @@ export type Launchpad = { name: "fundingRecord"; type: "publicKey"; index: false; - } + }, ]; }, { @@ -992,9 +992,9 @@ export type Launchpad = { name: "fundingRecord"; type: "publicKey"; index: false; - } + }, ]; - } + }, ]; errors: [ { @@ -1056,7 +1056,7 @@ export type Launchpad = { code: 6011; name: "InvalidMonthlySpendingLimit"; msg: "Monthly spending limit must be less than 1/6th of the minimum raise amount"; - } + }, ]; }; diff --git a/sdk/src/v0.5/types/optimistic_timelock.ts b/sdk/src/v0.5/types/optimistic_timelock.ts index dda1fa46..fa1f4313 100644 --- a/sdk/src/v0.5/types/optimistic_timelock.ts +++ b/sdk/src/v0.5/types/optimistic_timelock.ts @@ -14,7 +14,7 @@ export type OptimisticTimelock = { name: "timelock"; isMut: true; isSigner: true; - } + }, ]; args: [ { @@ -34,7 +34,7 @@ export type OptimisticTimelock = { { name: "enqueuerCooldownSlots"; type: "u64"; - } + }, ]; }, { @@ -49,13 +49,13 @@ export type OptimisticTimelock = { name: "timelock"; isMut: true; isSigner: false; - } + }, ]; args: [ { name: "delayInSlots"; type: "u64"; - } + }, ]; }, { @@ -70,13 +70,13 @@ export type OptimisticTimelock = { name: "timelock"; isMut: true; isSigner: false; - } + }, ]; args: [ { name: "authority"; type: "publicKey"; - } + }, ]; }, { @@ -91,13 +91,13 @@ export type OptimisticTimelock = { name: "timelock"; isMut: true; isSigner: false; - } + }, ]; args: [ { name: "cooldownSlots"; type: "u64"; - } + }, ]; }, { @@ -112,13 +112,13 @@ export type OptimisticTimelock = { name: "timelock"; isMut: true; isSigner: false; - } + }, ]; args: [ { name: "enqueuer"; type: "publicKey"; - } + }, ]; }, { @@ -133,13 +133,13 @@ export type OptimisticTimelock = { name: "timelock"; isMut: true; isSigner: false; - } + }, ]; args: [ { name: "optimisticProposer"; type: "publicKey"; - } + }, ]; }, { @@ -159,7 +159,7 @@ export type OptimisticTimelock = { name: "transactionBatch"; isMut: true; isSigner: true; - } + }, ]; args: []; }, @@ -175,7 +175,7 @@ export type OptimisticTimelock = { name: "transactionBatch"; isMut: true; isSigner: false; - } + }, ]; args: [ { @@ -193,7 +193,7 @@ export type OptimisticTimelock = { { name: "data"; type: "bytes"; - } + }, ]; }, { @@ -208,7 +208,7 @@ export type OptimisticTimelock = { name: "transactionBatch"; isMut: true; isSigner: false; - } + }, ]; args: []; }, @@ -229,7 +229,7 @@ export type OptimisticTimelock = { name: "transactionBatch"; isMut: true; isSigner: false; - } + }, ]; args: []; }, @@ -250,7 +250,7 @@ export type OptimisticTimelock = { name: "transactionBatch"; isMut: true; isSigner: false; - } + }, ]; args: []; }, @@ -271,10 +271,10 @@ export type OptimisticTimelock = { name: "transactionBatch"; isMut: true; isSigner: false; - } + }, ]; args: []; - } + }, ]; accounts: [ { @@ -305,10 +305,10 @@ export type OptimisticTimelock = { { name: "optimisticProposerCooldownSlots"; docs: [ - "The cooldown period for enqueuers to prevent spamming the timelock." + "The cooldown period for enqueuers to prevent spamming the timelock.", ]; type: "u64"; - } + }, ]; }; }, @@ -348,10 +348,10 @@ export type OptimisticTimelock = { type: { defined: "AuthorityType"; }; - } + }, ]; }; - } + }, ]; types: [ { @@ -366,7 +366,7 @@ export type OptimisticTimelock = { { name: "lastSlotEnqueued"; type: "u64"; - } + }, ]; }; }, @@ -394,7 +394,7 @@ export type OptimisticTimelock = { { name: "didExecute"; type: "bool"; - } + }, ]; }; }, @@ -414,7 +414,7 @@ export type OptimisticTimelock = { { name: "isWritable"; type: "bool"; - } + }, ]; }; }, @@ -428,7 +428,7 @@ export type OptimisticTimelock = { }, { name: "TimelockAuthority"; - } + }, ]; }; }, @@ -451,10 +451,10 @@ export type OptimisticTimelock = { }, { name: "Executed"; - } + }, ]; }; - } + }, ]; errors: [ { @@ -506,7 +506,7 @@ export type OptimisticTimelock = { code: 6009; name: "OptimisticProposerCooldown"; msg: "This optimistic proposer is still in its cooldown period"; - } + }, ]; }; diff --git a/sdk/src/v0.5/types/redemption.ts b/sdk/src/v0.5/types/redemption.ts new file mode 100644 index 00000000..bf2146e6 --- /dev/null +++ b/sdk/src/v0.5/types/redemption.ts @@ -0,0 +1,343 @@ +export type Redemption = { + version: "0.1.0"; + name: "redemption"; + instructions: [ + { + name: "initRedemptionConfig"; + accounts: [ + { + name: "authority"; + isMut: true; + isSigner: true; + }, + { + name: "redeemConfig"; + isMut: true; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: "maxRedeemAmount"; + type: "u64"; + }, + { + name: "burnToken"; + type: "bool"; + }, + ]; + }, + { + name: "triggerRedemption"; + accounts: [ + { + name: "redemption"; + isMut: true; + isSigner: false; + }, + { + name: "redeemConfig"; + isMut: true; + isSigner: false; + }, + { + name: "incomingMint"; + isMut: false; + isSigner: false; + }, + { + name: "vault"; + isMut: true; + isSigner: false; + }, + { + name: "user"; + isMut: false; + isSigner: true; + }, + { + name: "userIncomingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userOutgoingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: "amount"; + type: "u64"; + }, + ]; + }, + ]; + accounts: [ + { + name: "redemption"; + type: { + kind: "struct"; + fields: [ + { + name: "authority"; + type: "publicKey"; + }, + { + name: "maxRedeemAmount"; + type: "u64"; + }, + { + name: "incomingMint"; + type: "publicKey"; + }, + { + name: "vault"; + type: "publicKey"; + }, + { + name: "burnToken"; + type: "bool"; + }, + { + name: "redeemedAmount"; + type: "u64"; + }, + { + name: "bump"; + type: "u8"; + }, + ]; + }; + }, + { + name: "redeemConfig"; + type: { + kind: "struct"; + fields: [ + { + name: "authority"; + type: "publicKey"; + }, + { + name: "maxRedeemAmount"; + type: "u64"; + }, + { + name: "burnToken"; + type: "bool"; + }, + { + name: "bump"; + type: "u8"; + }, + ]; + }; + }, + ]; + errors: [ + { + code: 6000; + name: "RedeemAmountExceedsMaxRedeemAmount"; + msg: "Redeem amount exceeds max redeem amount"; + }, + { + code: 6001; + name: "Overflow"; + msg: "Overflow"; + }, + ]; +}; + +export const IDL: Redemption = { + version: "0.1.0", + name: "redemption", + instructions: [ + { + name: "initRedemptionConfig", + accounts: [ + { + name: "authority", + isMut: true, + isSigner: true, + }, + { + name: "redeemConfig", + isMut: true, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "maxRedeemAmount", + type: "u64", + }, + { + name: "burnToken", + type: "bool", + }, + ], + }, + { + name: "triggerRedemption", + accounts: [ + { + name: "redemption", + isMut: true, + isSigner: false, + }, + { + name: "redeemConfig", + isMut: true, + isSigner: false, + }, + { + name: "incomingMint", + isMut: false, + isSigner: false, + }, + { + name: "vault", + isMut: true, + isSigner: false, + }, + { + name: "user", + isMut: false, + isSigner: true, + }, + { + name: "userIncomingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "userOutgoingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "amount", + type: "u64", + }, + ], + }, + ], + accounts: [ + { + name: "redemption", + type: { + kind: "struct", + fields: [ + { + name: "authority", + type: "publicKey", + }, + { + name: "maxRedeemAmount", + type: "u64", + }, + { + name: "incomingMint", + type: "publicKey", + }, + { + name: "vault", + type: "publicKey", + }, + { + name: "burnToken", + type: "bool", + }, + { + name: "redeemedAmount", + type: "u64", + }, + { + name: "bump", + type: "u8", + }, + ], + }, + }, + { + name: "redeemConfig", + type: { + kind: "struct", + fields: [ + { + name: "authority", + type: "publicKey", + }, + { + name: "maxRedeemAmount", + type: "u64", + }, + { + name: "burnToken", + type: "bool", + }, + { + name: "bump", + type: "u8", + }, + ], + }, + }, + ], + errors: [ + { + code: 6000, + name: "RedeemAmountExceedsMaxRedeemAmount", + msg: "Redeem amount exceeds max redeem amount", + }, + { + code: 6001, + name: "Overflow", + msg: "Overflow", + }, + ], +}; diff --git a/sdk/src/v0.5/types/shared_liquidity_manager.ts b/sdk/src/v0.5/types/shared_liquidity_manager.ts index 1502ffa8..124942da 100644 --- a/sdk/src/v0.5/types/shared_liquidity_manager.ts +++ b/sdk/src/v0.5/types/shared_liquidity_manager.ts @@ -83,7 +83,7 @@ export type SharedLiquidityManager = { code: 6015; name: "QuestionAlreadyResolved"; msg: "Question already resolved"; - } + }, ]; }; diff --git a/sdk/src/v0.5/types/token_converter.ts b/sdk/src/v0.5/types/token_converter.ts new file mode 100644 index 00000000..80fc5e1b --- /dev/null +++ b/sdk/src/v0.5/types/token_converter.ts @@ -0,0 +1,553 @@ +export type TokenConverter = { + version: "0.1.0"; + name: "token_converter"; + instructions: [ + { + name: "initializeTokenConverter"; + accounts: [ + { + name: "tokenConverter"; + isMut: true; + isSigner: false; + }, + { + name: "inboundTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "outboundTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "inboundTokenMint"; + isMut: false; + isSigner: false; + }, + { + name: "outboundTokenMint"; + isMut: false; + isSigner: false; + }, + { + name: "authority"; + isMut: true; + isSigner: true; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: "conversionRatio"; + type: "u64"; + }, + { + name: "nonce"; + type: "u64"; + }, + ]; + }, + { + name: "convert"; + accounts: [ + { + name: "tokenConverter"; + isMut: true; + isSigner: false; + }, + { + name: "authority"; + isMut: true; + isSigner: true; + }, + { + name: "from"; + isMut: true; + isSigner: false; + }, + { + name: "to"; + isMut: true; + isSigner: false; + }, + { + name: "inboundTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "outboundTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "inboundTokenMint"; + isMut: false; + isSigner: false; + }, + { + name: "outboundTokenMint"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: "amount"; + type: "u64"; + }, + ]; + }, + ]; + accounts: [ + { + name: "tokenConverter"; + type: { + kind: "struct"; + fields: [ + { + name: "authority"; + type: "publicKey"; + }, + { + name: "inboundTokenMint"; + type: "publicKey"; + }, + { + name: "outboundTokenMint"; + type: "publicKey"; + }, + { + name: "inboundTokenVault"; + type: "publicKey"; + }, + { + name: "outboundTokenVault"; + type: "publicKey"; + }, + { + name: "inboundTokenDecimals"; + type: "u8"; + }, + { + name: "outboundTokenDecimals"; + type: "u8"; + }, + { + name: "conversionRatio"; + type: "u64"; + }, + { + name: "nonce"; + type: "u64"; + }, + { + name: "bump"; + type: "u8"; + }, + ]; + }; + }, + ]; + events: [ + { + name: "TokensConverted"; + fields: [ + { + name: "user"; + type: "publicKey"; + index: false; + }, + { + name: "tokenConverter"; + type: "publicKey"; + index: false; + }, + { + name: "inboundTokenMint"; + type: "publicKey"; + index: false; + }, + { + name: "outboundTokenMint"; + type: "publicKey"; + index: false; + }, + { + name: "inboundAmount"; + type: "u64"; + index: false; + }, + { + name: "outboundAmount"; + type: "u64"; + index: false; + }, + { + name: "timestamp"; + type: "i64"; + index: false; + }, + ]; + }, + ]; + errors: [ + { + code: 6000; + name: "InvalidAmount"; + msg: "Invalid amount - must be greater than 0"; + }, + { + code: 6001; + name: "InvalidInboundToken"; + msg: "Invalid inbound token mint"; + }, + { + code: 6002; + name: "InvalidOutboundToken"; + msg: "Invalid outbound token mint"; + }, + { + code: 6003; + name: "InvalidConverterInboundTokenAccount"; + msg: "Invalid converter inbound token account"; + }, + { + code: 6004; + name: "InvalidConverterOutboundTokenAccount"; + msg: "Invalid converter outbound token account"; + }, + { + code: 6005; + name: "InvalidAuthority"; + msg: "Invalid authority"; + }, + { + code: 6006; + name: "InsufficientBalance"; + msg: "Insufficient balance"; + }, + { + code: 6007; + name: "InsufficientConverterBalance"; + msg: "Insufficient converter balance"; + }, + { + code: 6008; + name: "ConverterNotActive"; + msg: "Converter not active"; + }, + { + code: 6009; + name: "Overflow"; + msg: "Arithmetic overflow"; + }, + { + code: 6010; + name: "AssertFailed"; + msg: "Assertion failed"; + }, + { + code: 6011; + name: "SameMint"; + msg: "Inbound and outbound mints cannot be the same"; + }, + ]; +}; + +export const IDL: TokenConverter = { + version: "0.1.0", + name: "token_converter", + instructions: [ + { + name: "initializeTokenConverter", + accounts: [ + { + name: "tokenConverter", + isMut: true, + isSigner: false, + }, + { + name: "inboundTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "outboundTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "inboundTokenMint", + isMut: false, + isSigner: false, + }, + { + name: "outboundTokenMint", + isMut: false, + isSigner: false, + }, + { + name: "authority", + isMut: true, + isSigner: true, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "conversionRatio", + type: "u64", + }, + { + name: "nonce", + type: "u64", + }, + ], + }, + { + name: "convert", + accounts: [ + { + name: "tokenConverter", + isMut: true, + isSigner: false, + }, + { + name: "authority", + isMut: true, + isSigner: true, + }, + { + name: "from", + isMut: true, + isSigner: false, + }, + { + name: "to", + isMut: true, + isSigner: false, + }, + { + name: "inboundTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "outboundTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "inboundTokenMint", + isMut: false, + isSigner: false, + }, + { + name: "outboundTokenMint", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "amount", + type: "u64", + }, + ], + }, + ], + accounts: [ + { + name: "tokenConverter", + type: { + kind: "struct", + fields: [ + { + name: "authority", + type: "publicKey", + }, + { + name: "inboundTokenMint", + type: "publicKey", + }, + { + name: "outboundTokenMint", + type: "publicKey", + }, + { + name: "inboundTokenVault", + type: "publicKey", + }, + { + name: "outboundTokenVault", + type: "publicKey", + }, + { + name: "inboundTokenDecimals", + type: "u8", + }, + { + name: "outboundTokenDecimals", + type: "u8", + }, + { + name: "conversionRatio", + type: "u64", + }, + { + name: "nonce", + type: "u64", + }, + { + name: "bump", + type: "u8", + }, + ], + }, + }, + ], + events: [ + { + name: "TokensConverted", + fields: [ + { + name: "user", + type: "publicKey", + index: false, + }, + { + name: "tokenConverter", + type: "publicKey", + index: false, + }, + { + name: "inboundTokenMint", + type: "publicKey", + index: false, + }, + { + name: "outboundTokenMint", + type: "publicKey", + index: false, + }, + { + name: "inboundAmount", + type: "u64", + index: false, + }, + { + name: "outboundAmount", + type: "u64", + index: false, + }, + { + name: "timestamp", + type: "i64", + index: false, + }, + ], + }, + ], + errors: [ + { + code: 6000, + name: "InvalidAmount", + msg: "Invalid amount - must be greater than 0", + }, + { + code: 6001, + name: "InvalidInboundToken", + msg: "Invalid inbound token mint", + }, + { + code: 6002, + name: "InvalidOutboundToken", + msg: "Invalid outbound token mint", + }, + { + code: 6003, + name: "InvalidConverterInboundTokenAccount", + msg: "Invalid converter inbound token account", + }, + { + code: 6004, + name: "InvalidConverterOutboundTokenAccount", + msg: "Invalid converter outbound token account", + }, + { + code: 6005, + name: "InvalidAuthority", + msg: "Invalid authority", + }, + { + code: 6006, + name: "InsufficientBalance", + msg: "Insufficient balance", + }, + { + code: 6007, + name: "InsufficientConverterBalance", + msg: "Insufficient converter balance", + }, + { + code: 6008, + name: "ConverterNotActive", + msg: "Converter not active", + }, + { + code: 6009, + name: "Overflow", + msg: "Arithmetic overflow", + }, + { + code: 6010, + name: "AssertFailed", + msg: "Assertion failed", + }, + { + code: 6011, + name: "SameMint", + msg: "Inbound and outbound mints cannot be the same", + }, + ], +}; diff --git a/sdk/src/v0.5/utils/filters.ts b/sdk/src/v0.5/utils/filters.ts index 945f7731..aee93f61 100644 --- a/sdk/src/v0.5/utils/filters.ts +++ b/sdk/src/v0.5/utils/filters.ts @@ -1,7 +1,7 @@ import { GetProgramAccountsFilter, PublicKey } from "@solana/web3.js"; export const filterPositionsByUser = ( - userAddr: PublicKey + userAddr: PublicKey, ): GetProgramAccountsFilter => ({ memcmp: { offset: 8, // discriminator @@ -10,7 +10,7 @@ export const filterPositionsByUser = ( }); export const filterPositionsByAmm = ( - ammAddr: PublicKey + ammAddr: PublicKey, ): GetProgramAccountsFilter => ({ memcmp: { offset: diff --git a/sdk/src/v0.5/utils/index.ts b/sdk/src/v0.5/utils/index.ts index cb5d012e..ee7438b0 100644 --- a/sdk/src/v0.5/utils/index.ts +++ b/sdk/src/v0.5/utils/index.ts @@ -26,7 +26,7 @@ export const addPriorityFee = (pf: number) => export const pubkeyToAccountInfo = ( pubkey: PublicKey, isWritable: boolean, - isSigner = false + isSigner = false, ): AccountMeta => { return { pubkey: pubkey, diff --git a/sdk/src/v0.5/utils/metadata.ts b/sdk/src/v0.5/utils/metadata.ts index 922a89f3..ef17bbdb 100644 --- a/sdk/src/v0.5/utils/metadata.ts +++ b/sdk/src/v0.5/utils/metadata.ts @@ -16,7 +16,7 @@ export const uploadConditionalTokenMetadataJson = async ( connection: Connection, identityPlugin: UmiPlugin, proposalNumber: number, - symbol: string + symbol: string, // proposal: BN, // conditionalToken: string, // image: string diff --git a/sdk/src/v0.5/utils/pda.ts b/sdk/src/v0.5/utils/pda.ts index 18478c47..ba9fe728 100644 --- a/sdk/src/v0.5/utils/pda.ts +++ b/sdk/src/v0.5/utils/pda.ts @@ -20,7 +20,7 @@ import { LAUNCHPAD_PROGRAM_ID, AUTOCRAT_PROGRAM_ID } from "../constants.js"; export const getEventAuthorityAddr = (programId: PublicKey) => { return PublicKey.findProgramAddressSync( [Buffer.from("__event_authority")], - programId + programId, ); }; @@ -28,7 +28,7 @@ export const getQuestionAddr = ( programId: PublicKey, questionId: Uint8Array, oracle: PublicKey, - numOutcomes: number + numOutcomes: number, ) => { if (questionId.length != 32) { throw new Error("questionId must be 32 bytes"); @@ -41,14 +41,14 @@ export const getQuestionAddr = ( oracle.toBuffer(), new BN(numOutcomes).toArrayLike(Buffer, "le", 1), ], - programId + programId, ); }; export const getVaultAddr = ( programId: PublicKey, question: PublicKey, - underlyingTokenMint: PublicKey + underlyingTokenMint: PublicKey, ) => { return PublicKey.findProgramAddressSync( [ @@ -56,14 +56,14 @@ export const getVaultAddr = ( question.toBuffer(), underlyingTokenMint.toBuffer(), ], - programId + programId, ); }; export const getConditionalTokenMintAddr = ( programId: PublicKey, vault: PublicKey, - index: number + index: number, ) => { return PublicKey.findProgramAddressSync( [ @@ -71,13 +71,13 @@ export const getConditionalTokenMintAddr = ( vault.toBuffer(), new BN(index).toArrayLike(Buffer, "le", 1), ], - programId + programId, ); }; export const getDownAndUpMintAddrs = ( programId: PublicKey, - vault: PublicKey + vault: PublicKey, ): { down: PublicKey; up: PublicKey } => { return { down: getConditionalTokenMintAddr(programId, vault, 0)[0], @@ -87,7 +87,7 @@ export const getDownAndUpMintAddrs = ( export const getFailAndPassMintAddrs = ( programId: PublicKey, - vault: PublicKey + vault: PublicKey, ): { fail: PublicKey; pass: PublicKey } => { return { fail: getConditionalTokenMintAddr(programId, vault, 0)[0], @@ -102,7 +102,7 @@ export const getMetadataAddr = (mint: PublicKey) => { MPL_TOKEN_METADATA_PROGRAM_ID.toBuffer(), mint.toBuffer(), ], - MPL_TOKEN_METADATA_PROGRAM_ID + MPL_TOKEN_METADATA_PROGRAM_ID, ); }; @@ -121,31 +121,31 @@ export const getDaoAddr = ({ daoCreator.toBuffer(), nonce.toArrayLike(Buffer, "le", 8), ], - programId + programId, ); }; export const getDaoTreasuryAddr = ( programId: PublicKey, - dao: PublicKey + dao: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync([dao.toBuffer()], programId); }; export const getProposalAddr = ( programId: PublicKey, - squadsProposal: PublicKey + squadsProposal: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [utils.bytes.utf8.encode("proposal"), squadsProposal.toBuffer()], - programId + programId, ); }; export const getAmmAddr = ( programId: PublicKey, baseMint: PublicKey, - quoteMint: PublicKey + quoteMint: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [ @@ -153,58 +153,58 @@ export const getAmmAddr = ( baseMint.toBuffer(), quoteMint.toBuffer(), ], - programId + programId, ); }; export const getAmmLpMintAddr = ( programId: PublicKey, - amm: PublicKey + amm: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [utils.bytes.utf8.encode("amm_lp_mint"), amm.toBuffer()], - programId + programId, ); }; export function getLaunchAddr( programId: PublicKey = LAUNCHPAD_PROGRAM_ID, - tokenMint: PublicKey + tokenMint: PublicKey, ): [PublicKey, number] { return PublicKey.findProgramAddressSync( [Buffer.from("launch"), tokenMint.toBuffer()], - programId + programId, ); } export const getLaunchSignerAddr = ( programId: PublicKey = LAUNCHPAD_PROGRAM_ID, - launch: PublicKey + launch: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [Buffer.from("launch_signer"), launch.toBuffer()], - programId + programId, ); }; export const getFundingRecordAddr = ( programId: PublicKey = LAUNCHPAD_PROGRAM_ID, launch: PublicKey, - funder: PublicKey + funder: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [Buffer.from("funding_record"), launch.toBuffer(), funder.toBuffer()], - programId + programId, ); }; export const getLiquidityPoolAddr = ( programId: PublicKey = LAUNCHPAD_PROGRAM_ID, - dao: PublicKey + dao: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [Buffer.from("pool_state"), dao.toBuffer()], - programId + programId, ); }; @@ -212,7 +212,7 @@ export const getSharedLiquidityPoolAddr = ( programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, dao: PublicKey, creator: PublicKey, - proposalStakeRateThresholdBps: number + proposalStakeRateThresholdBps: number, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [ @@ -221,38 +221,38 @@ export const getSharedLiquidityPoolAddr = ( creator.toBuffer(), new BN(proposalStakeRateThresholdBps).toArrayLike(Buffer, "le", 2), ], - programId + programId, ); }; export const getSlPoolPositionAddr = ( programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, slPool: PublicKey, - user: PublicKey + user: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [Buffer.from("sl_pool_position"), slPool.toBuffer(), user.toBuffer()], - programId + programId, ); }; export const getRaydiumCpmmLpMintAddr = ( poolState: PublicKey, - isDevnet: boolean + isDevnet: boolean, ): [PublicKey, number] => { const programId = isDevnet ? DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID : RAYDIUM_CP_SWAP_PROGRAM_ID; return PublicKey.findProgramAddressSync( [Buffer.from("pool_lp_mint"), poolState.toBuffer()], - programId + programId, ); }; export const getRaydiumCpmmPoolVaultAddr = ( poolState: PublicKey, token: PublicKey, - isDevnet: boolean + isDevnet: boolean, ): [PublicKey, number] => { const programId = isDevnet ? DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID @@ -263,37 +263,37 @@ export const getRaydiumCpmmPoolVaultAddr = ( poolState.toBuffer(), token.toBuffer(), ], - programId + programId, ); }; export const getRaydiumCpmmObservationStateAddr = ( poolState: PublicKey, - isDevnet: boolean + isDevnet: boolean, ): [PublicKey, number] => { const programId = isDevnet ? DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID : RAYDIUM_CP_SWAP_PROGRAM_ID; return PublicKey.findProgramAddressSync( [utils.bytes.utf8.encode("observation"), poolState.toBuffer()], - programId + programId, ); }; export const getSharedLiquidityPoolSignerAddr = ( programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, - slPool: PublicKey + slPool: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [Buffer.from("sl_pool_signer"), slPool.toBuffer()], - programId + programId, ); }; export const getSpotPoolAddr = ( programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, slPool: PublicKey, - index: number + index: number, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [ @@ -301,27 +301,27 @@ export const getSpotPoolAddr = ( slPool.toBuffer(), new BN(index).toArrayLike(Buffer, "le", 4), ], - programId + programId, ); }; export const getDraftProposalAddr = ( programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, - nonce: BN + nonce: BN, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [Buffer.from("draft_proposal"), nonce.toArrayLike(Buffer, "le", 8)], - programId + programId, ); }; export const getStakeRecordAddr = ( programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, draftProposal: PublicKey, - staker: PublicKey + staker: PublicKey, ): [PublicKey, number] => { return PublicKey.findProgramAddressSync( [Buffer.from("stake_record"), draftProposal.toBuffer(), staker.toBuffer()], - programId + programId, ); }; diff --git a/sdk/src/v0.5/utils/priceMath.ts b/sdk/src/v0.5/utils/priceMath.ts index cebf00c3..ee861520 100644 --- a/sdk/src/v0.5/utils/priceMath.ts +++ b/sdk/src/v0.5/utils/priceMath.ts @@ -46,10 +46,10 @@ export class AmmMath { public static getHumanPrice( ammPrice: BN, baseDecimals: number, - quoteDecimals: number + quoteDecimals: number, ): number { const decimalScalar = BN_TEN.pow( - new BN(quoteDecimals - baseDecimals).abs() + new BN(quoteDecimals - baseDecimals).abs(), ); const price1e12 = quoteDecimals > baseDecimals @@ -67,14 +67,14 @@ export class AmmMath { public static getTwap(amm: Amm): BN { return amm.oracle.aggregator.div( - amm.oracle.lastUpdatedSlot.sub(amm.createdAtSlot) + amm.oracle.lastUpdatedSlot.sub(amm.createdAtSlot), ); } public static simulateSwapInner( inputAmount: BN, inputReserves: BN, - outputReserves: BN + outputReserves: BN, ): BN { if (inputReserves.eqn(0) || outputReserves.eqn(0)) { throw new Error("reserves must be non-zero"); @@ -93,7 +93,7 @@ export class AmmMath { swapType: SwapType, baseReserves: BN, quoteReserves: BN, - slippageBps?: BN + slippageBps?: BN, ): SwapSimulation { let inputReserves: BN, outputReserves: BN; if (swapType.buy) { @@ -107,7 +107,7 @@ export class AmmMath { let expectedOut = this.simulateSwapInner( inputAmount, inputReserves, - outputReserves + outputReserves, ); let minExpectedOut; @@ -144,7 +144,7 @@ export class AmmMath { userBalanceIn: BN, ammReserveIn: BN, ammReserveOut: BN, - slippageBps: BN + slippageBps: BN, ): { optimalSwapAmount: BN; userInAfterSwap: BN; @@ -181,7 +181,7 @@ export class AmmMath { let expectedOut = this.simulateSwapInner( new BN(swapAmount), ammReserveIn, - ammReserveOut + ammReserveOut, ); let minimumExpectedOut = Number(expectedOut) - (Number(expectedOut) * Number(slippageBps)) / 10000; diff --git a/tests/autocrat/main.test.ts b/tests/autocrat/main.test.ts index 2cd4df41..3a60a135 100644 --- a/tests/autocrat/main.test.ts +++ b/tests/autocrat/main.test.ts @@ -4,11 +4,13 @@ import proposalBatchTx from "./integration/proposalBatchTx.test.js"; import initializeDao from "./unit/initializeDao.test.js"; import initializeProposal from "./unit/initializeProposal.test.js"; import finalizeProposal from "./unit/finalizeProposal.test.js"; +import spendingLimitChange from "./unit/spendingLimitChange.test.js"; export default function suite() { describe("#initialize_dao", initializeDao); describe("#initialize_proposal", initializeProposal); describe("#finalize_proposal", finalizeProposal); + describe.only("#upgrade_multisig_dao", spendingLimitChange); // describe("autocrat", autocrat); describe("full proposal", fullProposal); diff --git a/tests/autocrat/unit/spendingLimitChange.test.ts b/tests/autocrat/unit/spendingLimitChange.test.ts new file mode 100644 index 00000000..dd8a3a65 --- /dev/null +++ b/tests/autocrat/unit/spendingLimitChange.test.ts @@ -0,0 +1,447 @@ +import { + getDaoAddr, + PERMISSIONLESS_ACCOUNT, + PriceMath, +} from "@metadaoproject/futarchy/v0.5"; +import { + ComputeBudgetProgram, + PublicKey, + Transaction, + TransactionMessage, +} from "@solana/web3.js"; +import BN from "bn.js"; +import { expectError, ONE_MINUTE_IN_SLOTS } from "../../utils.js"; +import { assert } from "chai"; +import * as multisig from "@sqds/multisig"; +import { MEMO_PROGRAM_ID } from "@solana/spl-memo"; +const { Permissions, Permission } = multisig.types; + +const THOUSAND_BUCK_PRICE = PriceMath.getAmmPrice(1000, 9, 6); + +// TODO: abstract away these tests to make code cleaner + +export default function suite() { + let META: PublicKey, + USDC: PublicKey, + dao: PublicKey, + proposal: PublicKey, + multisigPda: PublicKey, + squadsProposal: PublicKey; + + beforeEach(async function () { + META = await this.createMint(this.payer.publicKey, 9); + USDC = await this.createMint(this.payer.publicKey, 6); + + await this.createTokenAccount(META, this.payer.publicKey); + await this.createTokenAccount(USDC, this.payer.publicKey); + + await this.mintTo(META, this.payer.publicKey, this.payer, 100 * 10 ** 9); + await this.mintTo( + USDC, + this.payer.publicKey, + this.payer, + 100_000 * 1_000_000 + ); + + const nonce = new BN(Math.floor(Math.random() * 1000000)); + + await this.autocratClient + .initializeDaoIx({ + baseMint: META, + quoteMint: USDC, + params: { + slotsPerProposal: new BN(ONE_MINUTE_IN_SLOTS).muln(60 * 24 * 3), + twapStartDelaySlots: new BN(ONE_MINUTE_IN_SLOTS).muln(60 * 24), + twapInitialObservation: THOUSAND_BUCK_PRICE, + twapMaxObservationChangePerUpdate: THOUSAND_BUCK_PRICE.divn(100), + minQuoteFutarchicLiquidity: new BN(1), + minBaseFutarchicLiquidity: new BN(1000), + passThresholdBps: 300, + nonce, + initialSpendingLimit: null, + }, + }) + .rpc(); + + [dao] = getDaoAddr({ + nonce, + daoCreator: this.payer.publicKey, + }); + + multisigPda = multisig.getMultisigPda({ createKey: dao })[0]; + }); + + it.only("executes spending limit change proposal", async function () { + + await this.autocratClient.autocrat.methods.upgradeMultisigDao().accounts({ + dao, + squadsMultisig: multisigPda, + squadsMultisigProgram: multisig.PROGRAM_ID, + }).rpc(); + + const storedMultisig = await multisig.accounts.Multisig.fromAccountAddress( + this.squadsConnection, + multisigPda + ); + console.log(storedMultisig); + + return; + + const newSpendingLimitPda = multisig.getSpendingLimitPda({ + multisigPda, + createKey: dao, + })[0]; + + const addSpendingLimitIx = multisig.instructions.multisigAddSpendingLimit({ + multisigPda, + spendingLimit: newSpendingLimitPda, + configAuthority: dao, + rentPayer: this.payer.publicKey, + createKey: dao, + vaultIndex: 0, + mint: USDC, + amount: new BN(50_000 * 10 ** 6), // 50,000 USDC + period: multisig.types.Period.Month, + members: [this.payer.publicKey], // Only the DAO can use this spending limit + destinations: [], // No specific destinations + memo: "", + }); + + const proposalResult = await this.initializeAndLaunchProposal({ + dao, + instructions: [addSpendingLimitIx], + }); + + proposal = proposalResult.proposal; + squadsProposal = proposalResult.squadsProposal; + + const { question, quoteVault } = this.futarchy.getProposalPdas( + proposal, + META, + USDC, + dao, + ); + + await this.conditionalVault + .splitTokensIx(question, quoteVault, USDC, new BN(11_000 * 1_000_000), 2) + .rpc(); + + // Trade heavily on pass market to make it pass + await this.futarchy + .conditionalSwapIx({ + dao, + baseMint: META, + quoteMint: USDC, + proposal, + market: "pass", + swapType: "buy", + inputAmount: new BN(10_000 * 1_000_000), + }) + .rpc(); + + // Crank TWAP to build up price history + for (let i = 0; i < 100; i++) { + this.advanceBySeconds(10_000); + + await this.futarchy + .conditionalSwapIx({ + dao, + baseMint: META, + quoteMint: USDC, + proposal, + market: "pass", + swapType: "buy", + inputAmount: new BN(10), + }) + .preInstructions([ + ComputeBudgetProgram.setComputeUnitPrice({ microLamports: i }), + ]) + .rpc(); + } + + // Finalize the proposal + await this.futarchy.finalizeProposal(proposal); + + const storedProposal = await this.futarchy.getProposal(proposal); + assert.exists(storedProposal.state.passed); + + const [vaultTransactionPda] = multisig.getTransactionPda({ + multisigPda: multisigPda, + index: 1n, + }); + + const transactionAccount = + await multisig.accounts.VaultTransaction.fromAccountAddress( + this.squadsConnection, + vaultTransactionPda, + ); + + const [vaultPda] = multisig.getVaultPda({ + multisigPda, + index: transactionAccount.vaultIndex, + programId: multisig.PROGRAM_ID, + }); + + const { accountMetas } = await multisig.utils.accountsForTransactionExecute( + { + connection: this.squadsConnection, + message: transactionAccount.message, + ephemeralSignerBumps: [...transactionAccount.ephemeralSignerBumps], + vaultPda, + transactionPda: vaultTransactionPda, + programId: multisig.PROGRAM_ID, + }, + ); + + await this.futarchy.autocrat.methods + .executeSpendingLimitChange() + .accounts({ + squadsMultisig: multisigPda, + proposal, + dao, + squadsProposal, + squadsMultisigProgram: multisig.PROGRAM_ID, + vaultTransaction: vaultTransactionPda, + }) + .remainingAccounts( + accountMetas.map((meta) => + meta.pubkey.equals(dao) ? { ...meta, isSigner: false } : meta, + ), + ) + .rpc(); + }); + + it("throws if the transaction is to remove the DAO as a member", async function () { + const removeMemberIx = multisig.instructions.multisigRemoveMember({ + multisigPda, + configAuthority: dao, + oldMember: dao, + }); + + const proposalResult = await this.initializeAndLaunchProposal({ + dao, + instructions: [removeMemberIx], + }); + + proposal = proposalResult.proposal; + squadsProposal = proposalResult.squadsProposal; + + const { question, quoteVault } = this.futarchy.getProposalPdas( + proposal, + META, + USDC, + dao, + ); + + await this.conditionalVault + .splitTokensIx(question, quoteVault, USDC, new BN(11_000 * 1_000_000), 2) + .rpc(); + + // Trade heavily on pass market to make it pass + await this.futarchy + .conditionalSwapIx({ + dao, + baseMint: META, + quoteMint: USDC, + proposal, + market: "pass", + swapType: "buy", + inputAmount: new BN(10_000 * 1_000_000), + }) + .rpc(); + + // Crank TWAP to build up price history + for (let i = 0; i < 100; i++) { + this.advanceBySeconds(10_000); + + await this.futarchy + .conditionalSwapIx({ + dao, + baseMint: META, + quoteMint: USDC, + proposal, + market: "pass", + swapType: "buy", + inputAmount: new BN(10), + }) + .preInstructions([ + ComputeBudgetProgram.setComputeUnitPrice({ microLamports: i }), + ]) + .rpc(); + } + + // Finalize the proposal + await this.futarchy.finalizeProposal(proposal); + + const storedProposal = await this.futarchy.getProposal(proposal); + assert.exists(storedProposal.state.passed); + + const [vaultTransactionPda] = multisig.getTransactionPda({ + multisigPda: multisigPda, + index: 1n, + }); + + const transactionAccount = + await multisig.accounts.VaultTransaction.fromAccountAddress( + this.squadsConnection, + vaultTransactionPda, + ); + + const [vaultPda] = multisig.getVaultPda({ + multisigPda, + index: transactionAccount.vaultIndex, + programId: multisig.PROGRAM_ID, + }); + + const { accountMetas } = await multisig.utils.accountsForTransactionExecute( + { + connection: this.squadsConnection, + message: transactionAccount.message, + ephemeralSignerBumps: [...transactionAccount.ephemeralSignerBumps], + vaultPda, + transactionPda: vaultTransactionPda, + programId: multisig.PROGRAM_ID, + }, + ); + + const callbacks = expectError( + "InvalidTransaction", + "The transaction should not be executed because it contains a call to remove the DAO as a member", + ); + + await this.futarchy.autocrat.methods + .executeSpendingLimitChange() + .accounts({ + squadsMultisig: multisigPda, + proposal, + dao, + squadsProposal, + squadsMultisigProgram: multisig.PROGRAM_ID, + vaultTransaction: vaultTransactionPda, + }) + .remainingAccounts( + accountMetas.map((meta) => + meta.pubkey.equals(dao) ? { ...meta, isSigner: false } : meta, + ), + ) + .rpc() + .then(callbacks[0], callbacks[1]); + }); + + it("throws if the vault transaction is a memo instruction", async function () { + const proposalResult = await this.initializeAndLaunchProposal({ + dao, + instructions: [ + { + programId: MEMO_PROGRAM_ID, + keys: [], + data: Buffer.from("Hello, world!"), + }, + ], + }); + + proposal = proposalResult.proposal; + squadsProposal = proposalResult.squadsProposal; + + const { question, quoteVault } = this.futarchy.getProposalPdas( + proposal, + META, + USDC, + dao, + ); + + await this.conditionalVault + .splitTokensIx(question, quoteVault, USDC, new BN(11_000 * 1_000_000), 2) + .rpc(); + + // Trade heavily on pass market to make it pass + await this.futarchy + .conditionalSwapIx({ + dao, + baseMint: META, + quoteMint: USDC, + proposal, + market: "pass", + swapType: "buy", + inputAmount: new BN(10_000 * 1_000_000), + }) + .rpc(); + + // Crank TWAP to build up price history + for (let i = 0; i < 100; i++) { + this.advanceBySeconds(10_000); + + await this.futarchy + .conditionalSwapIx({ + dao, + baseMint: META, + quoteMint: USDC, + proposal, + market: "pass", + swapType: "buy", + inputAmount: new BN(10), + }) + .preInstructions([ + ComputeBudgetProgram.setComputeUnitPrice({ microLamports: i }), + ]) + .rpc(); + } + + // Finalize the proposal + await this.futarchy.finalizeProposal(proposal); + + const storedProposal = await this.futarchy.getProposal(proposal); + assert.exists(storedProposal.state.passed); + + const [vaultTransactionPda] = multisig.getTransactionPda({ + multisigPda: multisigPda, + index: 1n, + }); + + const transactionAccount = + await multisig.accounts.VaultTransaction.fromAccountAddress( + this.squadsConnection, + vaultTransactionPda, + ); + + const [vaultPda] = multisig.getVaultPda({ + multisigPda, + index: transactionAccount.vaultIndex, + programId: multisig.PROGRAM_ID, + }); + + const { accountMetas } = await multisig.utils.accountsForTransactionExecute( + { + connection: this.squadsConnection, + message: transactionAccount.message, + ephemeralSignerBumps: [...transactionAccount.ephemeralSignerBumps], + vaultPda, + transactionPda: vaultTransactionPda, + programId: multisig.PROGRAM_ID, + }, + ); + + const callbacks = expectError( + "InvalidTransaction", + "The transaction should not be executed because it contains a call to remove the DAO as a member", + ); + + await this.futarchy.autocrat.methods + .executeSpendingLimitChange() + .accounts({ + squadsMultisig: multisigPda, + proposal, + dao, + squadsProposal, + squadsMultisigProgram: multisig.PROGRAM_ID, + vaultTransaction: vaultTransactionPda, + }) + .remainingAccounts( + accountMetas.map((meta) => + meta.pubkey.equals(dao) ? { ...meta, isSigner: false } : meta, + ), + ) + .rpc() + .then(callbacks[0], callbacks[1]); + }); +} diff --git a/verifiable-builds/autocrat.so b/verifiable-builds/autocrat.so index ca4b7f19..fe6c36bc 100755 Binary files a/verifiable-builds/autocrat.so and b/verifiable-builds/autocrat.so differ