Skip to content

Commit

Permalink
Ethereum compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed Oct 24, 2024
1 parent 38af93a commit 1cc1e7b
Show file tree
Hide file tree
Showing 30 changed files with 465 additions and 42 deletions.
9 changes: 7 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ scale-info = { version = "2.11.3", default-features = false, features = [
] }
jsonrpsee = { version = "0.22.5", features = ["server"] }
hex-literal = "0.4.1"
hex = { version = "0.4.3", default-features = false, features = ["alloc"] }
serde = { version = "1.0.204", default-features = false }
serde_json = "1.0.120"
smallvec = "1.13.2"
Expand All @@ -103,6 +104,7 @@ array-bytes = { version = "6.2.3", default-features = false }
serde-json-core = { version = '0.5.1', default-features = false }
heapless = { version = "0.8", default-features = false }
color-print = "0.3.6"
k256 = { version = "0.13.4", default-features = false, features = ["ecdsa"] }

# Emulations
xcm-emulator = { version = "0.12.0", default-features = false }
Expand All @@ -125,7 +127,7 @@ sp-staking = { version = "33.0.0", default-features = false }
# sp-runtime v38.0.1 takes out sp_std from runtime_string file and calls "alloc" directly which errors out
sp-runtime = { version = "=38.0.0", default-features = false }
sp-arithmetic = { version = "26.0.0", default-features = false }
sp-core = { version = "34.0.0", default-features = false }
sp-core = { version = "34.0.0", default-features = false, features = ["serde"] }
sp-io = { version = "37.0.0", default-features = false }
sp-blockchain = { version = "35.0.0", default-features = false }
sp-consensus-aura = { version = "0.39.0", default-features = false }
Expand Down
2 changes: 2 additions & 0 deletions integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ pallet-session.workspace = true
pallet-proxy-bonding.workspace = true
pallet-skip-feeless-payment.workspace = true
xcm-fee-payment-runtime-api.workspace = true
hex-literal.workspace = true
hex.workspace = true

# Runtimes
polkadot-runtime.workspace = true
Expand Down
1 change: 1 addition & 0 deletions integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ mod tests;

pub use constants::{accounts::*, asset_hub, penpal, polimec, polkadot};
pub use frame_support::{assert_noop, assert_ok, pallet_prelude::Weight, parameter_types, traits::Hooks};
use macros::generate_accounts;
pub use parachains_common::{AccountId, AssetHubPolkadotAuraId, AuraId, Balance, BlockNumber};
pub use sp_core::{sr25519, storage::Storage, Encode, Get};
pub use xcm::prelude::*;
Expand Down
5 changes: 3 additions & 2 deletions integration-tests/src/tests/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use crate::PolimecRuntime;
use frame_support::BoundedVec;
pub use pallet_funding::instantiator::{BidParams, ContributionParams, UserToUSDBalance};
use pallet_funding::{
AcceptedFundingAsset, BiddingTicketSizes, ContributingTicketSizes, CurrencyMetadata, ParticipationMode,
PriceProviderOf, ProjectMetadata, ProjectMetadataOf, TicketSize,
AcceptedFundingAsset, BiddingTicketSizes, ContributingTicketSizes, CurrencyMetadata, ParticipantsAccountType,
ParticipationMode, PriceProviderOf, ProjectMetadata, ProjectMetadataOf, TicketSize,
};
use sp_arithmetic::{FixedPointNumber, Percent};

Expand Down Expand Up @@ -88,6 +88,7 @@ pub fn default_project_metadata(issuer: AccountId) -> ProjectMetadataOf<polimec_
participation_currencies: vec![AcceptedFundingAsset::USDT].try_into().unwrap(),
funding_destination_account: issuer,
policy_ipfs_cid: Some(ipfs_hash()),
participants_account_type: ParticipantsAccountType::Polkadot,
}
}
pub fn default_evaluations() -> Vec<UserToUSDBalance<PolimecRuntime>> {
Expand Down
1 change: 1 addition & 0 deletions integration-tests/src/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pub fn project_metadata() -> ProjectMetadataOf<PolimecRuntime> {
.unwrap(),
funding_destination_account: ISSUER.into(),
policy_ipfs_cid: Some(metadata_hash),
participants_account_type: ParticipantsAccountType::Polkadot,
}
}

Expand Down
41 changes: 41 additions & 0 deletions integration-tests/src/tests/ethereum_support.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::*;
use hex_literal::hex;
use sp_runtime::traits::Convert;

generate_accounts!(ETH_BUYER);

#[test]
fn test_hardcoded_signatures() {
let polimec_account: PolimecAccountId = ETH_BUYER.into();
let project_id = 0;

// Values generated with `https://github.com/lrazovic/ethsigner`
let polimec_account_ss58 = polimec_runtime::SS58Converter::convert(polimec_account.clone());
dbg!(polimec_account_ss58);
let ethereum_account: [u8; 20] = hex!("FCAd0B19bB29D4674531d6f115237E16AfCE377c");
let signature: [u8; 65] = hex!("4fa35369a2d654112d3fb419e24dc0d7d61b7e3f23936d6d4df0ac8608fa4530795971d4d1967da60853aa974ad57252a521f97bcd5a68ddea5f8959a5c60b471c");

PolimecNet::execute_with(|| {
assert_ok!(PolimecFunding::verify_receiving_account_signature(
&polimec_account,
project_id,
&Junction::AccountKey20 { network: Some(NetworkId::Ethereum { chain_id: 1 }), key: ethereum_account },
signature,
));
});

let polkadot_signature: [u8; 64] = hex!("7efee88bb61b74c91e6dc0ad48ea5b0118db77a579da8a8a753933d76cdc9e029c11f32a51b00fd3a1e3ce5b56cd1e275b179d4b195e7d527eebc60680291b81");
let mut signature: [u8; 65] = [0u8; 65];
signature[..64].copy_from_slice(polkadot_signature.as_slice());
signature[64] = 0;
let polkadot_address: [u8; 32] = hex!("d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d");

PolimecNet::execute_with(|| {
assert_ok!(PolimecFunding::verify_receiving_account_signature(
&polimec_account,
project_id,
&Junction::AccountId32 { network: Some(NetworkId::Polkadot), id: polkadot_address },
signature,
));
});
}
1 change: 1 addition & 0 deletions integration-tests/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod credentials;
mod ct_migration;
mod defaults;
mod e2e;
mod ethereum_support;
mod evaluator_slash_sideffects;
mod governance;
mod oracle;
Expand Down
7 changes: 6 additions & 1 deletion pallets/funding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ polkadot-parachain-primitives.workspace = true
sp-api.workspace = true
polimec-common-test-utils = { workspace = true, optional = true }
frame-benchmarking = { workspace = true, optional = true }
hex-literal.workspace = true
k256.workspace = true
hex.workspace = true

# Used in the instantiator.
itertools.workspace = true
Expand All @@ -59,7 +62,7 @@ xcm-builder.workspace = true
xcm-executor.workspace = true

[features]
default = [ "std" ]
default = [ "std", "sp-core/serde" ]
std = [
"frame-benchmarking?/std",
"frame-support/std",
Expand Down Expand Up @@ -90,6 +93,8 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
"k256/std",
"hex/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand Down
2 changes: 2 additions & 0 deletions pallets/funding/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ where
participation_currencies: vec![AcceptedFundingAsset::USDT].try_into().unwrap(),
funding_destination_account: issuer,
policy_ipfs_cid: Some(metadata_hash.into()),
participants_account_type: ParticipantsAccountType::Polkadot,
}
}

Expand Down Expand Up @@ -410,6 +411,7 @@ mod benchmarks {
participation_currencies: vec![AcceptedFundingAsset::USDT, AcceptedFundingAsset::USDC].try_into().unwrap(),
funding_destination_account: issuer_funding.clone().clone(),
policy_ipfs_cid: Some(BoundedVec::try_from(IPFS_CID.as_bytes().to_vec()).unwrap()),
participants_account_type: ParticipantsAccountType::Ethereum,
};

let jwt = get_mock_jwt_with_cid(
Expand Down
7 changes: 7 additions & 0 deletions pallets/funding/src/functions/2_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ impl<T: Config> Pallet<T> {
usd_amount: Balance,
did: Did,
whitelisted_policy: Cid,
receiving_account: Junction,
) -> DispatchResultWithPostInfo {
// * Get variables *
let project_metadata = ProjectsMetadata::<T>::get(project_id).ok_or(Error::<T>::ProjectMetadataNotFound)?;
Expand All @@ -88,6 +89,7 @@ impl<T: Config> Pallet<T> {
let total_evaluations_count = EvaluationCounts::<T>::get(project_id);
let user_evaluations_count = Evaluations::<T>::iter_prefix((project_id, evaluator)).count() as u32;
let project_policy = project_metadata.policy_ipfs_cid.ok_or(Error::<T>::ImpossibleState)?;
let project_metadata = ProjectsMetadata::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;

// * Validity Checks *
ensure!(project_policy == whitelisted_policy, Error::<T>::PolicyMismatch);
Expand All @@ -100,6 +102,10 @@ impl<T: Config> Pallet<T> {
);
ensure!(total_evaluations_count < T::MaxEvaluationsPerProject::get(), Error::<T>::TooManyProjectParticipations);
ensure!(user_evaluations_count < T::MaxEvaluationsPerUser::get(), Error::<T>::TooManyUserParticipations);
ensure!(
project_metadata.participants_account_type.junction_is_supported(&receiving_account),
Error::<T>::UnsupportedReceiverAccountJunction
);

let plmc_bond = plmc_usd_price
.reciprocal()
Expand Down Expand Up @@ -129,6 +135,7 @@ impl<T: Config> Pallet<T> {
early_usd_amount,
late_usd_amount,
when: now,
receiving_account,
};

T::NativeCurrency::hold(&HoldReason::Evaluation.into(), evaluator, plmc_bond)?;
Expand Down
20 changes: 18 additions & 2 deletions pallets/funding/src/functions/3_auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,17 @@ impl<T: Config> Pallet<T> {
#[transactional]
pub fn do_bid(params: DoBidParams<T>) -> DispatchResultWithPostInfo {
// * Get variables *
let DoBidParams { bidder, project_id, ct_amount, mode, funding_asset, investor_type, did, whitelisted_policy } =
params;
let DoBidParams {
bidder,
project_id,
ct_amount,
mode,
funding_asset,
investor_type,
did,
whitelisted_policy,
receiving_account,
} = params;
let project_metadata = ProjectsMetadata::<T>::get(project_id).ok_or(Error::<T>::ProjectMetadataNotFound)?;
let project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;

Expand Down Expand Up @@ -110,6 +119,10 @@ impl<T: Config> Pallet<T> {
Error::<T>::TooHigh
);
ensure!(existing_bids.len() < T::MaxBidsPerUser::get() as usize, Error::<T>::TooManyUserParticipations);
ensure!(
project_metadata.participants_account_type.junction_is_supported(&receiving_account),
Error::<T>::UnsupportedReceiverAccountJunction
);

// While there's a remaining amount to bid for
while !amount_to_bid.is_zero() {
Expand All @@ -135,6 +148,7 @@ impl<T: Config> Pallet<T> {
metadata_ticket_size_bounds,
total_bids_by_bidder: existing_bids_amount.saturating_add(perform_bid_calls),
total_bids_for_project: total_bids_for_project.saturating_add(perform_bid_calls),
receiving_account,
};
Self::do_perform_bid(perform_params)?;

Expand Down Expand Up @@ -169,6 +183,7 @@ impl<T: Config> Pallet<T> {
metadata_ticket_size_bounds,
total_bids_by_bidder,
total_bids_for_project,
receiving_account,
} = do_perform_bid_params;

let ticket_size = ct_usd_price.checked_mul_int(ct_amount).ok_or(Error::<T>::BadMath)?;
Expand Down Expand Up @@ -200,6 +215,7 @@ impl<T: Config> Pallet<T> {
mode,
plmc_bond,
when: now,
receiving_account,
};

Self::bond_plmc_with_mode(&bidder, project_id, plmc_bond, mode, funding_asset)?;
Expand Down
8 changes: 8 additions & 0 deletions pallets/funding/src/functions/4_contribution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ impl<T: Config> Pallet<T> {
investor_type,
did,
whitelisted_policy,
receiving_account,
} = params;
let mut project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;
let did_has_winning_bid = DidWithWinningBids::<T>::get(project_id, did.clone());
Expand Down Expand Up @@ -46,6 +47,7 @@ impl<T: Config> Pallet<T> {
investor_type,
did,
whitelisted_policy,
receiving_account,
};

Self::do_perform_contribution(perform_params)
Expand All @@ -63,6 +65,7 @@ impl<T: Config> Pallet<T> {
investor_type,
did,
whitelisted_policy,
receiving_account,
} = params;

let project_metadata = ProjectsMetadata::<T>::get(project_id).ok_or(Error::<T>::ProjectMetadataNotFound)?;
Expand Down Expand Up @@ -107,6 +110,10 @@ impl<T: Config> Pallet<T> {
contributor_ticket_size.usd_ticket_below_maximum_per_did(total_usd_bought_by_did + ticket_size),
Error::<T>::TooHigh
);
ensure!(
project_metadata.participants_account_type.junction_is_supported(&receiving_account),
Error::<T>::UnsupportedReceiverAccountJunction
);

let plmc_bond = Self::calculate_plmc_bond(ticket_size, multiplier)?;
let funding_asset_amount = Self::calculate_funding_asset_amount(ticket_size, funding_asset)?;
Expand All @@ -124,6 +131,7 @@ impl<T: Config> Pallet<T> {
funding_asset_amount,
plmc_bond,
when: now,
receiving_account,
};

// Try adding the new contribution to the system
Expand Down
12 changes: 6 additions & 6 deletions pallets/funding/src/functions/6_settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ use polimec_common::{
migration_types::{MigrationInfo, MigrationOrigin, MigrationStatus, ParticipationType},
ReleaseSchedule,
};
use sp_runtime::{
traits::{Convert, Zero},
Perquintill,
};
use sp_runtime::{traits::Zero, Perquintill};

impl<T: Config> Pallet<T> {
#[transactional]
Expand Down Expand Up @@ -140,6 +137,7 @@ impl<T: Config> Pallet<T> {
ParticipationType::Evaluation,
ct_rewarded,
duration,
evaluation.receiving_account,
)?;
}
Evaluations::<T>::remove((project_id, evaluation.evaluator.clone(), evaluation.id));
Expand Down Expand Up @@ -204,6 +202,7 @@ impl<T: Config> Pallet<T> {
ParticipationType::Bid,
final_ct_amount,
ct_vesting_duration,
bid.receiving_account,
)?;

Self::release_funding_asset(
Expand Down Expand Up @@ -310,6 +309,7 @@ impl<T: Config> Pallet<T> {
ParticipationType::Contribution,
contribution.ct_amount,
ct_vesting_duration,
contribution.receiving_account,
)?;

final_ct_amount = contribution.ct_amount;
Expand Down Expand Up @@ -484,10 +484,10 @@ impl<T: Config> Pallet<T> {
participation_type: ParticipationType,
ct_amount: Balance,
vesting_time: BlockNumberFor<T>,
receiving_account: Junction,
) -> DispatchResult {
UserMigrations::<T>::try_mutate((project_id, origin), |maybe_migrations| -> DispatchResult {
let location_user =
Location::new(0, AccountId32 { network: None, id: T::AccountId32Conversion::convert(origin.clone()) });
let location_user = Location::new(0, receiving_account);
let migration_origin = MigrationOrigin { user: location_user, id, participation_type };
let vesting_time: u64 = vesting_time.try_into().map_err(|_| Error::<T>::BadMath)?;
let migration_info: MigrationInfo = (ct_amount, vesting_time).into();
Expand Down
Loading

0 comments on commit 1cc1e7b

Please sign in to comment.