Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated mapping api
Browse files Browse the repository at this point in the history
kubaplas committed Dec 7, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent a7fb17d commit 1a961f1
Showing 12 changed files with 120 additions and 105 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/odra-ci.yml
Original file line number Diff line number Diff line change
@@ -26,5 +26,6 @@ jobs:
target: wasm32-unknown-unknown
components: rustfmt, clippy
- run: just check-lint
# - run: just prepare-test-env
- run: just prepare-test-env
- run: cd examples2 && cargo odra test && cargo odra test -b casper
# - run: just test
8 changes: 4 additions & 4 deletions core/src/mapping.rs
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ impl<K: ToBytes, V> Mapping<K, V> {
}

impl<K: ToBytes, V> Mapping<K, V> {
fn env_for_key(&self, key: K) -> ContractEnv {
fn env_for_key(&self, key: &K) -> ContractEnv {
let mut env = (*self.parent_env).clone();
let key = key.to_bytes().unwrap_or_default();
env.add_to_mapping_data(&key);
@@ -33,21 +33,21 @@ impl<K: ToBytes, V> Mapping<K, V> {
}

impl<K: ToBytes, V: FromBytes + CLTyped + Default> Mapping<K, V> {
pub fn get_or_default(&self, key: K) -> V {
pub fn get_or_default(&self, key: &K) -> V {
let env = self.env_for_key(key);
Variable::<V>::new(Rc::new(env), self.index).get_or_default()
}
}

impl<K: ToBytes, V: ToBytes + CLTyped> Mapping<K, V> {
pub fn set(&mut self, key: K, value: V) {
pub fn set(&mut self, key: &K, value: V) {
let env = self.env_for_key(key);
Variable::<V>::new(Rc::new(env), self.index).set(value)
}
}

impl<K: ToBytes, V: Module> Mapping<K, V> {
pub fn module(&self, key: K) -> ModuleWrapper<V> {
pub fn module(&self, key: &K) -> ModuleWrapper<V> {
let env = self.env_for_key(key);
ModuleWrapper::new(Rc::new(env), self.index)
}
13 changes: 12 additions & 1 deletion core/src/variable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::prelude::*;
use crate::{CLTyped, FromBytes, ToBytes};
use crate::{CLTyped, FromBytes, OdraError, ToBytes, UnwrapOrRevert};

use crate::contract_env::ContractEnv;

@@ -30,6 +30,17 @@ impl<T: FromBytes + Default> Variable<T> {
let env = self.env();
env.get_value(&env.current_key()).unwrap_or_default()
}

pub fn get(&self) -> Option<T> {
let env = self.env();
env.get_value(&env.current_key())
}

pub fn get_or_revert_with<E: Into<OdraError>>(&self, error: E) -> T {
let env = self.env();
env.get_value(&env.current_key())
.unwrap_or_revert_with(&env, error)
}
}

impl<T: ToBytes + CLTyped> Variable<T> {
4 changes: 4 additions & 0 deletions examples2/Odra.toml
Original file line number Diff line number Diff line change
@@ -5,3 +5,7 @@ fqn = "examples2::Erc20"
[[contracts]]
name = "CounterPack"
fqn = "examples2::CounterPack"

[[contracts]]
name = "ReentrancyMock"
fqn = "examples2::ReentrancyMock"
25 changes: 14 additions & 11 deletions examples2/src/erc20.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use casper_event_standard::Event;
use odra::{casper_event_standard, Bytes, Module, OdraError, PublicKey};
use odra::{prelude::*, CallDef, Event, ModuleWrapper};
use odra::{prelude::*, CallDef, ModuleWrapper};
use odra::{Address, ContractEnv, Mapping, Variable, U256, U512};

#[derive(Event, Eq, PartialEq, Debug)]
@@ -48,7 +49,7 @@ impl Erc20 {
pub fn init(&mut self, total_supply: Option<U256>) {
if let Some(total_supply) = total_supply {
self.total_supply.set(total_supply);
self.balances.set(self.env().caller(), total_supply);
self.balances.set(&self.env().caller(), total_supply);
}
}

@@ -65,19 +66,19 @@ impl Erc20 {
}

pub fn balance_of(&self, owner: Address) -> U256 {
self.balances.get_or_default(owner)
self.balances.get_or_default(&owner)
}

pub fn transfer(&mut self, to: Address, value: U256) {
let caller = self.env().caller();
let balances = &mut self.balances;
let from_balance = balances.get_or_default(caller);
let to_balance = balances.get_or_default(to);
let from_balance = balances.get_or_default(&caller);
let to_balance = balances.get_or_default(&to);
if from_balance < value {
self.env().revert(Erc20Error::InsufficientBalance)
}
balances.set(caller, from_balance.saturating_sub(value));
balances.set(to, to_balance.saturating_add(value));
balances.set(&caller, from_balance.saturating_sub(value));
balances.set(&to, to_balance.saturating_add(value));
self.env.emit_event(OnTransfer {
from: Some(caller),
to: Some(to),
@@ -99,8 +100,10 @@ impl Erc20 {
let attached_value = self.env().attached_value();
let caller = self.env().caller();
let caller_balance = self.balance_of(caller);
self.balances
.set(caller, caller_balance + U256::from(attached_value.as_u64()));
self.balances.set(
&caller,
caller_balance + U256::from(attached_value.as_u64())
);
self.total_supply
.set(self.total_supply() + U256::from(attached_value.as_u64()));
}
@@ -116,7 +119,7 @@ impl Erc20 {
self.env().revert(Erc20Error::InsufficientBalance)
}

self.balances.set(caller, caller_balance - amount);
self.balances.set(&caller, caller_balance - amount);
self.total_supply.set(self.total_supply() - amount);
self.env()
.transfer_tokens(&caller, &U512::from(amount.as_u64()));
@@ -186,7 +189,7 @@ mod tests {

// Test cross calls
let mut pobcoin = Erc20Deployer::init(&env, Some(100.into()));
assert_eq!(erc20.cross_total(pobcoin.address.clone()), 200.into());
assert_eq!(erc20.cross_total(pobcoin.address), 200.into());

// Test attaching value and balances
let initial_balance = U512::from(100000000000000000u64);
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ check-lint: clippy
# cd examples && cargo check --no-default-features -F casper-livenet

install-cargo-odra:
cargo install cargo-odra --locked
git clone [email protected]:odradev/cargo-odra.git && cd cargo-odra && just install

prepare-test-env: install-cargo-odra
rustup target add wasm32-unknown-unknown
1 change: 1 addition & 0 deletions modules/Cargo.toml
Original file line number Diff line number Diff line change
@@ -11,4 +11,5 @@ categories = ["wasm"]

[dependencies]
odra = { path = "../odra", version = "0.8.0", default-features = false }
casper-event-standard = "0.4.1"
hex = { version = "0.4.3", default-features = false }
58 changes: 29 additions & 29 deletions modules/Odra.toml
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
[[contracts]]
name = "erc20"
fqn = "odra_modules::erc20::Erc20"

[[contracts]]
name = "erc721_token"
fqn = "odra_modules::erc721_token::Erc721Token"

[[contracts]]
name = "erc721_receiver"
fqn = "odra_modules::erc721_receiver::Erc721Receiver"

[[contracts]]
name = "erc1155_token"
fqn = "odra_modules::erc1155_token::Erc1155Token"

[[contracts]]
name = "erc1155_receiver"
fqn = "odra_modules::erc1155_receiver::Erc1155Receiver"

[[contracts]]
name = "wrapped_native_token"
fqn = "odra_modules::wrapped_native::WrappedNativeToken"

[[contracts]]
name = "ownable"
fqn = "odra_modules::access::Ownable"

[[contracts]]
name = "ownable2_step"
fqn = "odra_modules::access::Ownable2Step"

#
#[[contracts]]
#name = "erc721_token"
#fqn = "odra_modules::erc721_token::Erc721Token"
#
#[[contracts]]
#name = "erc721_receiver"
#fqn = "odra_modules::erc721_receiver::Erc721Receiver"
#
#[[contracts]]
#name = "erc1155_token"
#fqn = "odra_modules::erc1155_token::Erc1155Token"
#
#[[contracts]]
#name = "erc1155_receiver"
#fqn = "odra_modules::erc1155_receiver::Erc1155Receiver"
#
#[[contracts]]
#name = "wrapped_native_token"
#fqn = "odra_modules::wrapped_native::WrappedNativeToken"
#
#[[contracts]]
#name = "ownable"
#fqn = "odra_modules::access::Ownable"
#
#[[contracts]]
#name = "ownable2_step"
#fqn = "odra_modules::access::Ownable2Step"
#
71 changes: 34 additions & 37 deletions modules/src/erc20.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
use odra::prelude::string::String;
use odra::{
contract_env,
types::{event::OdraEvent, Address, U256},
Mapping, UnwrapOrRevert, Variable
};

use self::{
errors::Error,
events::{Approval, Transfer}
};
use odra::prelude::*;
use odra::{Address, ContractEnv, Mapping, U256, Variable};
use crate::erc20::errors::Error::{DecimalsNotSet, NameNotSet, SymbolNotSet};
use crate::erc20::events::*;

#[odra::module(events = [Approval, Transfer])]
pub struct Erc20 {
env: Rc<ContractEnv>,
decimals: Variable<u8>,
symbol: Variable<String>,
name: Variable<String>,
@@ -22,48 +16,47 @@ pub struct Erc20 {

#[odra::module]
impl Erc20 {
#[odra(init)]
pub fn init(
&mut self,
symbol: String,
name: String,
decimals: u8,
initial_supply: &Option<U256>
initial_supply: Option<U256>
) {
let caller = contract_env::caller();
let caller = self.env.caller();
self.symbol.set(symbol);
self.name.set(name);
self.decimals.set(decimals);

if let Some(initial_supply) = *initial_supply {
if let Some(initial_supply) = initial_supply {
self.total_supply.set(initial_supply);
self.balances.set(&caller, initial_supply);

if !initial_supply.is_zero() {
self.env.emit_event(
Transfer {
from: None,
to: Some(caller),
amount: initial_supply
}
.emit();
});
}
}
}

pub fn transfer(&mut self, recipient: &Address, amount: &U256) {
let caller = contract_env::caller();
let caller = self.env.caller();
self.raw_transfer(&caller, recipient, amount);
}

pub fn transfer_from(&mut self, owner: &Address, recipient: &Address, amount: &U256) {
let spender = contract_env::caller();
let spender = self.env.caller();

self.spend_allowance(owner, &spender, amount);
self.raw_transfer(owner, recipient, amount);
}

pub fn approve(&mut self, spender: &Address, amount: &U256) {
let owner = contract_env::caller();
let owner = self.env.caller();

self.allowances.get_instance(&owner).set(spender, *amount);
Approval {
@@ -75,17 +68,17 @@ impl Erc20 {
}

pub fn name(&self) -> String {
self.name.get().unwrap_or_revert_with(Error::NameNotSet)
self.name.get_or_default().unwrap_or_revert_with(NameNotSet)
}

pub fn symbol(&self) -> String {
self.symbol.get().unwrap_or_revert_with(Error::SymbolNotSet)
self.symbol.get().unwrap_or_revert_with(SymbolNotSet)
}

pub fn decimals(&self) -> u8 {
self.decimals
.get()
.unwrap_or_revert_with(Error::DecimalsNotSet)
.unwrap_or_revert_with(DecimalsNotSet)
}

pub fn total_supply(&self) -> U256 {
@@ -114,7 +107,7 @@ impl Erc20 {

pub fn burn(&mut self, address: &Address, amount: &U256) {
if self.balance_of(address) < *amount {
contract_env::revert(Error::InsufficientBalance);
self.env.revert(Error::InsufficientBalance);
}
self.total_supply.subtract(*amount);
self.balances.subtract(address, *amount);
@@ -131,7 +124,7 @@ impl Erc20 {
impl Erc20 {
fn raw_transfer(&mut self, owner: &Address, recipient: &Address, amount: &U256) {
if *amount > self.balances.get_or_default(owner) {
contract_env::revert(Error::InsufficientBalance)
self.env.revert(Error::InsufficientBalance)
}

self.balances.subtract(owner, *amount);
@@ -148,7 +141,7 @@ impl Erc20 {
fn spend_allowance(&mut self, owner: &Address, spender: &Address, amount: &U256) {
let allowance = self.allowances.get_instance(owner).get_or_default(spender);
if allowance < *amount {
contract_env::revert(Error::InsufficientAllowance)
self.env.revert(Error::InsufficientAllowance)
}
self.allowances
.get_instance(owner)
@@ -163,8 +156,8 @@ impl Erc20 {
}

pub mod events {
use odra::types::{casper_types::U256, Address};
use odra::Event;
use odra::{Address, U256};
use casper_event_standard::Event;

#[derive(Event, Eq, PartialEq, Debug)]
pub struct Transfer {
@@ -182,15 +175,19 @@ pub mod events {
}

pub mod errors {
use odra::execution_error;

execution_error! {
pub enum Error {
InsufficientBalance => 30_000,
InsufficientAllowance => 30_001,
NameNotSet => 30_002,
SymbolNotSet => 30_003,
DecimalsNotSet => 30_004,
use odra::OdraError;

pub enum Error {
InsufficientBalance = 30_000,
InsufficientAllowance = 30_001,
NameNotSet = 30_002,
SymbolNotSet = 30_003,
DecimalsNotSet = 30_004,
}

impl From<Error> for OdraError {
fn from(error: Error) -> Self {
OdraError::user(error as u16)
}
}
}
18 changes: 9 additions & 9 deletions modules/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub mod access;
pub mod erc1155;
pub mod erc1155_receiver;
pub mod erc1155_token;
// pub mod access;
// pub mod erc1155;
// pub mod erc1155_receiver;
// pub mod erc1155_token;
pub mod erc20;
pub mod erc721;
pub mod erc721_receiver;
pub mod erc721_token;
pub mod security;
pub mod wrapped_native;
// pub mod erc721;
// pub mod erc721_receiver;
// pub mod erc721_token;
// pub mod security;
// pub mod wrapped_native;
21 changes: 10 additions & 11 deletions modules/src/wrapped_native.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
use crate::erc20::Erc20;
use odra::{
contract_env,
types::{event::OdraEvent, Address},
UnwrapOrRevert
};
use odra_core::uints::{ToU256, ToU512};

#[odra::module(events = [Deposit, Withdrawal])]
pub struct WrappedNativeToken {
@@ -13,7 +7,6 @@ pub struct WrappedNativeToken {

#[odra::module]
impl WrappedNativeToken {
#[odra(init)]
pub fn init(&mut self) {
let metadata = contract_env::native_token_metadata();
let symbol = format!("W{}", metadata.symbol);
@@ -89,8 +82,8 @@ impl WrappedNativeToken {

pub mod events {
use odra::{
types::{casper_types::U256, Address},
Event
Event,
types::{Address, casper_types::U256}
};

#[derive(Event, Debug, Eq, PartialEq)]
@@ -112,11 +105,17 @@ mod tests {
assert_events,
prelude::format,
test_env,
types::{Address, OdraError, VmError, U256, U512}
types::{
Address, OdraError, U256, U512, VmError
}
};
use odra_core::uints::{ToU256, ToU512};

use crate::wrapped_native::{WrappedNativeTokenDeployer, WrappedNativeTokenRef};
use crate::{
wrapped_native::{
WrappedNativeTokenDeployer, WrappedNativeTokenRef
}
};

fn setup() -> (WrappedNativeTokenRef, Address, U512, Address, U512) {
let token: WrappedNativeTokenRef = WrappedNativeTokenDeployer::init();
1 change: 0 additions & 1 deletion odra/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![no_std]

pub use odra_core::call_result::*;
pub use odra_core::casper_event_standard::Event;
pub use odra_core::mapping::*;
pub use odra_core::module::*;
pub use odra_core::variable::*;

0 comments on commit 1a961f1

Please sign in to comment.