Skip to content

Commit

Permalink
Merge pull request #112 from Brushfam/feature/erc165
Browse files Browse the repository at this point in the history
  • Loading branch information
Artemka374 authored Aug 30, 2023
2 parents b8fc8a0 + d145cfd commit 1371707
Show file tree
Hide file tree
Showing 13 changed files with 366 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ governance = ["openbrush_contracts/governance", "openbrush_contracts/checkpoints
crypto = ["openbrush_contracts/crypto"]
nonces = ["openbrush_contracts/nonces"]
checkpoints = ["openbrush_contracts/checkpoints"]
psp61 = ["openbrush_contracts/psp61"]

test-all = [
"psp22",
Expand Down
2 changes: 2 additions & 0 deletions contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ ownable = []
payment_splitter = []
reentrancy_guard = []
pausable = []
psp61 = []
timelock_controller = [
"access_control",
]
Expand All @@ -72,6 +73,7 @@ test-all = [
"psp22",
"psp34",
"psp37",
"psp61",
"access_control",
"ownable",
"payment_splitter",
Expand Down
2 changes: 2 additions & 0 deletions contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,5 @@ pub use upgradeability::proxy;
pub use upgradeability::upgradeable;
#[cfg(feature = "nonces")]
pub use utils::nonces;
#[cfg(feature = "psp61")]
pub use utils::psp61;
1 change: 1 addition & 0 deletions contracts/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub mod proxy;
pub mod psp22;
pub mod psp34;
pub mod psp37;
pub mod psp61;
pub mod upgradeable;

pub mod types;
10 changes: 10 additions & 0 deletions contracts/src/traits/psp61/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use ink::prelude::vec::Vec;

#[openbrush::trait_definition]
pub trait PSP61 {
#[ink(message)]
fn supports_interface(&self, interface_id: u32) -> bool;

#[ink(message)]
fn supported_interfaces(&self) -> Vec<u32>;
}
3 changes: 3 additions & 0 deletions contracts/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@

#[cfg(feature = "nonces")]
pub mod nonces;

#[cfg(feature = "psp61")]
pub mod psp61;
67 changes: 67 additions & 0 deletions contracts/src/utils/psp61/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) 2012-2023 727-ventures
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the"Software"),
// to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pub use crate::{
psp61,
traits::psp61::*,
};
use ink::prelude::{
vec,
vec::Vec,
};

pub trait PSP61Internal {
fn _interfaces(&self) -> Vec<u32> {
vec![]
}
}

pub trait PSP61InternalOB {
fn _interfaces_ob(&self) -> Vec<u32> {
vec![]
}
}

pub trait PSP61Impl: PSP61Internal + PSP61InternalOB {
fn supports_interface(&self, interface_id: u32) -> bool {
self._interfaces().contains(&interface_id) || self._interfaces_ob().contains(&interface_id)
}

fn supported_interfaces(&self) -> Vec<u32> {
let mut interfaces = self._interfaces();
interfaces.append(&mut self._interfaces_ob());
interfaces
}
}

#[macro_export]
macro_rules! supported_interfaces {
($contract:ident => $($interface_id:expr),*) => {
impl ::openbrush::contracts::psp61::PSP61Internal for $contract {
fn _interfaces(&self) -> ::ink::prelude::vec::Vec<u32> {
::ink::prelude::vec![$($interface_id),*]
}
}
};
($contract:ident) => {
impl ::openbrush::contracts::psp61::PSP61Internal for $contract {}
};
}
6 changes: 1 addition & 5 deletions examples/payment_splitter/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ pub mod my_payment_splitter {
#[rustfmt::skip]
use ink_e2e::{build_message, PolkadotConfig};

use test_helpers::{
address_of,
get_shares,
method_call,
};
use test_helpers::{address_of, get_shares, method_call};

type E2EResult<T> = Result<T, Box<dyn std::error::Error>>;

Expand Down
46 changes: 46 additions & 0 deletions examples/psp61/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[package]
name = "my_psp61"
version = "3.1.1"
authors = ["Brushfam <[email protected]>"]
edition = "2021"

[dependencies]
ink = { version = "4.2.1", default-features = false}

scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true }

# These dependencies
openbrush = { path = "../..", default-features = false, features = [
"psp61",
"ownable",
"access_control",
"pausable",
"reentrancy_guard",
"upgradeable",
"payment_splitter"
] }

[dev-dependencies]
ink_e2e = "4.2.1"
test_helpers = { path = "../test_helpers", default-features = false }

[lib]
name = "my_psp61"
path = "lib.rs"


[features]
default = ["std"]
std = [
"ink/std",
"scale/std",
"scale-info/std",
# These dependencies
"openbrush/std",
]
ink-as-dependency = []
e2e-tests = []

[profile.dev]
codegen-units = 16
154 changes: 154 additions & 0 deletions examples/psp61/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

#[openbrush::implementation(PSP61, Ownable, AccessControl, Pausable, Upgradeable)]
#[openbrush::contract]
pub mod my_psp61 {
use ink::prelude::{
vec,
vec::Vec,
};
use openbrush::{
contracts::supported_interfaces,
traits::{
Storage,
String,
},
};

#[ink(storage)]
#[derive(Default, Storage)]
pub struct Contract {
#[storage_field]
pub ownable: ownable::Data,
#[storage_field]
pub access_control: access_control::Data,
#[storage_field]
pub pausable: pausable::Data,
}

supported_interfaces!(Contract);

impl Contract {
#[ink(constructor)]
pub fn new() -> Self {
Self::default()
}

#[ink(message)]
pub fn ownable_id(&self) -> u32 {
ownable::ownable_external::TRAIT_ID
}

#[ink(message)]
pub fn access_control_id(&self) -> u32 {
access_control::accesscontrol_external::TRAIT_ID
}

#[ink(message)]
pub fn pausable_id(&self) -> u32 {
pausable::pausable_external::TRAIT_ID
}

#[ink(message)]
pub fn upgradeable_id(&self) -> u32 {
upgradeable::upgradeable_external::TRAIT_ID
}

#[ink(message)]
pub fn psp61_id(&self) -> u32 {
psp61::psp61_external::TRAIT_ID
}

#[ink(message)]
pub fn id_batch(&self) -> Vec<(String, u32)> {
vec![
(String::from("ownable"), ownable::ownable_external::TRAIT_ID),
(
String::from("access_control"),
access_control::accesscontrol_external::TRAIT_ID,
),
(String::from("pausable"), pausable::pausable_external::TRAIT_ID),
(String::from("upgradeable"), upgradeable::upgradeable_external::TRAIT_ID),
(String::from("psp61"), psp61::psp61_external::TRAIT_ID),
]
}
}

#[cfg(test)]
mod tests {
use super::Contract;
use openbrush::contracts::{
access_control,
ownable,
pausable,
psp61,
psp61::PSP61,
upgradeable,
};

#[ink::test]
fn assure_ids_are_proper() {
let contract = Contract::new();

assert_eq!(contract.ownable_id(), ownable::ownable_external::TRAIT_ID);
assert_eq!(
contract.access_control_id(),
access_control::accesscontrol_external::TRAIT_ID
);
assert_eq!(contract.pausable_id(), pausable::pausable_external::TRAIT_ID);
assert_eq!(contract.upgradeable_id(), upgradeable::upgradeable_external::TRAIT_ID);
assert_eq!(contract.psp61_id(), psp61::psp61_external::TRAIT_ID);
}

#[ink::test]
fn check_for_interfaces() {
let contract = Contract::new();

assert_eq!(contract.supports_interface(ownable::ownable_external::TRAIT_ID), true);
assert_eq!(
contract.supports_interface(access_control::accesscontrol_external::TRAIT_ID),
true
);
assert_eq!(contract.supports_interface(pausable::pausable_external::TRAIT_ID), true);
assert_eq!(
contract.supports_interface(upgradeable::upgradeable_external::TRAIT_ID),
true
);
assert_eq!(contract.supports_interface(psp61::psp61_external::TRAIT_ID), true);
}

#[ink::test]
fn check_for_interfaces_batch() {
let contract = Contract::new();

let ids = contract.id_batch();
let mut interfaces = contract.supported_interfaces();

let mut ids: Vec<_> = ids
.into_iter()
.map(|(_, id)| {
assert_eq!(contract.supports_interface(id), true);
id
})
.collect();

ids.sort_unstable();
interfaces.sort_unstable();

assert_eq!(ids, interfaces);
}

#[ink::test]
fn check_for_non_existing_interface() {
let contract = Contract::new();

assert_eq!(contract.supports_interface(0), false);

let interfaces = contract.supported_interfaces();

interfaces.into_iter().for_each(|id| {
assert_eq!(contract.supports_interface(id + 1), false);
});
}
}
}
3 changes: 2 additions & 1 deletion lang/codegen/src/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub fn generate(attrs: TokenStream, ink_module: TokenStream) -> TokenStream {

let mut impl_args = ImplArgs::new(&map, &mut items, &mut imports, &mut overriden_traits, ident);

for to_implement in args {
for to_implement in &args {
match to_implement.as_str() {
"PSP22" => impl_psp22(&mut impl_args),
"PSP22Mintable" => impl_psp22_mintable(&mut impl_args),
Expand Down Expand Up @@ -119,6 +119,7 @@ pub fn generate(attrs: TokenStream, ink_module: TokenStream) -> TokenStream {
"GovernorQuorum" => impl_governor_quorum(&mut impl_args),
"GovernorCounting" => impl_governor_counting(&mut impl_args),
"Nonces" => impl_nonces(&mut impl_args),
"PSP61" => impl_psp61(&mut impl_args, args.clone()),
_ => panic!("openbrush::implementation({to_implement}) not implemented!"),
}
}
Expand Down
Loading

0 comments on commit 1371707

Please sign in to comment.