Skip to content

Commit

Permalink
Merge pull request #154 from multiversx/mintBurn-or-locking
Browse files Browse the repository at this point in the history
add mintBurn or locking functionality
  • Loading branch information
sasurobert authored Jan 22, 2024
2 parents 531c35b + 12ea6db commit bae95ea
Show file tree
Hide file tree
Showing 92 changed files with 2,857 additions and 793 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ permissions:
jobs:
contracts:
name: Contracts
uses: multiversx/mx-sc-actions/.github/workflows/[email protected].0
uses: multiversx/mx-sc-actions/.github/workflows/[email protected].5
with:
rust-toolchain: nightly-2023-04-24
vmtools-version: v1.4.60
rust-toolchain: nightly-2023-12-11
vmtools-version: v1.5.19
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
8 changes: 6 additions & 2 deletions bridge-proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ path = "../common/transaction"
path = "../common/eth-address"

[dependencies.multiversx-sc]
version = "0.45.2"
version = "0.46.1"

[dependencies.adder]
git = "https://github.com/multiversx/mx-contracts-rs"
rev = "64e8926"

[dev-dependencies]
num-bigint = "0.4.2"

[dev-dependencies.multiversx-sc-scenario]
version = "0.45.2"
version = "0.46.1"
2 changes: 1 addition & 1 deletion bridge-proxy/meta/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ authors = ["you"]
path = ".."

[dependencies.multiversx-sc-meta]
version = "0.45.2"
version = "0.46.1"
12 changes: 9 additions & 3 deletions bridge-proxy/src/bridge-proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ pub trait BridgeProxyContract: config::ConfigModule {
let tx_node = self
.eth_transaction_list()
.remove_node_by_id(tx_id)
.unwrap_or_else(|| sc_panic!("No more ETH transactions!"));
.unwrap_or_else(|| sc_panic!("Invalid ETH transaction!"));
let tx = tx_node.get_value_as_ref();

self.send()
.contract_call::<IgnoreValue>(tx.eth_tx.to.clone(), tx.eth_tx.data.clone())
.with_raw_arguments(tx.eth_tx.args.clone().into())
.with_esdt_transfer((tx.token_id.clone(), tx.nonce, tx.amount.clone()))
.with_gas_limit(tx.eth_tx.gas_limit)
.async_call()
Expand All @@ -63,9 +64,14 @@ pub trait BridgeProxyContract: config::ConfigModule {
for failed_tx_loop in self.eth_failed_transaction_list().into_iter() {
let failed_tx = failed_tx_loop.get_value_as_ref();

all_payments.push(EsdtTokenPayment::new(failed_tx.token_id.clone(), failed_tx.nonce, failed_tx.amount.clone()));
all_payments.push(EsdtTokenPayment::new(
failed_tx.token_id.clone(),
failed_tx.nonce,
failed_tx.amount.clone(),
));
}
self.send().direct_multi(&self.multi_transfer_address().get(), &all_payments);
self.send()
.direct_multi(&self.multi_transfer_address().get(), &all_payments);

result
}
Expand Down
9 changes: 6 additions & 3 deletions bridge-proxy/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
multiversx_sc::imports!();
multiversx_sc::derive_imports!();

use transaction::{EthTransactionPayment, EthTransaction};
use transaction::{EthTransaction, EthTransactionPayment};

#[multiversx_sc::module]
pub trait ConfigModule {
#[only_owner]
#[endpoint(setupMultiTransfer)]
fn set_multi_transfer_contract_address(&self, opt_multi_transfer_address: OptionalValue<ManagedAddress>) {
fn set_multi_transfer_contract_address(
&self,
opt_multi_transfer_address: OptionalValue<ManagedAddress>,
) {
match opt_multi_transfer_address {
OptionalValue::Some(sc_addr) => {
require!(
Expand All @@ -25,7 +28,7 @@ pub trait ConfigModule {
let eth_tx_list = self.eth_transaction_list();
match eth_tx_list.get_node_by_id(id) {
Some(tx) => tx.get_value_cloned().eth_tx,
None => sc_panic!("No transaction with this id!")
None => sc_panic!("No transaction with this id!"),
}
}

Expand Down
241 changes: 195 additions & 46 deletions bridge-proxy/tests/bridge_proxy_blackbox_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@

use std::collections::LinkedList;

use adder::{Adder, ProxyTrait as _};
use bridge_proxy::config::ProxyTrait as _;
use bridge_proxy::ProxyTrait;

use multiversx_sc::{
api::ManagedTypeApi,
codec::multi_types::{MultiValueVec, OptionalValue},
api::{HandleConstraints, ManagedTypeApi},
codec::{
multi_types::{MultiValueVec, OptionalValue},
TopEncodeMultiOutput,
},
storage::mappers::SingleValue,
types::{
Address, BigUint, CodeMetadata, ManagedAddress, ManagedBuffer, ManagedByteArray,
TokenIdentifier,
Address, BigUint, CodeMetadata, ManagedAddress, ManagedArgBuffer, ManagedBuffer,
ManagedByteArray, ManagedVec, TokenIdentifier,
},
};
use multiversx_sc_scenario::{
api::StaticApi,
rust_biguint,
scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext},
scenario_model::*,
ContractInfo, ScenarioWorld,
Expand All @@ -27,60 +32,27 @@ use transaction::{EthTransaction, EthTransactionPayment};
const BRIDGE_TOKEN_ID: &[u8] = b"BRIDGE-123456";
const GAS_LIMIT: u64 = 1_000_000;
const BRIDGE_PROXY_PATH_EXPR: &str = "file:output/bridge-proxy.wasm";
const ADDER_BOGUS_PATH_EXPR: &str = "file:bogus-path.wasm";

fn world() -> ScenarioWorld {
let mut blockchain = ScenarioWorld::new();

blockchain.register_contract(BRIDGE_PROXY_PATH_EXPR, bridge_proxy::ContractBuilder);
blockchain
}

#[test]
fn deploy_deposit_test() {
let mut test = BridgeProxyTestState::setup();
let bridge_token_id_expr = "str:BRIDGE-123456"; // when specifying the token transfer

test.bridge_proxy_deploy();
blockchain.register_contract(ADDER_BOGUS_PATH_EXPR, adder::ContractBuilder);

let eth_tx = EthTransaction {
from: test.eth_user,
to: ManagedAddress::from_address(&test.user.value),
token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID),
amount: BigUint::from(500u64),
tx_nonce: 1u64,
data: ManagedBuffer::from("data"),
gas_limit: GAS_LIMIT,
};

test.world.set_state_step(SetStateStep::new().put_account(
&test.owner,
Account::new().esdt_balance(bridge_token_id_expr, 1_000u64),
));

test.world.sc_call(
ScCallStep::new()
.from(&test.owner)
.to(&test.bridge_proxy)
.call(test.bridge_proxy.deposit(&eth_tx))
.esdt_transfer(bridge_token_id_expr, 0u64, 500u64),
);

test.world.sc_query(
ScQueryStep::new()
.to(&test.bridge_proxy)
.call(test.bridge_proxy.get_eth_transaction_by_id(1u32))
.expect_value(eth_tx),
);
blockchain
}

type BridgeProxyContract = ContractInfo<bridge_proxy::Proxy<StaticApi>>;
type AdderContract = ContractInfo<adder::Proxy<StaticApi>>;

struct BridgeProxyTestState<M: ManagedTypeApi> {
world: ScenarioWorld,
owner: AddressValue,
user: AddressValue,
eth_user: EthAddress<M>,
bridge_proxy: BridgeProxyContract,
bridge_proxy_contract: BridgeProxyContract,
adder_contract: AdderContract,
}

impl<M: ManagedTypeApi> BridgeProxyTestState<M> {
Expand All @@ -95,7 +67,8 @@ impl<M: ManagedTypeApi> BridgeProxyTestState<M> {
eth_user: EthAddress {
raw_addr: ManagedByteArray::default(),
},
bridge_proxy: BridgeProxyContract::new("sc:bridge_proxy"),
bridge_proxy_contract: BridgeProxyContract::new("sc:bridge_proxy"),
adder_contract: AdderContract::new("sc:adder"),
};

state
Expand All @@ -109,17 +82,193 @@ impl<M: ManagedTypeApi> BridgeProxyTestState<M> {
self.world.set_state_step(
SetStateStep::new()
.put_account(&self.owner, Account::new().nonce(1))
.new_address(&self.owner, 1, &self.bridge_proxy),
.new_address(&self.owner, 1, &self.bridge_proxy_contract),
);

let ic = &self.world.interpreter_context();
self.world.sc_deploy(
ScDeployStep::new()
.from(self.owner.clone())
.code(self.world.code_expression(BRIDGE_PROXY_PATH_EXPR))
.call(self.bridge_proxy.init(ManagedAddress::zero())),
.call(self.bridge_proxy_contract.init(ManagedAddress::zero())),
);

self
}

fn deploy_adder(&mut self) -> &mut Self {
self.world.set_state_step(SetStateStep::new().new_address(
&self.owner,
2,
&self.adder_contract,
));

self.world.sc_deploy(
ScDeployStep::new()
.from(self.owner.clone())
.code(self.world.code_expression(ADDER_BOGUS_PATH_EXPR))
.call(self.adder_contract.init(BigUint::zero())),
);

self
}
}

#[test]
fn deploy_deposit_test() {
let mut test = BridgeProxyTestState::setup();
let bridge_token_id_expr = "str:BRIDGE-123456"; // when specifying the token transfer

test.bridge_proxy_deploy();
test.deploy_adder();

let mut args = ManagedVec::new();
args.push(ManagedBuffer::from(&[5u8]));

let eth_tx = EthTransaction {
from: test.eth_user.clone(),
to: ManagedAddress::from_address(&test.adder_contract.to_address()),
token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID),
amount: BigUint::from(500u64),
tx_nonce: 1u64,
data: ManagedBuffer::from(b"add"),
gas_limit: GAS_LIMIT,
args,
};

test.world.set_state_step(SetStateStep::new().put_account(
&test.owner,
Account::new().esdt_balance(bridge_token_id_expr, 1_000u64),
));

test.world.sc_call(
ScCallStep::new()
.from(&test.owner)
.to(&test.bridge_proxy_contract)
.call(test.bridge_proxy_contract.deposit(&eth_tx))
.esdt_transfer(bridge_token_id_expr, 0u64, 500u64),
);

test.world.sc_query(
ScQueryStep::new()
.to(&test.bridge_proxy_contract)
.call(test.bridge_proxy_contract.get_eth_transaction_by_id(1u32))
.expect_value(eth_tx),
);

test.world.sc_call(
ScCallStep::new()
.from(&test.owner)
.to(&test.bridge_proxy_contract)
.call(test.bridge_proxy_contract.execute_with_async(1u32)),
);

test.world.sc_query(
ScQueryStep::new()
.to(&test.adder_contract)
.call(test.adder_contract.sum())
.expect_value(SingleValue::from(BigUint::from(5u32))),
);
}


#[test]
fn multiple_deposit_test() {
let mut test = BridgeProxyTestState::setup();
let bridge_token_id_expr = "str:BRIDGE-123456"; // when specifying the token transfer

test.bridge_proxy_deploy();
test.deploy_adder();

let mut args1 = ManagedVec::new();
args1.push(ManagedBuffer::from(&[5u8]));

let eth_tx1 = EthTransaction {
from: test.eth_user.clone(),
to: ManagedAddress::from_address(&test.adder_contract.to_address()),
token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID),
amount: BigUint::from(500u64),
tx_nonce: 1u64,
data: ManagedBuffer::from(b"add"),
gas_limit: GAS_LIMIT,
args: args1,
};

let mut args2 = ManagedVec::new();
args2.push(ManagedBuffer::from(&[15u8]));

let eth_tx2 = EthTransaction {
from: test.eth_user.clone(),
to: ManagedAddress::from_address(&test.adder_contract.to_address()),
token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID),
amount: BigUint::zero(),
tx_nonce: 1u64,
data: ManagedBuffer::from(b"add"),
gas_limit: GAS_LIMIT,
args: args2,
};

test.world.set_state_step(SetStateStep::new().put_account(
&test.owner,
Account::new().esdt_balance(bridge_token_id_expr, 1_000u64),
));

test.world.sc_call(
ScCallStep::new()
.from(&test.owner)
.to(&test.bridge_proxy_contract)
.call(test.bridge_proxy_contract.deposit(&eth_tx1))
.esdt_transfer(bridge_token_id_expr, 0u64, 500u64),
);

test.world.sc_call(
ScCallStep::new()
.from(&test.owner)
.to(&test.bridge_proxy_contract)
.call(test.bridge_proxy_contract.deposit(&eth_tx2))
.esdt_transfer(bridge_token_id_expr, 0u64, 0u64),
);

test.world.sc_query(
ScQueryStep::new()
.to(&test.bridge_proxy_contract)
.call(test.bridge_proxy_contract.get_eth_transaction_by_id(1u32))
.expect_value(eth_tx1),
);

test.world.sc_query(
ScQueryStep::new()
.to(&test.bridge_proxy_contract)
.call(test.bridge_proxy_contract.get_eth_transaction_by_id(2u32))
.expect_value(eth_tx2),
);

test.world.sc_call(
ScCallStep::new()
.from(&test.owner)
.to(&test.bridge_proxy_contract)
.call(test.bridge_proxy_contract.execute_with_async(1u32)),
);

test.world.sc_query(
ScQueryStep::new()
.to(&test.adder_contract)
.call(test.adder_contract.sum())
.expect_value(SingleValue::from(BigUint::from(5u32))),
);

test.world.sc_call(
ScCallStep::new()
.from(&test.owner)
.to(&test.bridge_proxy_contract)
.call(test.bridge_proxy_contract.execute_with_async(2u32)),
);

test.world.sc_query(
ScQueryStep::new()
.to(&test.adder_contract)
.call(test.adder_contract.sum())
.expect_value(SingleValue::from(BigUint::from(20u32))),
);

}
Loading

0 comments on commit bae95ea

Please sign in to comment.