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

Swap backend #448

Open
wants to merge 41 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
31cb151
init
Nov 5, 2024
ac7d7f4
added request pipeline
Nov 5, 2024
75fe8ae
added swap tests
Nov 6, 2024
596039f
fixed tests
Nov 6, 2024
993d10d
fixed tests
Nov 6, 2024
8913831
fixed tests
Nov 6, 2024
68b0b42
fixed tests
Nov 6, 2024
82d3480
fixed tests
Nov 6, 2024
4b3b6c7
fix tests
Nov 6, 2024
a8a9c2d
refactored structs
Nov 8, 2024
5cf97f1
added auth
Nov 8, 2024
2da5066
added price fixing
Nov 11, 2024
3a24e0b
merged main
Nov 11, 2024
152a99e
merged
Nov 11, 2024
300c852
fixed tests
Nov 11, 2024
3420ccc
remove unecessary structs
Nov 14, 2024
8d8e895
Merge branch 'main' of https://github.com/yral-dapp/hot-or-not-backen…
Nov 19, 2024
90e3a21
merge conflicts
Nov 19, 2024
c2d1fe4
fixed tests
Nov 19, 2024
d491db6
fix tests
Nov 19, 2024
2c7ca74
fix tests
Nov 19, 2024
b388e97
comments
Nov 23, 2024
0adf186
Merge branch 'main' into swap
joel-medicala-yral Jan 13, 2025
03dfae2
merged
joel-medicala-yral Jan 13, 2025
2408ba2
Merge branch 'main' of https://github.com/yral-dapp/hot-or-not-backen…
joel-medicala-yral Jan 26, 2025
750c954
fixed icrc2 label
joel-medicala-yral Jan 26, 2025
d1bac77
fixed request approval from caller instead of canister id
joel-medicala-yral Jan 26, 2025
814a254
added manual approveg
joel-medicala-yral Jan 26, 2025
2512392
added stuff
joel-medicala-yral Jan 26, 2025
1198d14
added price fetching sims
joel-medicala-yral Jan 29, 2025
0d21dc2
Revert "added price fetching sims"
joel-medicala-yral Jan 30, 2025
2147b6b
added price fetching test
joel-medicala-yral Jan 30, 2025
cca2089
fixed the swap request issue
joel-medicala-yral Jan 30, 2025
039ef9a
remove unused code
joel-medicala-yral Feb 3, 2025
37f20a2
removed comments
joel-medicala-yral Feb 3, 2025
516eb15
fixed nits
joel-medicala-yral Feb 7, 2025
844c028
removed uncessary tests
joel-medicala-yral Feb 7, 2025
5cf0ec7
Merge branch 'main' into swap
joel-medicala-yral Feb 7, 2025
e23f07a
removed uncessary tests
joel-medicala-yral Feb 7, 2025
7434dc5
Merge branch 'swap' of https://github.com/yral-dapp/hot-or-not-backen…
joel-medicala-yral Feb 7, 2025
a2de58c
removed unessary imports
joel-medicala-yral Feb 7, 2025
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
56 changes: 49 additions & 7 deletions src/canister/individual_user_template/can.did
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,25 @@ type AirdropError = variant {
type AirdropInfo = record {
principals_who_successfully_claimed : vec record { principal; ClaimStatus };
};

type ApproveError = variant {
GenericError : record { message : text; error_code : nat };
TemporarilyUnavailable;
Duplicate : record { duplicate_of : nat };
BadFee : record { expected_fee : nat };
AllowanceChanged : record { current_allowance : nat };
CreatedInFuture : record { ledger_time : nat64 };
TooOld;
Expired : record { ledger_time : nat64 };
InsufficientFunds : record { balance : nat };
};

type BalanceInfo = record {
balance : nat;
withdrawable : nat;
net_airdrop_reward : nat;
};

type BetDetails = record {
bet_direction : BetDirection;
bet_maker_canister_id : principal;
Expand Down Expand Up @@ -84,6 +98,7 @@ type DeployedCdaoCanisters = record {
airdrop_info : AirdropInfo;
root : principal;
swap : principal;
last_swapped_price : opt float64;
ledger : principal;
index : principal;
governance : principal;
Expand Down Expand Up @@ -402,13 +417,14 @@ type Result_24 = variant { Ok : text; Err : text };
type Result_25 = variant { Ok : IndividualUserCreatorDaoEntry; Err : text };
type Result_26 = variant { Committed : Committed; Aborted : record {} };
type Result_27 = variant { Ok : Ok; Err : GovernanceError };
type Result_28 = variant { Ok; Err : CdaoTokenError };
type Result_29 = variant {
type Result_28 = variant { Ok; Err : SwapError };
type Result_29 = variant { Ok; Err : CdaoTokenError };
type Result_3 = variant { Ok : bool; Err : CdaoTokenError };
type Result_30 = variant {
Ok : UserProfileDetailsForFrontend;
Err : UpdateProfileDetailsError;
};
type Result_3 = variant { Ok : bool; Err : CdaoTokenError };
type Result_30 = variant { Ok; Err : UpdateProfileSetUniqueUsernameError };
type Result_31 = variant { Ok; Err : UpdateProfileSetUniqueUsernameError };
type Result_4 = variant {
Ok : BettingStatus;
Err : BetOnCurrentlyViewingPostError;
Expand Down Expand Up @@ -486,6 +502,18 @@ type SwapDistribution = record {
total_e8s : nat64;
initial_swap_amount_e8s : nat64;
};
type SwapError = variant {
SwapAllocationExhausted;
ApproveError : ApproveError;
TransferFromError : TransferFromError;
CallError : record { RejectionCode; text };
IsNotTokenCreator;
NoController;
InvalidLedger;
UnsupportedToken;
Unauthenticated;
};
type SwapTokenData = record { amt : nat; ledger : principal };
type SystemTime = record {
nanos_since_epoch : nat32;
secs_since_epoch : nat64;
Expand Down Expand Up @@ -514,6 +542,7 @@ type TokenEvent = variant {
amount : nat64;
};
};
type TokenPairs = record { token_a : SwapTokenData; token_b : SwapTokenData };
type TransferError = variant {
GenericError : record { message : text; error_code : nat };
TemporarilyUnavailable;
Expand All @@ -524,6 +553,17 @@ type TransferError = variant {
TooOld;
InsufficientFunds : record { balance : nat };
};
type TransferFromError = variant {
GenericError : record { message : text; error_code : nat };
TemporarilyUnavailable;
InsufficientAllowance : record { allowance : nat };
BadBurn : record { min_burn_amount : nat };
Duplicate : record { duplicate_of : nat };
BadFee : record { expected_fee : nat };
CreatedInFuture : record { ledger_time : nat64 };
TooOld;
InsufficientFunds : record { balance : nat };
};
type TreasuryDistribution = record { total_e8s : nat64 };
type UpdateProfileDetailsError = variant { NotAuthorized };
type UpdateProfileSetUniqueUsernameError = variant {
Expand Down Expand Up @@ -671,23 +711,25 @@ service : (IndividualUserTemplateInitArgs) -> {
SettleNeuronsFundParticipationRequest,
) -> (SettleNeuronsFundParticipationResponse);
stake_dollr_for_gdollr : (nat) -> (Result_1);
swap_request_action : (TokenPairs, principal) -> (Result_28);
transfer_token_to_user_canister : (principal, principal, opt blob, nat) -> (
Result_28,
Result_29,
);
transfer_tokens_and_posts : (principal, principal) -> (Result_22);
update_last_access_time : () -> (Result_24);
update_last_canister_functionality_access_time : () -> ();
update_last_swap_price : (principal, float64) -> ();
update_ml_feed_cache : (vec MLFeedCacheItem) -> (Result_24);
update_post_add_view_details : (nat64, PostViewDetailsFromFrontend) -> ();
update_post_as_ready_to_view : (nat64) -> ();
update_post_increment_share_count : (nat64) -> (nat64);
update_post_status : (nat64, PostStatus) -> ();
update_post_toggle_like_status_by_caller : (nat64) -> (bool);
update_profile_display_details : (UserProfileUpdateDetailsFromFrontend) -> (
Result_29,
Result_30,
);
update_profile_owner : (opt principal) -> (Result_1);
update_profile_set_unique_username_once : (text) -> (Result_30);
update_profile_set_unique_username_once : (text) -> (Result_31);
update_profiles_i_follow_toggle_list_with_specified_profile : (
FolloweeArg,
) -> (Result_9);
Expand Down
6 changes: 3 additions & 3 deletions src/canister/individual_user_template/src/api/cdao/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod airdrop;
pub mod swap;
mod token;
use std::collections::{HashMap, HashSet, VecDeque};

Expand Down Expand Up @@ -373,9 +374,8 @@ async fn deploy_cdao_sns(
root: root.0,
swap: swap.0,
index: index.0,
airdrop_info: AirdropInfo {
principals_who_successfully_claimed: HashMap::new(),
},
airdrop_info: AirdropInfo { principals_who_successfully_claimed: HashMap::new() },
last_swapped_price: None,
};
CANISTER_DATA.with(|cdata| {
let mut cdata = cdata.borrow_mut();
Expand Down
55 changes: 55 additions & 0 deletions src/canister/individual_user_template/src/api/cdao/swap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use candid::{CandidType, Nat, Principal};
use ic_cdk_macros::update;
use icrc_ledger_types::icrc2::transfer_from::{TransferFromArgs, TransferFromError};
use serde::Deserialize;
use shared_utils::{canister_specific::individual_user_template::types::{cdao::TokenPairs, error::SwapError}, common::utils::permissions::is_caller_global_admin};
use crate::util::guard::is_caller_profile_owner;
use crate::{api::profile::get_profile_details_v2::get_profile_details_v2, CANISTER_DATA};

#[derive(CandidType, Deserialize, PartialEq, Eq, Debug)]
struct SupportedStandards{
name: String,
url: String
}

#[update(guard = "is_caller_profile_owner")]
pub async fn swap_request_action(token_pairs: TokenPairs, requester: Principal) -> Result<(), SwapError>{
//auth
if ic_cdk::caller() != get_profile_details_v2().principal_id{
return Err(SwapError::Unauthenticated);
joel-medicala-yral marked this conversation as resolved.
Show resolved Hide resolved
}
let TokenPairs{token_a, token_b} = token_pairs;

let transfer_res: (Result<Nat, TransferFromError>, ) = ic_cdk::call(token_a.ledger, "icrc2_transfer_from", (TransferFromArgs{
from: requester.into(),
spender_subaccount: None,
to: ic_cdk::caller().into(),
amount: token_a.amt,
fee: None,
memo: None,
created_at_time: None
}, )).await?;
transfer_res.0.map_err(SwapError::TransferFromError)?;

let transfer_res: (Result<Nat, TransferFromError>, ) = ic_cdk::call(token_b.ledger, "icrc2_transfer_from", (TransferFromArgs{
from: ic_cdk::caller().into(),
spender_subaccount: None,
to: requester.into(),
amount: token_b.amt,
fee: None,
memo: None,
created_at_time: None
}, )).await?;
transfer_res.0.map_err(SwapError::TransferFromError)?;
joel-medicala-yral marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}

#[update(guard = "is_caller_global_admin")]
fn update_last_swap_price(token_ledger: Principal, price: f64){
CANISTER_DATA.with_borrow_mut(|data| {
if let Some(cdao) = data.cdao_canisters.iter_mut().find(|cdao| cdao.ledger == token_ledger){
cdao.last_swapped_price = Some(price);
}
});
}
2 changes: 1 addition & 1 deletion src/canister/individual_user_template/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ pub mod token;
pub mod well_known_principal;
pub mod cdao;
pub mod device_id_management;
pub mod pump_n_dump;
pub mod pump_n_dump;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ic_cdk_macros::query;
use shared_utils::canister_specific::individual_user_template::types::profile::UserProfileDetailsForFrontendV2;

#[query]
fn get_profile_details_v2() -> UserProfileDetailsForFrontendV2 {
pub fn get_profile_details_v2() -> UserProfileDetailsForFrontendV2 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think to do the guard i need it to be public na?

CANISTER_DATA.with_borrow(|canister_data_ref_cell| {
let profile = canister_data_ref_cell.profile.clone();
let token_balance = &canister_data_ref_cell.my_token_balance;
Expand Down
7 changes: 4 additions & 3 deletions src/canister/individual_user_template/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ use icrc_ledger_types::icrc1::transfer::Memo;
use shared_utils::{
canister_specific::individual_user_template::types::{
arg::{FolloweeArg, IndividualUserTemplateInitArgs, PlaceBetArg},
cdao::DeployedCdaoCanisters,
cdao::{DeployedCdaoCanisters, TokenPairs},
device_id::DeviceIdentity,
error::{
AirdropError, BetOnCurrentlyViewingPostError, CdaoDeployError, CdaoTokenError,
FollowAnotherUserProfileError, GetPostsOfUserProfileError,
BetOnCurrentlyViewingPostError, CdaoDeployError, CdaoTokenError,
FollowAnotherUserProfileError, GetPostsOfUserProfileError, AirdropError, SwapError
},
follow::{FollowEntryDetail, FollowEntryId},
hot_or_not::{BetDetails, BetOutcomeForBetMaker, BettingStatus, PlacedBetDetail},
Expand Down Expand Up @@ -60,6 +60,7 @@ pub mod data_model;
mod util;

thread_local! {

static CANISTER_DATA: RefCell<CanisterData> = RefCell::default();
static SNAPSHOT_DATA: RefCell<Vec<u8>> = RefCell::default();
static PUMP_N_DUMP: RefCell<PumpAndDumpGame> = RefCell::default();
Expand Down
9 changes: 9 additions & 0 deletions src/canister/individual_user_template/src/util/guard.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use crate::api::profile::get_profile_details_v2::get_profile_details_v2;

pub fn is_caller_profile_owner() -> Result<(), String> {

if ic_cdk::caller() != get_profile_details_v2().principal_id{
return Err("Unauthorize".to_string());
}
Ok(())
}
1 change: 1 addition & 0 deletions src/canister/individual_user_template/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod migration;
pub mod periodic_update;
pub mod score_ranking;
pub mod subnet_orchestrator;
pub mod guard;
2 changes: 1 addition & 1 deletion src/canister/platform_orchestrator/src/guard/is_caller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ pub(crate) fn is_caller_global_admin_or_controller() -> Result<(), String> {
false => Err("Unauthorized".into()),
}
})
}
}
32 changes: 7 additions & 25 deletions src/lib/integration_tests/tests/creator_dao/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,27 @@ pub mod test_deletion_of_creator_tokens;
pub mod test_number_of_creator_tokens;
pub mod types;
pub mod utils;
pub mod test_swap_flow;

use ic_ledger_types::Memo;
use ic_sns_governance::pb::v1::governance::Version;
use ic_sns_governance::pb::v1::{
manage_neuron, neuron, Account, GetRunningSnsVersionRequest, GetRunningSnsVersionResponse,
ListNeurons, ListNeuronsResponse, ManageNeuron, ManageNeuronResponse,
};
use ic_sns_init::pb::v1::{
sns_init_payload::InitialTokenDistribution, AirdropDistribution, DeveloperDistribution,
FractionalDeveloperVotingPower, NeuronDistribution, SnsInitPayload, SwapDistribution,
TreasuryDistribution,
};
use ic_sns_swap::pb::v1::{
GetInitRequest, GetInitResponse, NeuronBasketConstructionParameters, NewSaleTicketRequest,
NewSaleTicketResponse, RefreshBuyerTokensRequest, RefreshBuyerTokensResponse,
};
use ic_sns_governance::pb::v1::{GetRunningSnsVersionRequest, GetRunningSnsVersionResponse};
use sha2::{Digest, Sha256};
use shared_utils::canister_specific::individual_user_template::types::arg::IndividualUserTemplateInitArgs;
use shared_utils::canister_specific::individual_user_template::types::error::AirdropError;
use test_utils::setup::test_constants::get_mock_user_bob_principal_id;
use shared_utils::constant::{
SNS_TOKEN_ARCHIVE_MODULE_HASH, SNS_TOKEN_GOVERNANCE_MODULE_HASH, SNS_TOKEN_INDEX_MODULE_HASH,
SNS_TOKEN_LEDGER_MODULE_HASH, SNS_TOKEN_ROOT_MODULE_HASH, SNS_TOKEN_SWAP_MODULE_HASH,
SNS_TOKEN_ARCHIVE_MODULE_HASH, SNS_TOKEN_GOVERNANCE_MODULE_HASH, SNS_TOKEN_INDEX_MODULE_HASH, SNS_TOKEN_LEDGER_MODULE_HASH, SNS_TOKEN_ROOT_MODULE_HASH, SNS_TOKEN_SWAP_MODULE_HASH
};
use shared_utils::types::creator_dao_stats::CreatorDaoTokenStats;
use std::time::{Duration, UNIX_EPOCH};
use std::{collections::HashMap, fmt::Debug, str::FromStr, time::SystemTime, vec};
use test_utils::setup::test_constants::get_mock_user_bob_principal_id;
use std::{collections::HashMap, fmt::Debug, vec};
use utils::{setup_default_sns_creator_token, setup_sns_w_canister_for_creator_dao};

use candid::{encode_args, CandidType, Decode, Encode, Nat, Principal};
use ic_base_types::PrincipalId;
use ic_sns_wasm::init::SnsWasmCanisterInitPayload;
use icp_ledger::Subaccount;
use pocket_ic::WasmResult;
use serde::{Deserialize, Serialize};
use shared_utils::{
canister_specific::individual_user_template::{
types::cdao::DeployedCdaoCanisters, types::error::CdaoDeployError,
},
canister_specific::individual_user_template::
types::cdao::DeployedCdaoCanisters,
common::types::known_principal::KnownPrincipalType,
constant::SNS_WASM_W_PRINCIPAL_ID,
};
Expand Down
Loading