Skip to content

Commit

Permalink
Merge pull request #1634 from multiversx/transfer-role-unified
Browse files Browse the repository at this point in the history
Upgrade transfer role contract
  • Loading branch information
andrei-marinica committed May 20, 2024
2 parents 5a41da5 + bef1623 commit d2a30ba
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,7 @@ impl PriceAggregatorTestState {
world.account(OWNER_ADDRESS).nonce(1);
world.current_block().block_timestamp(100);

world.set_state_step(SetStateStep::new()).new_address(
OWNER_ADDRESS,
1,
PRICE_AGGREGATOR_ADDRESS,
);
world.new_address(OWNER_ADDRESS, 1, PRICE_AGGREGATOR_ADDRESS);

let mut oracles = Vec::new();
for i in 1..=NR_ORACLES {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ impl CrowdfundingESDTTestState {
}

fn set_block_timestamp(&mut self, block_timestamp_expr: u64) {
self.world
.set_state_step(SetStateStep::new().block_timestamp(block_timestamp_expr));
self.world.current_block().block_timestamp(block_timestamp_expr);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[[proxy]]
path = "src/transfer_role_proxy.rs"
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![allow(clippy::type_complexity)]

multiversx_sc::imports!();
pub mod transfer_role_proxy;

#[multiversx_sc::contract]
pub trait TransferRoleFeatures:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Code generated by the multiversx-sc proxy generator. DO NOT EDIT.

////////////////////////////////////////////////////
////////////////// AUTO-GENERATED //////////////////
////////////////////////////////////////////////////

#![allow(dead_code)]
#![allow(clippy::all)]

use multiversx_sc::proxy_imports::*;

pub struct TransferRoleFeaturesProxy;

impl<Env, From, To, Gas> TxProxyTrait<Env, From, To, Gas> for TransferRoleFeaturesProxy
where
Env: TxEnv,
From: TxFrom<Env>,
To: TxTo<Env>,
Gas: TxGas<Env>,
{
type TxProxyMethods = TransferRoleFeaturesProxyMethods<Env, From, To, Gas>;

fn proxy_methods(self, tx: Tx<Env, From, To, (), Gas, (), ()>) -> Self::TxProxyMethods {
TransferRoleFeaturesProxyMethods { wrapped_tx: tx }
}
}

pub struct TransferRoleFeaturesProxyMethods<Env, From, To, Gas>
where
Env: TxEnv,
From: TxFrom<Env>,
To: TxTo<Env>,
Gas: TxGas<Env>,
{
wrapped_tx: Tx<Env, From, To, (), Gas, (), ()>,
}

#[rustfmt::skip]
impl<Env, From, Gas> TransferRoleFeaturesProxyMethods<Env, From, (), Gas>
where
Env: TxEnv,
Env::Api: VMApi,
From: TxFrom<Env>,
Gas: TxGas<Env>,
{
pub fn init<
Arg0: ProxyArg<MultiValueEncoded<Env::Api, ManagedAddress<Env::Api>>>,
>(
self,
whitelist: Arg0,
) -> TxTypedDeploy<Env, From, NotPayable, Gas, ()> {
self.wrapped_tx
.payment(NotPayable)
.raw_deploy()
.argument(&whitelist)
.original_result()
}
}

#[rustfmt::skip]
impl<Env, From, To, Gas> TransferRoleFeaturesProxyMethods<Env, From, To, Gas>
where
Env: TxEnv,
Env::Api: VMApi,
From: TxFrom<Env>,
To: TxTo<Env>,
Gas: TxGas<Env>,
{
pub fn forward_payments<
Arg0: ProxyArg<ManagedAddress<Env::Api>>,
Arg1: ProxyArg<ManagedBuffer<Env::Api>>,
Arg2: ProxyArg<MultiValueEncoded<Env::Api, ManagedBuffer<Env::Api>>>,
>(
self,
dest: Arg0,
endpoint_name: Arg1,
args: Arg2,
) -> TxTypedCall<Env, From, To, (), Gas, ()> {
self.wrapped_tx
.raw_call("forwardPayments")
.argument(&dest)
.argument(&endpoint_name)
.argument(&args)
.original_result()
}
}
Original file line number Diff line number Diff line change
@@ -1,116 +1,91 @@
#![allow(deprecated)] // TODO: unified syntax

use multiversx_sc_scenario::imports::*;
use transfer_role_features::ProxyTrait as _;
use transfer_role_features::transfer_role_proxy;

const ACCEPT_FUNDS_FUNC_NAME: &[u8] = b"accept_funds";
const OWNER_ADDRESS_EXPR: &str = "address:owner";
const REJECT_FUNDS_FUNC_NAME: &[u8] = b"reject_funds";
const TRANSFER_ROLE_FEATURES_ADDRESS_EXPR: &str = "sc:transfer-role-features";
const TRANSFER_ROLE_FEATURES_PATH_EXPR: &str = "mxsc:output/transfer-role-features.mxsc.json";
const TRANSFER_TOKEN_ID: &[u8] = b"TRANSFER-123456";
const TRANSFER_TOKEN_ID_EXPR: &str = "str:TRANSFER-123456";
const USER_ADDRESS_EXPR: &str = "address:user";
const VAULT_ADDRESS_EXPR: &str = "sc:vault";
const VAULT_PATH_EXPR: &str = "mxsc:../vault/output/vault.mxsc.json";

type TransferRoleFeaturesContract = ContractInfo<transfer_role_features::Proxy<StaticApi>>;
const OWNER_ADDRESS: TestAddress = TestAddress::new("owner");
const TRANSFER_ROLE_FEATURES_ADDRESS: TestSCAddress = TestSCAddress::new("transfer-role-features");
const TRANSFER_ROLE_FEATURES_PATH: MxscPath =
MxscPath::new("output/transfer-role-features.mxsc.json");
const TRANSFER_TOKEN: TestTokenIdentifier = TestTokenIdentifier::new("TRANSFER-123456");
const USER_ADDRESS: TestAddress = TestAddress::new("user");
const VAULT_ADDRESS: TestSCAddress = TestSCAddress::new("vault");
const VAULT_PATH: MxscPath = MxscPath::new("../vault/output/vault.mxsc.json");

fn world() -> ScenarioWorld {
let mut blockchain = ScenarioWorld::new();
blockchain.set_current_dir_from_workspace(
"contracts/feature-tests/composability/transfer-role-features",
);

blockchain.register_contract(
TRANSFER_ROLE_FEATURES_PATH_EXPR,
TRANSFER_ROLE_FEATURES_PATH,
transfer_role_features::ContractBuilder,
);
blockchain.register_contract(VAULT_PATH_EXPR, vault::ContractBuilder);
blockchain.register_contract(VAULT_PATH, vault::ContractBuilder);
blockchain
}

struct TransferRoleTestState {
world: ScenarioWorld,
owner_address: Address,
vault_address: Address,
transfer_role_features_contract: TransferRoleFeaturesContract,
}

impl TransferRoleTestState {
fn new() -> Self {
let mut world = world();
let vault_code = world.code_expression(VAULT_PATH_EXPR);

world.set_state_step(
SetStateStep::new()
.put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1))
.new_address(OWNER_ADDRESS_EXPR, 1, TRANSFER_ROLE_FEATURES_ADDRESS_EXPR)
.put_account(VAULT_ADDRESS_EXPR, Account::new().nonce(1).code(vault_code))
.put_account(
USER_ADDRESS_EXPR,
Account::new()
.nonce(1)
.esdt_balance(TRANSFER_TOKEN_ID_EXPR, 1_000u64),
),

world.account(OWNER_ADDRESS).nonce(1).new_address(
OWNER_ADDRESS,
1,
TRANSFER_ROLE_FEATURES_ADDRESS,
);

let owner_address = AddressValue::from(OWNER_ADDRESS_EXPR).to_address();
let vault_address = AddressValue::from(VAULT_ADDRESS_EXPR).to_address();
let transfer_role_features_contract =
TransferRoleFeaturesContract::new(TRANSFER_ROLE_FEATURES_ADDRESS_EXPR);

Self {
world,
owner_address,
vault_address,
transfer_role_features_contract,
}
world.account(VAULT_ADDRESS).nonce(1).code(VAULT_PATH);
world
.account(USER_ADDRESS)
.nonce(1)
.esdt_balance(TRANSFER_TOKEN, 1000);

Self { world }
}

fn deploy(&mut self) -> &mut Self {
let transfer_role_features_code =
self.world.code_expression(TRANSFER_ROLE_FEATURES_PATH_EXPR);

let whitelist = MultiValueVec::from(vec![
AddressValue::from(OWNER_ADDRESS_EXPR).to_address(),
AddressValue::from(VAULT_ADDRESS_EXPR).to_address(),
AddressValue::from(OWNER_ADDRESS).to_address(),
AddressValue::from(VAULT_ADDRESS).to_address(),
]);

self.world.sc_deploy(
ScDeployStep::new()
.from(OWNER_ADDRESS_EXPR)
.code(transfer_role_features_code)
.call(self.transfer_role_features_contract.init(whitelist)),
);
self.world
.tx()
.from(OWNER_ADDRESS)
.typed(transfer_role_proxy::TransferRoleFeaturesProxy)
.init(whitelist)
.code(TRANSFER_ROLE_FEATURES_PATH)
.new_address(TRANSFER_ROLE_FEATURES_ADDRESS)
.run();

self
}

fn forward_payments(&mut self, dest: Address, endpoint_name: &[u8]) {
self.world.sc_call(
ScCallStep::new()
.from(USER_ADDRESS_EXPR)
.esdt_transfer(TRANSFER_TOKEN_ID, 0, 100u64)
.call(self.transfer_role_features_contract.forward_payments(
dest,
endpoint_name,
MultiValueVec::<Vec<u8>>::new(),
)),
);
self.world
.tx()
.from(USER_ADDRESS)
.to(TRANSFER_ROLE_FEATURES_ADDRESS)
.typed(transfer_role_proxy::TransferRoleFeaturesProxy)
.forward_payments(dest, endpoint_name, MultiValueVec::<Vec<u8>>::new())
.egld_or_single_esdt(
&EgldOrEsdtTokenIdentifier::esdt(TRANSFER_TOKEN),
0u64,
&multiversx_sc::proxy_imports::BigUint::from(100u64),
)
.run();
}

fn check_user_and_vault_balance(&mut self) {
self.world
.check_state_step(CheckStateStep::new().put_account(
USER_ADDRESS_EXPR,
CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "800"),
));
.check_account(USER_ADDRESS)
.esdt_balance(TRANSFER_TOKEN, 800);
self.world
.check_state_step(CheckStateStep::new().put_account(
VAULT_ADDRESS_EXPR,
CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "100"),
));
.check_account(VAULT_ADDRESS)
.esdt_balance(TRANSFER_TOKEN, 100);
}
}

Expand All @@ -120,40 +95,38 @@ fn test_transfer_role() {
state.deploy();

// transfer to user - ok
state.forward_payments(state.owner_address.clone(), b"");
state.forward_payments(Address::from(OWNER_ADDRESS.eval_to_array()), b"");
state
.world
.check_state_step(CheckStateStep::new().put_account(
USER_ADDRESS_EXPR,
CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "900"),
));
.check_account(USER_ADDRESS)
.esdt_balance(TRANSFER_TOKEN, 900);

state
.world
.check_state_step(CheckStateStep::new().put_account(
OWNER_ADDRESS_EXPR,
CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "100"),
));
.check_account(OWNER_ADDRESS)
.esdt_balance(TRANSFER_TOKEN, 100);

// transfer to user - err, not whitelisted
state.world.sc_call(
ScCallStep::new()
.from(USER_ADDRESS_EXPR)
.esdt_transfer(TRANSFER_TOKEN_ID, 0, 100u64)
.call(state.transfer_role_features_contract.forward_payments(
Address::zero(),
"",
MultiValueVec::<Vec<u8>>::new(),
))
.expect(TxExpect::user_error(
"str:Destination address not whitelisted",
)),
);
state
.world
.tx()
.from(USER_ADDRESS)
.to(TRANSFER_ROLE_FEATURES_ADDRESS)
.typed(transfer_role_proxy::TransferRoleFeaturesProxy)
.forward_payments(Address::zero(), "", MultiValueVec::<Vec<u8>>::new())
.egld_or_single_esdt(
&EgldOrEsdtTokenIdentifier::esdt(TRANSFER_TOKEN),
0u64,
&multiversx_sc::proxy_imports::BigUint::from(100u64),
)
.with_result(ExpectMessage("Destination address not whitelisted"))
.run();

// transfer to sc - ok
state.forward_payments(state.vault_address.clone(), ACCEPT_FUNDS_FUNC_NAME);
state.forward_payments(VAULT_ADDRESS.to_address(), ACCEPT_FUNDS_FUNC_NAME);
state.check_user_and_vault_balance();

// transfer to sc - reject
state.forward_payments(state.vault_address.clone(), REJECT_FUNDS_FUNC_NAME);
state.forward_payments(VAULT_ADDRESS.to_address(), REJECT_FUNDS_FUNC_NAME);
state.check_user_and_vault_balance();
}

0 comments on commit d2a30ba

Please sign in to comment.