diff --git a/Cargo.lock b/Cargo.lock
index 8e8b388e66..94c785d58e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1349,6 +1349,36 @@ dependencies = [
"lazy_static",
]
+[[package]]
+name = "crowdloan-rewards-precompiles"
+version = "0.6.0"
+dependencies = [
+ "cumulus-pallet-parachain-system",
+ "cumulus-primitives-core",
+ "cumulus-primitives-parachain-inherent",
+ "cumulus-test-relay-sproof-builder",
+ "derive_more",
+ "evm",
+ "frame-support",
+ "frame-system",
+ "log",
+ "max-encoded-len",
+ "pallet-balances",
+ "pallet-crowdloan-rewards",
+ "pallet-evm",
+ "pallet-scheduler",
+ "pallet-timestamp",
+ "parity-scale-codec",
+ "precompile-utils",
+ "rustc-hex",
+ "serde",
+ "sha3 0.9.1",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
[[package]]
name = "crunchy"
version = "0.2.2"
@@ -2161,6 +2191,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
+[[package]]
+name = "faster-hex"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b02a61fea82de8484f9d7ce99b698b0e190ef8de71035690a961a43d7b18a2ad"
+
[[package]]
name = "fastrand"
version = "1.5.0"
@@ -4788,6 +4824,7 @@ name = "moonbase-runtime"
version = "0.8.4"
dependencies = [
"account",
+ "crowdloan-rewards-precompiles",
"cumulus-pallet-parachain-system",
"cumulus-primitives-core",
"cumulus-primitives-parachain-inherent",
@@ -5112,6 +5149,7 @@ name = "moonbeam-runtime"
version = "0.8.4"
dependencies = [
"account",
+ "crowdloan-rewards-precompiles",
"cumulus-pallet-parachain-system",
"cumulus-primitives-core",
"cumulus-primitives-parachain-inherent",
@@ -5303,6 +5341,7 @@ name = "moonriver-runtime"
version = "0.8.4"
dependencies = [
"account",
+ "crowdloan-rewards-precompiles",
"cumulus-pallet-parachain-system",
"cumulus-primitives-core",
"cumulus-primitives-parachain-inherent",
@@ -5376,6 +5415,7 @@ name = "moonshadow-runtime"
version = "0.8.4"
dependencies = [
"account",
+ "crowdloan-rewards-precompiles",
"cumulus-pallet-parachain-system",
"cumulus-primitives-core",
"cumulus-primitives-parachain-inherent",
@@ -8245,6 +8285,22 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+[[package]]
+name = "precompile-utils"
+version = "0.1.0"
+dependencies = [
+ "evm",
+ "frame-support",
+ "frame-system",
+ "log",
+ "pallet-evm",
+ "parity-scale-codec",
+ "slices",
+ "sp-core",
+ "sp-io",
+ "sp-std",
+]
+
[[package]]
name = "predicates"
version = "1.0.8"
@@ -10528,6 +10584,18 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
+[[package]]
+name = "slices"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2086e458a369cdca838e9f6ed04b4cc2e3ce636d99abb80c9e2eada107749cf"
+dependencies = [
+ "faster-hex",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "slog"
version = "2.7.0"
diff --git a/Cargo.toml b/Cargo.toml
index e20d54cb15..fe75ed6ed5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ members = [
'node',
'node/cli',
'node/service',
- 'bin/utils/moonkey'
+ 'bin/utils/moonkey',
]
exclude = [
'bin/utils/moonkey'
diff --git a/precompiles/crowdloan-rewards/Cargo.toml b/precompiles/crowdloan-rewards/Cargo.toml
new file mode 100644
index 0000000000..4a2bce724d
--- /dev/null
+++ b/precompiles/crowdloan-rewards/Cargo.toml
@@ -0,0 +1,48 @@
+[package]
+name = "crowdloan-rewards-precompiles"
+version = "0.6.0"
+authors = ["PureStake"]
+edition = "2018"
+description = "A Precompile to make crowdloan rewards accessible to pallet-evm"
+
+[dependencies]
+log = "0.4"
+rustc-hex = { version = "2.0.1", default-features = false }
+
+frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8", default-features = false }
+evm = { version = "0.27.0", default-features = false, features = ["with-codec"] }
+sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.8" }
+sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.8" }
+pallet-evm = { git = "https://github.com/purestake/frontier", default-features = false, branch = "moonbeam-polkadot-v0.9.8" }
+pallet-crowdloan-rewards = { git = "https://github.com/purestake/crowdloan-rewards", default-features = false, branch = "main" }
+frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.8" }
+precompile-utils = { path = "../utils", default-features = false }
+
+[dev-dependencies]
+sha3 = "0.9"
+sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.8" }
+codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false }
+sp-runtime = { git="https://github.com/paritytech/substrate", branch="polkadot-v0.9.8" }
+pallet-balances = { git="https://github.com/paritytech/substrate", branch="polkadot-v0.9.8" }
+pallet-timestamp = { git="https://github.com/paritytech/substrate", branch="polkadot-v0.9.8" }
+pallet-scheduler = { git="https://github.com/paritytech/substrate", branch="polkadot-v0.9.8" }
+max-encoded-len = { git="https://github.com/paritytech/substrate", branch="polkadot-v0.9.8", features=["derive"] }
+serde = "1.0.100"
+derive_more = "0.99"
+cumulus-primitives-parachain-inherent = { git = "https://github.com/purestake/cumulus", default-features = false, branch = "joshy-np098" }
+cumulus-pallet-parachain-system = { git = "https://github.com/purestake/cumulus", default-features = false, branch = "joshy-np098" }
+cumulus-primitives-core = { git = "https://github.com/purestake/cumulus", default-features = false, branch = "joshy-np098" }
+cumulus-test-relay-sproof-builder = { git = "https://github.com/purestake/cumulus", default-features = false, branch = "joshy-np098" }
+
+[features]
+default = ["std"]
+std = [
+ "frame-support/std",
+ "evm/std",
+ "sp-std/std",
+ "sp-core/std",
+ "pallet-crowdloan-rewards/std",
+ "frame-system/std",
+ "precompile-utils/std",
+ "pallet-evm/std",
+]
diff --git a/precompiles/crowdloan-rewards/CrowdloanInterface.sol b/precompiles/crowdloan-rewards/CrowdloanInterface.sol
new file mode 100644
index 0000000000..81578d2923
--- /dev/null
+++ b/precompiles/crowdloan-rewards/CrowdloanInterface.sol
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-3.0-only
+pragma solidity >=0.8.0;
+
+/// @author The Moonbeam Team
+/// @title The interface through which solidity contracts will interact with Crowdloan Rewards
+/// We follow this same interface including four-byte function selectors, in the precompile that
+/// wraps the pallet
+interface CrowdloanRewards {
+ // First some simple accessors
+
+ /// @dev Checks whether the address is a contributor
+ /// @param contributor the address that we want to confirm is a contributor
+ /// @return A boolean confirming whether the address is a contributor
+ function is_contributor(address contributor) external view returns (bool);
+
+ /// @dev Retrieve total reward and claimed reward for an address
+ /// @param contributor the address for which we want to retrieve the information
+ /// @return A u256 tuple, reflecting (total_rewards, claimed_rewards)
+ function reward_info(address contributor) external view returns (uint256, uint256);
+
+ // Now the dispatchables
+
+ /// @dev Claim the vested amount from the crowdloan rewards
+ function claim() external;
+
+ /// @dev Update reward address to receive crowdloan rewards
+ /// @param new_address, the new_address where to receive the rewards from now on
+ function update_reward_address(address new_address) external;
+
+}
+
+// These are the selectors generated by remix following this advice
+// https://ethereum.stackexchange.com/a/73405/9963
+// Eventually we will probably want a better way of generating these and copying them to Rust
+
+//{
+// "53440c90": "is_contributor(address)"
+// "76f70249": "reward_info(address)"
+// "4e71d92d": "claim()"
+// "aaac61d6": "update_reward_address(address)"
+//}
\ No newline at end of file
diff --git a/precompiles/crowdloan-rewards/src/lib.rs b/precompiles/crowdloan-rewards/src/lib.rs
new file mode 100644
index 0000000000..f184ac6178
--- /dev/null
+++ b/precompiles/crowdloan-rewards/src/lib.rs
@@ -0,0 +1,273 @@
+// Copyright 2019-2021 PureStake Inc.
+// This file is part of Moonbeam.
+
+// Moonbeam is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Moonbeam is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Moonbeam. If not, see .
+
+//! Precompile to call pallet-crowdloan-rewards runtime methods via the EVM
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use evm::{executor::PrecompileOutput, Context, ExitError, ExitSucceed};
+use frame_support::{
+ dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo},
+ traits::{Currency, Get},
+};
+use pallet_evm::{AddressMapping, GasWeightMapping, Precompile};
+use precompile_utils::{error, InputReader, OutputBuilder};
+
+use sp_core::{H160, U256};
+use sp_std::{
+ convert::{TryFrom, TryInto},
+ fmt::Debug,
+ marker::PhantomData,
+};
+
+#[cfg(test)]
+mod mock;
+#[cfg(test)]
+mod tests;
+
+type BalanceOf =
+ <::RewardCurrency as Currency<
+ ::AccountId,
+ >>::Balance;
+
+/// A precompile to wrap the functionality from pallet_crowdloan_rewards.
+pub struct CrowdloanRewardsWrapper(PhantomData);
+
+impl Precompile for CrowdloanRewardsWrapper
+where
+ Runtime: pallet_crowdloan_rewards::Config + pallet_evm::Config,
+ Runtime::AccountId: From,
+ BalanceOf: TryFrom + Debug,
+ Runtime::Call: Dispatchable + GetDispatchInfo,
+ ::Origin: From