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

anon mining amm #277

Merged
merged 11 commits into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from 6 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
43 changes: 43 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ codegen-units = 1
members = [
"client",
"primitives",
"pallets/anonymity-mining",
"pallets/asset-registry",
"pallets/hasher",
"pallets/verifier",
Expand Down
86 changes: 86 additions & 0 deletions pallets/anonymity-mining/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
[package]
authors = ["Webb Technologies Inc."]
description = "Pallet that handles rewards from anonymity mining."
edition = "2018"
homepage = "https://substrate.dev"
license = "Unlicense"
name = "pallet-anonymity-mining"
repository = "https://github.com/webb-tools/protocol-substrate"
version = "1.0.0"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "max-encoded-len"] }
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }

pallet-vanchor = { path = "../vanchor", default-features = false }
pallet-asset-registry = { path = "../asset-registry", default-features = false }
pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" }
pallet-hasher = { path = "../hasher", default-features = false }
pallet-mixer = { path = "../mixer", default-features = false }
pallet-mt = { path = "../mt", default-features = false }
pallet-linkable-tree = { path = "../linkable-tree", default-features = false }
pallet-vanchor-verifier = { path = "../vanchor-verifier", default-features = false }
pallet-token-wrapper = { path = "../token-wrapper", default-features = false }
pallet-key-storage = {path = "../key-storage"}
pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
orml-currencies = { git = "https://github.com/open-web3-stack/open-runtime-module-library.git", branch = "polkadot-v0.9.30", default-features = false }
orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library.git", branch = "polkadot-v0.9.30", default-features = false }
orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library.git", branch = "polkadot-v0.9.30", default-features = false }

frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" }
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" }
webb-primitives = { path = "../../primitives", default-features = false }

# Optional dependencies
frame-benchmarking = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30", optional = true }

[dev-dependencies]
hex-literal = "0.2.1"
hex = "0.4"
serde = { version = "1.0.119" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" }
sp-io = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" }
ark-crypto-primitives = { version = "^0.3.0", features = ["r1cs"], default-features = false }
ark-ff = { version = "^0.3.0", default-features = false }
ark-ec = { version = "^0.3.0", default-features = false }
ark-std = { version = "^0.3.0", default-features = false }
ark-relations = { version = "^0.3.0", default-features = false }
ark-serialize = { version = "^0.3.0", default-features = false, features = [ "derive" ] }
ark-bls12-381 = { version = "^0.3.0", default-features = false, features = [ "curve" ] }
ark-bls12-377 = { version = "^0.3.0", default-features = false, features = [ "curve", "r1cs" ] }
ark-bn254 = { version = "^0.3.0", default-features = false, features = [ "curve" ] }
arkworks-setups = { version = "1.2.1", features = ["r1cs"], default-features = false }

[features]
default = ["std"]
std = [
"codec/std",
"frame-support/std",
"frame-system/std",
"sp-runtime/std",
"sp-std/std",
"webb-primitives/std",
"webb-primitives/hashing",
"frame-benchmarking/std",
"orml-currencies/std",
"orml-tokens/std",
"orml-traits/std",
"pallet-asset-registry/std",
"pallet-balances/std",
"pallet-vanchor/std",
"pallet-mt/std",
"pallet-vanchor-verifier/std",
"pallet-token-wrapper/std"

]
runtime-benchmarks = [
"frame-benchmarking",
"frame-system/runtime-benchmarks",
"frame-support/runtime-benchmarks",
]
223 changes: 223 additions & 0 deletions pallets/anonymity-mining/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
// This file is part of Webb.

// Copyright (C) 2021 Webb Technologies Inc.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! # Anonymity Mining Module
//!
//! ## Overview
//!
//! The supported dispatchable functions are documented in the [`Call`] enum.

// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(test)]
pub mod mock;
#[cfg(test)]
mod tests;

use frame_support::{
pallet_prelude::{ensure, DispatchError},
sp_runtime::{
traits::{AccountIdConversion, One, Saturating, Zero},
SaturatedConversion,
},
traits::{Get, Time},
PalletId,
};
use orml_traits::{currency::transactional, MultiCurrency};
use pallet_vanchor::VAnchorConfigration;
use sp_std::{convert::TryInto, prelude::*, vec};
use webb_primitives::{
traits::vanchor::{VAnchorInspector, VAnchorInterface},
types::runtime::Moment,
};

pub use pallet::*;

/// Type alias for the orml_traits::MultiCurrency::Balance type
pub type BalanceOf<T, I> =
<<T as Config<I>>::Currency as MultiCurrency<<T as frame_system::Config>::AccountId>>::Balance;
/// Type alias for the orml_traits::MultiCurrency::CurrencyId type
pub type CurrencyIdOf<T, I> = <<T as pallet::Config<I>>::Currency as MultiCurrency<
<T as frame_system::Config>::AccountId,
>>::CurrencyId;

#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::{dispatch::DispatchResultWithPostInfo, pallet_prelude::*};
use frame_system::pallet_prelude::*;

#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info]
pub struct Pallet<T, I = ()>(_);

#[pallet::config]
/// The module configuration trait.
pub trait Config<I: 'static = ()>:
frame_system::Config + pallet_balances::Config + pallet_vanchor::Config<I>
{
/// The overarching event type.
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;

/// Account Identifier from which the internal Pot is generated.
type PotId: Get<PalletId>;

/// Currency type for taking deposits
type Currency: MultiCurrency<Self::AccountId>;

/// VAnchor Interface
type VAnchor: VAnchorInterface<VAnchorConfigration<Self, I>>
+ VAnchorInspector<VAnchorConfigration<Self, I>>;

/// AP asset id
#[pallet::constant]
type AnonymityPointsAssetId: Get<CurrencyIdOf<Self, I>>;

/// Reward asset id
#[pallet::constant]
type RewardAssetId: Get<CurrencyIdOf<Self, I>>;

/// Native currency id
#[pallet::constant]
type NativeCurrencyId: Get<CurrencyIdOf<Self, I>>;

// /// Time provider
type Time: Time;

/// Start time
type StartTimestamp: Time;

#[pallet::constant]
type PoolWeight: Get<u64>;

#[pallet::constant]
type Duration: Get<u64>;

/// The origin which may forcibly reset parameters or otherwise alter
/// privileged attributes.
type ForceOrigin: EnsureOrigin<Self::RuntimeOrigin>;
}

#[pallet::genesis_config]
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
pub phantom: (PhantomData<T>, PhantomData<I>),
}

#[cfg(feature = "std")]
impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
fn default() -> Self {
Self { phantom: Default::default() }
}
}

#[pallet::genesis_build]
impl<T: Config<I>, I: 'static> GenesisBuild<T, I> for GenesisConfig<T, I> {
fn build(&self) {}
}

#[pallet::storage]
#[pallet::getter(fn parameters)]
/// Details of the module's parameters
pub(super) type Parameters<T: Config<I>, I: 'static = ()> =
StorageValue<_, Vec<u8>, ValueQuery>;

#[pallet::event]
pub enum Event<T: Config<I>, I: 'static = ()> {}

#[pallet::error]
pub enum Error<T, I = ()> {
/// Parameters haven't been initialized
ParametersNotInitialized,
/// Error during hashing
HashError,
}

#[pallet::call]
impl<T: Config<I>, I: 'static> Pallet<T, I> {
#[pallet::weight(0)]
pub fn swap(
origin: OriginFor<T>,
recipient: T::AccountId,
amount: BalanceOf<T, I>,
) -> DispatchResultWithPostInfo {
ensure_signed(origin)?;
let tokens = Self::get_expected_return(&Self::account_id(), amount).unwrap();
drewstone marked this conversation as resolved.
Show resolved Hide resolved

// Deposit AP tokens to the pallet
<T as Config<I>>::Currency::transfer(
T::AnonymityPointsAssetId::get(),
&recipient,
&Self::account_id(),
amount,
)?;

// Pallet sends reward tokens
<T as Config<I>>::Currency::transfer(
T::RewardAssetId::get(),
&Self::account_id(),
&recipient,
amount,
)?;

Ok(().into())
}
}
}

impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Get a unique, inaccessible account id from the `PotId`.
pub fn account_id() -> T::AccountId {
T::PotId::get().into_account_truncating()
}

/// Get expected number of tokens to swap
pub fn get_expected_return(
addr: &T::AccountId,
amount: BalanceOf<T, I>,
) -> Result<BalanceOf<T, I>, DispatchError> {
let old_balance = Self::get_virtual_balance(addr).unwrap();
// let pow =
// (amount.saturated_into::<u64>()).saturating_mul(<T as Config<I>>::PoolWeight::get());
let pow = 0;
let one: u64 = 1;
let exp = one.saturating_pow(pow.try_into().unwrap()) / 2;
let new_balance = (old_balance.saturated_into::<u64>()).saturating_mul(exp);
//let final_balance = old_balance - new_balance;
let final_balance = old_balance.saturating_sub(new_balance.saturated_into::<BalanceOf<T,
I>>());
Ok(final_balance)
}

/// Calculate balance to use
pub fn get_virtual_balance(addr: &T::AccountId) -> Result<BalanceOf<T, I>, DispatchError> {
let reward_balance =
<T as Config<I>>::Currency::total_balance(T::RewardAssetId::get(), addr);
let start_timestamp = T::Time::now();
let current_timestamp = T::Time::now();
let elapsed_timestamp = current_timestamp - start_timestamp;
drewstone marked this conversation as resolved.
Show resolved Hide resolved
let elapsed = elapsed_timestamp.saturated_into::<u64>();
if elapsed <= <T as Config<I>>::Duration::get() {
// TODO: initialLiquidity + (L * elapsed) / duration - tokensSold
return Ok(reward_balance)
} else {
return Ok(reward_balance)
}
}
}
Loading