Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add arbitrary proposal to add options #7

Merged
merged 7 commits into from
Oct 1, 2024
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
49 changes: 49 additions & 0 deletions src/arbitrary_proposal_add_options.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use starknet::contract_address::{ContractAddress};

#[starknet::interface]
trait IArbitraryProposalAddOptions<TContractState> {
fn execute_arbitrary_proposal(ref self: TContractState);
}

#[starknet::contract]
pub mod ArbitraryProposalAddOptions {
use amm_governance::proposals::proposals as proposals_component;
use amm_governance::proposals::proposals::InternalTrait;
use konoha::contract::IGovernanceDispatcher;
use konoha::contract::IGovernanceDispatcherTrait;
use konoha::types::{CustomProposalConfig};
use starknet::{ContractAddress, ClassHash, get_contract_address};

component!(path: proposals_component, storage: proposals, event: ProposalsEvent);

#[storage]
struct Storage {
#[substorage(v0)]
proposals: proposals_component::Storage,
}

#[derive(starknet::Event, Drop)]
#[event]
enum Event {
ProposalsEvent: proposals_component::Event,
}

#[constructor]
fn constructor(ref self: ContractState) {}

#[abi(embed_v0)]
impl ArbitraryProposalAddOptions of super::IArbitraryProposalAddOptions<ContractState> {
fn execute_arbitrary_proposal(ref self: ContractState) {
let option_deployer_class_hash: felt252 =
0x004e19b87b7777e6e7032ca325794cd793a4d6e9591a8c4e60e0d1b27e4da3d7;

let add_options = CustomProposalConfig {
target: option_deployer_class_hash,
selector: selector!("add_options"),
library_call: true
};

self.proposals.add_custom_proposal_config(add_options);
}
}
}
5 changes: 3 additions & 2 deletions src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
mod arbitrary_proposal_add_options;
pub mod carm;
pub mod constants;
pub mod contract;
mod options;
pub mod proposals;
pub mod staking;
mod traits;
mod types;
pub mod traits;
pub mod types;
mod upgrades;
pub mod vecarm;
5 changes: 3 additions & 2 deletions src/traits.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use amm_governance::types::{OptionType, OptionSide};
use amm_governance::types::{OptionType, OptionSide, Option_};
use cubit::f128::types::{Fixed, FixedTrait};
use starknet::{ContractAddress, ClassHash};

Expand Down Expand Up @@ -87,7 +87,7 @@ pub trait IAMM<TContractState> {
self: @TContractState, lptoken_addr: ContractAddress, lpt_amt: u256
) -> u256;
fn get_available_lptoken_addresses(self: @TContractState, order_i: felt252) -> ContractAddress;
// fn get_all_options(self: @TContractState, lptoken_address: ContractAddress) -> Array<Option_>;
fn get_all_options(self: @TContractState, lptoken_address: ContractAddress) -> Array<Option_>;
// fn get_all_non_expired_options_with_premia(
// self: @TContractState, lptoken_address: ContractAddress
// ) -> Array<OptionWithPremia>;
Expand Down Expand Up @@ -211,6 +211,7 @@ pub trait IAMM<TContractState> {
fn set_pragma_checkpoint(ref self: TContractState, key: felt252);
fn set_pragma_required_checkpoints(ref self: TContractState);
fn upgrade(ref self: TContractState, new_implementation: ClassHash);
fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress);
}

#[starknet::interface]
Expand Down
10 changes: 10 additions & 0 deletions src/types.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ pub struct FutureOption {
pub base_token_address: ContractAddress,
pub initial_volatility: Fixed
}

#[derive(Copy, Drop, Serde)]
pub struct Option_ {
pub option_side: OptionSide,
pub maturity: u64,
pub strike_price: Fixed,
pub quote_token_address: ContractAddress,
pub base_token_address: ContractAddress,
pub option_type: OptionType
}
179 changes: 179 additions & 0 deletions tests/add_options_proposal.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
use amm_governance::proposals::{IProposalsDispatcherTrait, IProposalsDispatcher};
use amm_governance::traits::{IAMMDispatcher, IAMMDispatcherTrait};
use amm_governance::types::Option_;

use konoha::upgrades::IUpgradesDispatcher;
use konoha::upgrades::IUpgradesDispatcherTrait;
use snforge_std::{
CheatSpan, CheatTarget, ContractClassTrait, ContractClass, prank, start_warp, declare
};

use starknet::{ContractAddress, get_block_timestamp};

fn get_voter_addresses() -> @Span<felt252> {
let arr = array![
0x0011d341c6e841426448ff39aa443a6dbb428914e05ba2259463c18308b86233,
0x0583a9d956d65628f806386ab5b12dccd74236a3c6b930ded9cf3c54efc722a1,
0x03d1525605db970fa1724693404f5f64cba8af82ec4aab514e6ebd3dec4838ad,
0x00d79a15d84f5820310db21f953a0fae92c95e25d93cb983cc0c27fc4c52273c,
0x0428c240649b76353644faF011B0d212e167f148fdd7479008Aa44eEaC782BfC,
0x06717eaf502baac2b6b2c6ee3ac39b34a52e726a73905ed586e757158270a0af,
];
@arr.span()
}

fn get_option_calldata() -> @Span<felt252> {
// calldata generated by FE
let arr = array![
0x047472e6755afc57ada9550b6a3ac93129cc4b5f98f51c73e0644d129fd208d9, //amm address !
0x2, // array length
0x5354524b2d555344432d43414c4c2d4c4f4e47, // str_to_felt STRK-USDC-CALL-LONG
0x5354524b2d555344432d43414c4c2d53484f5254, // str_to_felt STRK-USDC-CALL-SHORT
0x675B78FF, // maturity
0x6666666666666666, // strike price 0.4
0x0, // fixed sign
0x0, // option type
0x2b629088a1d30019ef18b893cebab236f84a365402fa0df2f51ec6a01506b1d, // lp address
0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8, // quote address
0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d, // base address
0x5a0000000000000000, // volatility
0x0, // fixed sign
0x5354524b2d555344432d43414c4c2d4c4f4e47, // str_to_felt STRK-USDC-CALL-LONG
0x5354524b2d555344432d43414c4c2d53484f5254, // str_to_felt STRK-USDC-CALL-SHORT
0x675B78FF, // maturity
0x8000000000000000, // strike price 0.5
0x0, // fixed sign
0x0, // option type
0x2b629088a1d30019ef18b893cebab236f84a365402fa0df2f51ec6a01506b1d, // lp address
0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8, // quote address
0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d, // base address
0x5a0000000000000000,
0x0,
];
@arr.span()
}

#[test]
#[fork("MAINNET")]
fn test_add_custom_proposal() {
// # ADD CUSTOM PROPOSAL FOR ADDING OPTIONS

let gov_addr = 0x001405ab78ab6ec90fba09e6116f373cda53b0ba557789a4578d8c1ec374ba0f
.try_into()
.unwrap();
let props = IProposalsDispatcher { contract_address: gov_addr };

let user1: ContractAddress =
0x0011d341c6e841426448ff39aa443a6dbb428914e05ba2259463c18308b86233 // team m 1
.try_into()
.unwrap();

let prop_id = 103;

let mut voter_addresses = *get_voter_addresses();

// vote yay with all users
loop {
match voter_addresses.pop_front() {
Option::Some(address) => {
let current_voter: ContractAddress = (*address).try_into().unwrap();
prank(CheatTarget::One(gov_addr), current_voter, CheatSpan::TargetCalls(1));
props.vote(prop_id, 1);
},
Option::None(()) => { break (); }
}
};

let curr_timestamp = get_block_timestamp();
let proposal_wait_time = consteval_int!(60 * 60 * 24 * 7) + 420;
let warped_timestamp = curr_timestamp + proposal_wait_time;

start_warp(CheatTarget::One(gov_addr), warped_timestamp);
assert(props.get_proposal_status(prop_id) == 1, 'arbitrary proposal not passed');

let upgrades = IUpgradesDispatcher { contract_address: gov_addr };

upgrades.apply_passed_proposal(prop_id);

println!("custom proposal added");

// # TRANSFER OWNERSHIP OF AMM

let amm_owner_address: ContractAddress =
0x74fd7da23e21f0f0479adb435221b23f57ca4c32a0c68aad9409a41c27f3067
.try_into()
.unwrap();
let amm_address: ContractAddress =
0x047472e6755afc57ada9550b6a3ac93129cc4b5f98f51c73e0644d129fd208d9
.try_into()
.unwrap();
let amm = IAMMDispatcher { contract_address: amm_address };

prank(CheatTarget::One(amm_address), amm_owner_address, CheatSpan::TargetCalls(1));
amm.transfer_ownership(gov_addr);

println!("AMM ownership transfered");

// # ADD OPTIONS VIA NEW CUSTOM PROPOSAL

let add_options_calldata = get_option_calldata();

println!("add options calldata: {:?}", add_options_calldata);

prank(CheatTarget::One(gov_addr), user1, CheatSpan::TargetCalls(1));
// propose arbitrary proposal
let prop_id2: felt252 = props.submit_custom_proposal(0x2, *add_options_calldata).into();

let mut voter_addresses2 = *get_voter_addresses();

// vote yay with all users
loop {
match voter_addresses2.pop_front() {
Option::Some(address) => {
let current_voter: ContractAddress = (*address).try_into().unwrap();
prank(CheatTarget::One(gov_addr), current_voter, CheatSpan::TargetCalls(1));
props.vote(prop_id2, 1);
},
Option::None(()) => { break (); }
}
};

let warped_timestamp2 = curr_timestamp + proposal_wait_time * 2;

start_warp(CheatTarget::One(gov_addr), warped_timestamp2);
assert(props.get_proposal_status(prop_id2) == 1, 'add options not passed');
println!("add options passed");

upgrades.apply_passed_proposal(prop_id2);

println!("options added");

// # VALIDATED THAT CORRECT OPTIONS WERE ADDED

let strk_usdc_call_lp_address: ContractAddress =
0x2b629088a1d30019ef18b893cebab236f84a365402fa0df2f51ec6a01506b1d
.try_into()
.unwrap();
let mut all_strk_usdc_call_options: Array<Option_> = amm
.get_all_options(strk_usdc_call_lp_address);

// TODO: validate that the options that were added are there
loop {
match all_strk_usdc_call_options.pop_front() {
Option::Some(option) => {
// only print the new options
if option.maturity == 1734047999 {
// TODO: right now just read it from the console
println!("OPTION");
println!("strike: {:?}", option.strike_price.mag);
println!("quote: {:?}", option.quote_token_address);
println!("base: {:?}", option.base_token_address);
println!("type: {:?}", option.option_type);
println!("side: {:?}", option.option_side);
println!("maturity: {:?}", option.maturity);
}
},
Option::None(()) => { break (); }
}
};
}
1 change: 1 addition & 0 deletions tests/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod add_options_proposal;
mod test_prop_pass;
//mod unstake_airdrop;
//mod add_options;
Expand Down
2 changes: 1 addition & 1 deletion tests/upgrade.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fn scenario_airdrop_staked_carm() {
0x0583a9d956d65628f806386ab5b12dccd74236a3c6b930ded9cf3c54efc722a1 // team
.try_into()
.unwrap();
let investor1: ContractAddress =
let _investor1: ContractAddress =
0x056d761e1e5d1918dba05de02afdbd8de8da01a63147dce828c9b1fe9227077d
.try_into()
.unwrap();
Expand Down
Loading