Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions programs/autocrat/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub enum AutocratError {
InsufficientLpTokenBalance,
#[msg("The LP tokens passed in have less liquidity than the DAO's `min_quote_futarchic_liquidity` or `min_base_futachic_liquidity`")]
InsufficientLpTokenLock,
#[msg("Proposal duration must be longer than TWAP start delay")]
ProposalDurationTooShort,
#[msg("Question must have exactly 2 outcomes for binary futarchy")]
QuestionMustBeBinary,
}
9 changes: 8 additions & 1 deletion programs/autocrat/src/instructions/initialize_dao.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,21 @@ impl InitializeDao<'_> {
let (treasury, treasury_pda_bump) =
Pubkey::find_program_address(&[dao.key().as_ref()], ctx.program_id);

let slots_per_proposal = slots_per_proposal.unwrap_or(THREE_DAYS_IN_SLOTS);

require!(
slots_per_proposal > twap_start_delay_slots,
AutocratError::ProposalDurationTooShort
);

dao.set_inner(Dao {
token_mint: ctx.accounts.token_mint.key(),
usdc_mint: ctx.accounts.usdc_mint.key(),
treasury_pda_bump,
treasury,
proposal_count: 0,
pass_threshold_bps: pass_threshold_bps.unwrap_or(DEFAULT_PASS_THRESHOLD_BPS),
slots_per_proposal: slots_per_proposal.unwrap_or(THREE_DAYS_IN_SLOTS),
slots_per_proposal,
twap_initial_observation,
twap_max_observation_change_per_update,
twap_start_delay_slots,
Expand Down
20 changes: 20 additions & 0 deletions sdk/src/v0.4/types/autocrat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,16 @@ export type Autocrat = {
code: 6011;
name: "InsufficientLpTokenLock";
msg: "The LP tokens passed in have less liquidity than the DAO's `min_quote_futarchic_liquidity` or `min_base_futachic_liquidity`";
},
{
code: 6012;
name: "ProposalDurationTooShort";
msg: "Proposal duration must be longer than TWAP start delay";
},
{
code: 6013;
name: "QuestionMustBeBinary";
msg: "Question must have exactly 2 outcomes for binary futarchy";
}
];
};
Expand Down Expand Up @@ -2009,5 +2019,15 @@ export const IDL: Autocrat = {
name: "InsufficientLpTokenLock",
msg: "The LP tokens passed in have less liquidity than the DAO's `min_quote_futarchic_liquidity` or `min_base_futachic_liquidity`",
},
{
code: 6012,
name: "ProposalDurationTooShort",
msg: "Proposal duration must be longer than TWAP start delay",
},
{
code: 6013,
name: "QuestionMustBeBinary",
msg: "Question must have exactly 2 outcomes for binary futarchy",
},
],
};
10 changes: 10 additions & 0 deletions sdk/src/v0.4/types/conditional_vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,11 @@ export type ConditionalVault = {
code: 6015;
name: "ConditionalTokenMetadataAlreadySet";
msg: "Conditional token metadata already set";
},
{
code: 6016;
name: "UnauthorizedConditionalTokenAccount";
msg: "Conditional token account is not owned by the authority";
}
];
};
Expand Down Expand Up @@ -1835,5 +1840,10 @@ export const IDL: ConditionalVault = {
name: "ConditionalTokenMetadataAlreadySet",
msg: "Conditional token metadata already set",
},
{
code: 6016,
name: "UnauthorizedConditionalTokenAccount",
msg: "Conditional token account is not owned by the authority",
},
],
};
28 changes: 28 additions & 0 deletions tests/autocrat/autocrat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,34 @@ export default function suite() {
});
});

it("doesn't allow DAOs with proposal duration less than TWAP start delay", async function () {
const callbacks = expectError(
"ProposalDurationTooShort",
"DAO initialized despite slots_per_proposal being less than twap_start_delay_slots"
);

const daoKeypair = Keypair.generate();

await autocratClient
.initializeDaoIx(
daoKeypair,
META,
{
twapInitialObservation: new BN(1),
twapMaxObservationChangePerUpdate: new BN(1000),
twapStartDelaySlots: new BN(10000),
minQuoteFutarchicLiquidity: new BN(5),
minBaseFutarchicLiquidity: new BN(5000),
passThresholdBps: 300,
slotsPerProposal: new BN(5000),
},
USDC
)
.signers([payer])
.rpc()
.then(callbacks[0], callbacks[1]);
});

describe("#initialize_proposal", async function () {
it("initializes proposals", async function () {
const accounts = [
Expand Down
Loading