@layerzerolabs/protocol-stellar-v2 0.2.29 → 0.2.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +371 -321
- package/.turbo/turbo-lint.log +211 -202
- package/.turbo/turbo-test.log +1766 -1673
- package/Cargo.lock +11 -1
- package/contracts/common-macros/src/lib.rs +0 -2
- package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +1 -0
- package/contracts/endpoint-v2/src/messaging_channel.rs +32 -3
- package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/clear_payload.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound.rs +6 -6
- package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +1 -1
- package/contracts/endpoint-v2/src/tests/messaging_channel/outbound.rs +16 -10
- package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +10 -10
- package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +3 -3
- package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +4 -3
- package/contracts/macro-integration-tests/tests/runtime/upgradeable/migrate_guard_and_state.rs +1 -57
- package/contracts/macro-integration-tests/tests/ui/lz_contract/fail/upgradeable_missing_internal.stderr +0 -30
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -3
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +6 -4
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -3
- package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -3
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_auth_trait.stderr +0 -30
- package/contracts/macro-integration-tests/tests/ui/upgradeable/fail/missing_upgradeable_internal.stderr +0 -30
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/basic.rs +0 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/multisig_contract.rs +0 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_migration.rs +0 -2
- package/contracts/macro-integration-tests/tests/ui/upgradeable/pass/no_user_contractimpl.rs +1 -3
- package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +3 -6
- package/contracts/message-libs/message-lib-common/src/tests/worker_options/extract_type_3_options.rs +10 -0
- package/contracts/message-libs/message-lib-common/src/worker_options.rs +6 -2
- package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +3 -3
- package/contracts/message-libs/treasury/src/lib.rs +2 -1
- package/contracts/message-libs/treasury/src/tests/setup.rs +1 -1
- package/contracts/message-libs/treasury/src/treasury.rs +5 -2
- package/contracts/message-libs/uln-302/src/errors.rs +2 -0
- package/contracts/message-libs/uln-302/src/events.rs +3 -3
- package/contracts/message-libs/uln-302/src/interfaces/receive_uln.rs +8 -0
- package/contracts/message-libs/uln-302/src/lib.rs +2 -1
- package/contracts/message-libs/uln-302/src/receive_uln.rs +16 -13
- package/contracts/message-libs/uln-302/src/send_uln.rs +51 -24
- package/contracts/message-libs/uln-302/src/storage.rs +2 -2
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +45 -1
- package/contracts/message-libs/uln-302/src/tests/receive_uln302/verifiable.rs +63 -0
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +47 -2
- package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +50 -1
- package/contracts/message-libs/uln-302/src/uln302.rs +0 -8
- package/contracts/oapps/counter/Cargo.toml +4 -4
- package/contracts/oapps/counter/integration_tests/setup_uln.rs +22 -2
- package/contracts/oapps/counter/src/counter.rs +8 -8
- package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +33 -10
- package/contracts/oapps/oapp/src/lib.rs +6 -2
- package/contracts/oapps/oapp/src/oapp_core.rs +49 -24
- package/contracts/oapps/oapp/src/oapp_options_type3.rs +21 -14
- package/contracts/oapps/oapp/src/oapp_receiver.rs +17 -16
- package/contracts/oapps/oapp/src/oapp_sender.rs +66 -15
- package/contracts/oapps/oapp/src/tests/oapp_core.rs +5 -5
- package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +18 -18
- package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +4 -4
- package/contracts/oapps/oapp/src/tests/oapp_sender.rs +3 -3
- package/contracts/oapps/oapp-macros/Cargo.toml +0 -1
- package/contracts/oapps/oapp-macros/src/generators.rs +87 -46
- package/contracts/oapps/oapp-macros/src/lib.rs +3 -61
- package/contracts/oapps/oapp-macros/src/tests/oapp.rs +9 -23
- package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +15 -11
- package/contracts/oapps/oft/Cargo.toml +1 -1
- package/contracts/oapps/oft/integration-tests/extensions/test_oft_fee.rs +3 -3
- package/contracts/oapps/oft/integration-tests/extensions/test_pausable.rs +4 -4
- package/contracts/oapps/oft/integration-tests/extensions/test_rate_limiter.rs +144 -8
- package/contracts/oapps/oft/integration-tests/setup.rs +4 -2
- package/contracts/oapps/oft/integration-tests/utils.rs +25 -11
- package/contracts/oapps/oft/src/extensions/oft_fee.rs +65 -63
- package/contracts/oapps/oft/src/extensions/pausable.rs +2 -3
- package/contracts/oapps/oft/src/extensions/rate_limiter.rs +22 -5
- package/contracts/oapps/oft/src/interfaces/mint_burnable.rs +18 -0
- package/contracts/oapps/oft/src/interfaces/mod.rs +3 -0
- package/contracts/oapps/oft/src/lib.rs +4 -2
- package/contracts/oapps/oft/src/oft.rs +35 -36
- package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +13 -9
- package/contracts/oapps/oft/src/oft_types/mint_burn.rs +14 -9
- package/contracts/oapps/oft/src/oft_types/mod.rs +14 -12
- package/contracts/oapps/oft/src/tests/extensions/oft_fee.rs +28 -20
- package/contracts/oapps/oft/src/tests/extensions/rate_limiter.rs +136 -2
- package/contracts/oapps/oft/src/tests/oft_types/lock_unlock.rs +12 -8
- package/contracts/oapps/oft-core/integration-tests/setup.rs +8 -9
- package/contracts/oapps/oft-core/integration-tests/test_with_sml.rs +7 -6
- package/contracts/oapps/oft-core/integration-tests/utils.rs +5 -4
- package/contracts/oapps/oft-core/src/codec/oft_compose_msg_codec.rs +2 -2
- package/contracts/oapps/oft-core/src/codec/oft_msg_codec.rs +33 -37
- package/contracts/oapps/oft-core/src/errors.rs +2 -1
- package/contracts/oapps/oft-core/src/events.rs +6 -0
- package/contracts/oapps/oft-core/src/lib.rs +8 -4
- package/contracts/oapps/oft-core/src/oft_core.rs +205 -148
- package/contracts/oapps/oft-core/src/storage.rs +4 -2
- package/contracts/oapps/oft-core/src/tests/test_decimals.rs +2 -2
- package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +6 -6
- package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +7 -6
- package/contracts/oapps/oft-core/src/tests/test_oft_msg_codec.rs +11 -82
- package/contracts/oapps/oft-core/src/tests/test_quote_oft.rs +13 -13
- package/contracts/oapps/oft-core/src/tests/test_quote_send.rs +1 -1
- package/contracts/oapps/oft-core/src/tests/test_resolve_address.rs +2 -2
- package/contracts/oapps/oft-core/src/tests/test_send.rs +22 -22
- package/contracts/oapps/oft-core/src/tests/test_utils.rs +20 -22
- package/contracts/oapps/oft-core/src/utils.rs +12 -8
- package/contracts/sac-manager/Cargo.toml +25 -0
- package/contracts/sac-manager/src/errors.rs +18 -0
- package/contracts/sac-manager/src/extensions/mod.rs +6 -0
- package/contracts/sac-manager/src/extensions/redistribution.rs +109 -0
- package/contracts/sac-manager/src/extensions/supply_control/mod.rs +488 -0
- package/contracts/sac-manager/src/extensions/supply_control/rate_limit.rs +126 -0
- package/contracts/sac-manager/src/interfaces/mod.rs +3 -0
- package/contracts/sac-manager/src/interfaces/sac_manager.rs +52 -0
- package/contracts/sac-manager/src/lib.rs +23 -0
- package/contracts/sac-manager/src/sac_manager.rs +193 -0
- package/contracts/sac-manager/src/storage.rs +20 -0
- package/contracts/sac-manager/src/tests/mod.rs +14 -0
- package/contracts/sac-manager/src/tests/redistribution/mod.rs +1 -0
- package/contracts/sac-manager/src/tests/redistribution/redistribute_funds.rs +82 -0
- package/contracts/sac-manager/src/tests/sac_manager/admin_mint.rs +206 -0
- package/contracts/sac-manager/src/tests/sac_manager/burn.rs +215 -0
- package/contracts/sac-manager/src/tests/sac_manager/clawback.rs +209 -0
- package/contracts/sac-manager/src/tests/sac_manager/mint.rs +252 -0
- package/contracts/sac-manager/src/tests/sac_manager/mod.rs +9 -0
- package/contracts/sac-manager/src/tests/sac_manager/set_admin.rs +36 -0
- package/contracts/sac-manager/src/tests/sac_manager/set_authorized.rs +43 -0
- package/contracts/sac-manager/src/tests/sac_manager/set_oft_address.rs +47 -0
- package/contracts/sac-manager/src/tests/sac_manager/test_helper.rs +75 -0
- package/contracts/sac-manager/src/tests/sac_manager/view_functions.rs +60 -0
- package/contracts/sac-manager/src/tests/supply_control/enumerable_set.rs +256 -0
- package/contracts/sac-manager/src/tests/supply_control/mod.rs +8 -0
- package/contracts/sac-manager/src/tests/supply_control/refill.rs +90 -0
- package/contracts/sac-manager/src/tests/supply_control/set_mint_whitelist.rs +245 -0
- package/contracts/sac-manager/src/tests/supply_control/set_supply_controller.rs +267 -0
- package/contracts/sac-manager/src/tests/supply_control/set_supply_controller_manager.rs +122 -0
- package/contracts/sac-manager/src/tests/supply_control/test_helper.rs +38 -0
- package/contracts/sac-manager/src/tests/supply_control/update_allow_any_mint_burn.rs +114 -0
- package/contracts/sac-manager/src/tests/supply_control/update_limit_config.rs +257 -0
- package/contracts/sac-manager/src/tests/test_helper.rs +190 -0
- package/contracts/upgrader/src/lib.rs +2 -1
- package/contracts/utils/src/errors.rs +0 -1
- package/contracts/utils/src/tests/upgradeable.rs +0 -66
- package/contracts/utils/src/upgradeable.rs +0 -18
- package/contracts/workers/dvn/src/dvn.rs +2 -2
- package/contracts/workers/dvn/src/interfaces/dvn.rs +2 -2
- package/contracts/workers/dvn/src/lib.rs +2 -1
- package/contracts/workers/dvn-fee-lib/src/lib.rs +3 -1
- package/contracts/workers/executor/src/auth.rs +42 -26
- package/contracts/workers/executor/src/executor.rs +28 -3
- package/contracts/workers/executor/src/lib.rs +4 -2
- package/contracts/workers/executor/src/storage.rs +21 -1
- package/contracts/workers/executor/src/tests/auth.rs +64 -20
- package/contracts/workers/executor/src/tests/executor.rs +1 -1
- package/contracts/workers/executor/src/tests/setup.rs +18 -0
- package/contracts/workers/executor-fee-lib/src/lib.rs +4 -1
- package/contracts/workers/executor-helper/src/executor_helper.rs +24 -10
- package/contracts/workers/executor-helper/src/tests/setup.rs +147 -34
- package/contracts/workers/price-feed/src/lib.rs +3 -1
- package/contracts/workers/worker/src/lib.rs +2 -1
- package/contracts/workers/worker/src/worker.rs +31 -17
- package/docs/oapp-guide.md +17 -8
- package/docs/oft-guide.md +3 -3
- package/package.json +3 -3
- package/sdk/.turbo/turbo-test.log +512 -351
- package/sdk/dist/generated/bml.d.ts +3 -9
- package/sdk/dist/generated/bml.js +6 -7
- package/sdk/dist/generated/counter.d.ts +22 -28
- package/sdk/dist/generated/counter.js +11 -12
- package/sdk/dist/generated/dvn.d.ts +36 -54
- package/sdk/dist/generated/dvn.js +10 -15
- package/sdk/dist/generated/dvn_fee_lib.d.ts +3 -21
- package/sdk/dist/generated/dvn_fee_lib.js +6 -11
- package/sdk/dist/generated/endpoint.d.ts +3 -9
- package/sdk/dist/generated/endpoint.js +6 -7
- package/sdk/dist/generated/executor.d.ts +80 -54
- package/sdk/dist/generated/executor.js +16 -16
- package/sdk/dist/generated/executor_fee_lib.d.ts +3 -21
- package/sdk/dist/generated/executor_fee_lib.js +6 -11
- package/sdk/dist/generated/executor_helper.d.ts +36 -42
- package/sdk/dist/generated/executor_helper.js +9 -10
- package/sdk/dist/generated/layerzero_view.d.ts +20 -32
- package/sdk/dist/generated/layerzero_view.js +25 -26
- package/sdk/dist/generated/oft.d.ts +147 -79
- package/sdk/dist/generated/oft.js +47 -54
- package/sdk/dist/generated/price_feed.d.ts +20 -38
- package/sdk/dist/generated/price_feed.js +15 -20
- package/sdk/dist/generated/sac_manager.d.ts +1309 -0
- package/sdk/dist/generated/sac_manager.js +484 -0
- package/sdk/dist/generated/sml.d.ts +3 -9
- package/sdk/dist/generated/sml.js +6 -7
- package/sdk/dist/generated/treasury.d.ts +3 -9
- package/sdk/dist/generated/treasury.js +8 -9
- package/sdk/dist/generated/uln302.d.ts +20 -20
- package/sdk/dist/generated/uln302.js +25 -22
- package/sdk/dist/generated/upgrader.d.ts +3 -9
- package/sdk/dist/generated/upgrader.js +6 -7
- package/sdk/dist/index.d.ts +1 -0
- package/sdk/dist/index.js +1 -0
- package/sdk/package.json +1 -1
- package/sdk/src/index.ts +1 -0
- package/sdk/test/oft-sml.test.ts +7 -5
- package/sdk/test/sac-manager-redistribution.test.ts +578 -0
- package/sdk/test/suites/globalSetup.ts +11 -6
- package/sdk/test/test_data/test_upgradeable_dvn.wasm +0 -0
- package/sdk/test/upgrader.test.ts +75 -202
- package/sdk/test/utils.ts +40 -0
- package/tools/ts-bindings-gen/src/main.rs +1 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Address,
|
|
3
|
+
Asset,
|
|
4
|
+
AuthClawbackEnabledFlag,
|
|
5
|
+
type AuthFlag,
|
|
6
|
+
AuthRevocableFlag,
|
|
7
|
+
BASE_FEE,
|
|
8
|
+
Keypair,
|
|
9
|
+
Operation,
|
|
10
|
+
rpc,
|
|
11
|
+
TransactionBuilder,
|
|
12
|
+
} from '@stellar/stellar-sdk';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import { beforeAll, describe, expect, it } from 'vitest';
|
|
15
|
+
|
|
16
|
+
import { getFullyQualifiedRepoRootPath } from '@layerzerolabs/common-node-utils';
|
|
17
|
+
|
|
18
|
+
import { Client as SacManagerClient } from '../src/generated/sac_manager';
|
|
19
|
+
import { DEFAULT_DEPLOYER, NETWORK_PASSPHRASE, RPC_URL } from './suites/constants';
|
|
20
|
+
import { deployAssetSac, deployContract } from './suites/deploy';
|
|
21
|
+
import { fundAccount } from './suites/localnet';
|
|
22
|
+
import { getTokenAuthorized, getTokenBalance } from './utils';
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Test Accounts
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
const TOKEN_ISSUER = Keypair.random();
|
|
29
|
+
const REDISTRIBUTION_ADMIN = Keypair.random();
|
|
30
|
+
const USER_A = Keypair.random();
|
|
31
|
+
const USER_B = Keypair.random();
|
|
32
|
+
const USER_C = Keypair.random();
|
|
33
|
+
|
|
34
|
+
// Token configuration
|
|
35
|
+
const TOKEN_CODE = 'RTKN';
|
|
36
|
+
let TOKEN_ASSET: Asset;
|
|
37
|
+
|
|
38
|
+
// Contract addresses
|
|
39
|
+
let sacTokenAddress = '';
|
|
40
|
+
let sacManagerAddress = '';
|
|
41
|
+
|
|
42
|
+
// Clients
|
|
43
|
+
let sacManagerClient: SacManagerClient;
|
|
44
|
+
|
|
45
|
+
// Initial token amounts
|
|
46
|
+
const INITIAL_TOKEN_AMOUNT = '1000'; // 1000 tokens
|
|
47
|
+
const TRANSFER_AMOUNT = 100_0000000n; // 100 tokens (7 decimals)
|
|
48
|
+
const REDISTRIBUTE_AMOUNT = 50_0000000n; // 50 tokens (7 decimals)
|
|
49
|
+
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Helper Functions
|
|
52
|
+
// ============================================================================
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Creates a SacManagerClient with a specific signer
|
|
56
|
+
*/
|
|
57
|
+
function createClientWithSigner(contractId: string, signer: Keypair): SacManagerClient {
|
|
58
|
+
return new SacManagerClient({
|
|
59
|
+
contractId,
|
|
60
|
+
publicKey: signer.publicKey(),
|
|
61
|
+
signTransaction: async (tx: string) => {
|
|
62
|
+
const transaction = TransactionBuilder.fromXDR(tx, NETWORK_PASSPHRASE);
|
|
63
|
+
transaction.sign(signer);
|
|
64
|
+
return {
|
|
65
|
+
signedTxXdr: transaction.toXDR(),
|
|
66
|
+
signerAddress: signer.publicKey(),
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
rpcUrl: RPC_URL,
|
|
70
|
+
networkPassphrase: NETWORK_PASSPHRASE,
|
|
71
|
+
allowHttp: true,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Note: The old executeRedistributeFundsWithAuth function has been removed
|
|
76
|
+
// because we now use the SacManagerClient directly which handles authorization properly
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Invokes a SAC contract function using raw transaction building
|
|
80
|
+
*/
|
|
81
|
+
async function invokeSacFunction(
|
|
82
|
+
sacAddress: string,
|
|
83
|
+
functionName: string,
|
|
84
|
+
args: any[],
|
|
85
|
+
signer: Keypair,
|
|
86
|
+
): Promise<void> {
|
|
87
|
+
const server = new rpc.Server(RPC_URL, { allowHttp: true });
|
|
88
|
+
const account = await server.getAccount(signer.publicKey());
|
|
89
|
+
|
|
90
|
+
const tx = new TransactionBuilder(account, {
|
|
91
|
+
fee: BASE_FEE,
|
|
92
|
+
networkPassphrase: NETWORK_PASSPHRASE,
|
|
93
|
+
})
|
|
94
|
+
.addOperation(
|
|
95
|
+
Operation.invokeContractFunction({
|
|
96
|
+
contract: sacAddress,
|
|
97
|
+
function: functionName,
|
|
98
|
+
args,
|
|
99
|
+
}),
|
|
100
|
+
)
|
|
101
|
+
.setTimeout(30)
|
|
102
|
+
.build();
|
|
103
|
+
|
|
104
|
+
const simulated = await server.simulateTransaction(tx);
|
|
105
|
+
if (rpc.Api.isSimulationError(simulated)) {
|
|
106
|
+
throw new Error(`Simulation failed: ${JSON.stringify(simulated)}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const preparedTx = rpc.assembleTransaction(tx, simulated).build();
|
|
110
|
+
preparedTx.sign(signer);
|
|
111
|
+
|
|
112
|
+
const sendResult = await server.sendTransaction(preparedTx);
|
|
113
|
+
if (sendResult.status !== 'PENDING') {
|
|
114
|
+
throw new Error(`Transaction failed to send: ${JSON.stringify(sendResult)}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const txResult = await server.pollTransaction(sendResult.hash);
|
|
118
|
+
if (txResult.status !== 'SUCCESS') {
|
|
119
|
+
throw new Error(`Transaction not successful: ${JSON.stringify(txResult)}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ============================================================================
|
|
124
|
+
// Test Suite
|
|
125
|
+
// ============================================================================
|
|
126
|
+
|
|
127
|
+
describe('SAC Manager Redistribution E2E Tests', async () => {
|
|
128
|
+
const repoRoot = await getFullyQualifiedRepoRootPath();
|
|
129
|
+
const wasmDir = path.join(
|
|
130
|
+
repoRoot,
|
|
131
|
+
'contracts',
|
|
132
|
+
'protocol',
|
|
133
|
+
'stellar',
|
|
134
|
+
'target',
|
|
135
|
+
'wasm32v1-none',
|
|
136
|
+
'release',
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const SAC_MANAGER_WASM_PATH = path.join(wasmDir, 'sac_manager.wasm');
|
|
140
|
+
|
|
141
|
+
beforeAll(async () => {
|
|
142
|
+
console.log('\n====================================');
|
|
143
|
+
console.log('SAC Manager Redistribution E2E Tests');
|
|
144
|
+
console.log('====================================\n');
|
|
145
|
+
|
|
146
|
+
// Fund test accounts (including DEFAULT_DEPLOYER which is normally funded by globalSetup)
|
|
147
|
+
console.log('Funding test accounts...');
|
|
148
|
+
await fundAccount(DEFAULT_DEPLOYER.publicKey());
|
|
149
|
+
await fundAccount(TOKEN_ISSUER.publicKey());
|
|
150
|
+
await fundAccount(REDISTRIBUTION_ADMIN.publicKey());
|
|
151
|
+
await fundAccount(USER_A.publicKey());
|
|
152
|
+
await fundAccount(USER_B.publicKey());
|
|
153
|
+
await fundAccount(USER_C.publicKey());
|
|
154
|
+
console.log('Test accounts funded');
|
|
155
|
+
|
|
156
|
+
// Create the token asset
|
|
157
|
+
TOKEN_ASSET = new Asset(TOKEN_CODE, TOKEN_ISSUER.publicKey());
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// ========================================================================
|
|
161
|
+
// Setup SAC Manager with SAC (redistribution enabled at construction)
|
|
162
|
+
// ========================================================================
|
|
163
|
+
|
|
164
|
+
describe('Setup SAC Manager with SAC', () => {
|
|
165
|
+
it('Set AUTH_REVOCABLE and AUTH_CLAWBACK_ENABLED flags on issuer account', async () => {
|
|
166
|
+
const server = new rpc.Server(RPC_URL, { allowHttp: true });
|
|
167
|
+
const issuerAccount = await server.getAccount(TOKEN_ISSUER.publicKey());
|
|
168
|
+
|
|
169
|
+
// Set AUTH_REVOCABLE and AUTH_CLAWBACK_ENABLED flags on issuer
|
|
170
|
+
// AUTH_REVOCABLE allows revoking authorization (blacklisting)
|
|
171
|
+
// AUTH_CLAWBACK_ENABLED allows clawback operations (required for redistribute_funds)
|
|
172
|
+
const authFlags = (AuthRevocableFlag | AuthClawbackEnabledFlag) as AuthFlag;
|
|
173
|
+
const setOptionsTx = new TransactionBuilder(issuerAccount, {
|
|
174
|
+
fee: BASE_FEE,
|
|
175
|
+
networkPassphrase: NETWORK_PASSPHRASE,
|
|
176
|
+
})
|
|
177
|
+
.addOperation(
|
|
178
|
+
Operation.setOptions({
|
|
179
|
+
setFlags: authFlags,
|
|
180
|
+
}),
|
|
181
|
+
)
|
|
182
|
+
.setTimeout(30)
|
|
183
|
+
.build();
|
|
184
|
+
|
|
185
|
+
setOptionsTx.sign(TOKEN_ISSUER);
|
|
186
|
+
|
|
187
|
+
const sendResult = await server.sendTransaction(setOptionsTx);
|
|
188
|
+
if (sendResult.status !== 'PENDING') {
|
|
189
|
+
throw new Error(`Failed to set auth flags: ${JSON.stringify(sendResult)}`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const txResult = await server.pollTransaction(sendResult.hash);
|
|
193
|
+
if (txResult.status !== 'SUCCESS') {
|
|
194
|
+
throw new Error(`Failed to set auth flags: ${JSON.stringify(txResult)}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
console.log('AUTH_REVOCABLE and AUTH_CLAWBACK_ENABLED flags set on issuer');
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('Deploy SAC with trustlines and issue tokens', async () => {
|
|
201
|
+
const server = new rpc.Server(RPC_URL, { allowHttp: true });
|
|
202
|
+
|
|
203
|
+
// Create trustlines for all test accounts and issue tokens
|
|
204
|
+
const issuerAccount = await server.getAccount(TOKEN_ISSUER.publicKey());
|
|
205
|
+
const issueTx = new TransactionBuilder(issuerAccount, {
|
|
206
|
+
fee: BASE_FEE,
|
|
207
|
+
networkPassphrase: NETWORK_PASSPHRASE,
|
|
208
|
+
})
|
|
209
|
+
// Trustline for DEFAULT_DEPLOYER (will be the SAC manager admin)
|
|
210
|
+
.addOperation(
|
|
211
|
+
Operation.changeTrust({
|
|
212
|
+
asset: TOKEN_ASSET,
|
|
213
|
+
source: DEFAULT_DEPLOYER.publicKey(),
|
|
214
|
+
}),
|
|
215
|
+
)
|
|
216
|
+
// Trustline for REDISTRIBUTION_ADMIN
|
|
217
|
+
.addOperation(
|
|
218
|
+
Operation.changeTrust({
|
|
219
|
+
asset: TOKEN_ASSET,
|
|
220
|
+
source: REDISTRIBUTION_ADMIN.publicKey(),
|
|
221
|
+
}),
|
|
222
|
+
)
|
|
223
|
+
// Trustline for USER_A
|
|
224
|
+
.addOperation(
|
|
225
|
+
Operation.changeTrust({
|
|
226
|
+
asset: TOKEN_ASSET,
|
|
227
|
+
source: USER_A.publicKey(),
|
|
228
|
+
}),
|
|
229
|
+
)
|
|
230
|
+
// Trustline for USER_B
|
|
231
|
+
.addOperation(
|
|
232
|
+
Operation.changeTrust({
|
|
233
|
+
asset: TOKEN_ASSET,
|
|
234
|
+
source: USER_B.publicKey(),
|
|
235
|
+
}),
|
|
236
|
+
)
|
|
237
|
+
// Trustline for USER_C
|
|
238
|
+
.addOperation(
|
|
239
|
+
Operation.changeTrust({
|
|
240
|
+
asset: TOKEN_ASSET,
|
|
241
|
+
source: USER_C.publicKey(),
|
|
242
|
+
}),
|
|
243
|
+
)
|
|
244
|
+
// Issue tokens to USER_A (sender)
|
|
245
|
+
.addOperation(
|
|
246
|
+
Operation.payment({
|
|
247
|
+
asset: TOKEN_ASSET,
|
|
248
|
+
amount: INITIAL_TOKEN_AMOUNT,
|
|
249
|
+
destination: USER_A.publicKey(),
|
|
250
|
+
}),
|
|
251
|
+
)
|
|
252
|
+
// Issue tokens to USER_B (will be blacklisted)
|
|
253
|
+
.addOperation(
|
|
254
|
+
Operation.payment({
|
|
255
|
+
asset: TOKEN_ASSET,
|
|
256
|
+
amount: INITIAL_TOKEN_AMOUNT,
|
|
257
|
+
destination: USER_B.publicKey(),
|
|
258
|
+
}),
|
|
259
|
+
)
|
|
260
|
+
.setTimeout(30)
|
|
261
|
+
.build();
|
|
262
|
+
|
|
263
|
+
issueTx.sign(
|
|
264
|
+
TOKEN_ISSUER,
|
|
265
|
+
DEFAULT_DEPLOYER,
|
|
266
|
+
REDISTRIBUTION_ADMIN,
|
|
267
|
+
USER_A,
|
|
268
|
+
USER_B,
|
|
269
|
+
USER_C,
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
const sendResult = await server.sendTransaction(issueTx);
|
|
273
|
+
if (sendResult.status !== 'PENDING') {
|
|
274
|
+
throw new Error(`Failed to setup trustlines: ${JSON.stringify(sendResult)}`);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const txResult = await server.pollTransaction(sendResult.hash);
|
|
278
|
+
if (txResult.status !== 'SUCCESS') {
|
|
279
|
+
throw new Error(`Failed to setup trustlines: ${JSON.stringify(txResult)}`);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
console.log('Trustlines created and tokens issued');
|
|
283
|
+
|
|
284
|
+
// Deploy the SAC for the token
|
|
285
|
+
sacTokenAddress = await deployAssetSac(TOKEN_ASSET);
|
|
286
|
+
console.log('SAC deployed at:', sacTokenAddress);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('Deploy SAC Manager contract with redistribution enabled', async () => {
|
|
290
|
+
sacManagerClient = await deployContract<SacManagerClient>(
|
|
291
|
+
SacManagerClient,
|
|
292
|
+
SAC_MANAGER_WASM_PATH,
|
|
293
|
+
{
|
|
294
|
+
sac_token: sacTokenAddress,
|
|
295
|
+
owner: DEFAULT_DEPLOYER.publicKey(),
|
|
296
|
+
redistribution_enabled: true,
|
|
297
|
+
supply_control_enabled: false,
|
|
298
|
+
},
|
|
299
|
+
DEFAULT_DEPLOYER,
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
sacManagerAddress = sacManagerClient.options.contractId;
|
|
303
|
+
console.log('SAC Manager deployed at:', sacManagerAddress);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it('Set SAC admin to SAC Manager', async () => {
|
|
307
|
+
// Set the SAC admin to the SAC manager contract
|
|
308
|
+
// This allows the SAC manager to call clawback, set_authorized, mint, etc.
|
|
309
|
+
await invokeSacFunction(
|
|
310
|
+
sacTokenAddress,
|
|
311
|
+
'set_admin',
|
|
312
|
+
[Address.fromString(sacManagerAddress).toScVal()],
|
|
313
|
+
TOKEN_ISSUER,
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
console.log('SAC admin set to SAC Manager');
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it('Verify redistribution is enabled at construction', async () => {
|
|
320
|
+
const { result: enabled } = await sacManagerClient.redistribution_enabled();
|
|
321
|
+
expect(enabled).toBe(true);
|
|
322
|
+
console.log('Redistribution enabled:', enabled);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('Verify owner (DEFAULT_DEPLOYER) starts with zero balance', async () => {
|
|
326
|
+
const ownerBalance = await getTokenBalance(
|
|
327
|
+
DEFAULT_DEPLOYER.publicKey(),
|
|
328
|
+
sacTokenAddress,
|
|
329
|
+
);
|
|
330
|
+
console.log('Owner (DEFAULT_DEPLOYER) balance:', ownerBalance.toString());
|
|
331
|
+
expect(ownerBalance).toBe(0n);
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// ========================================================================
|
|
336
|
+
// Blacklist Management
|
|
337
|
+
// ========================================================================
|
|
338
|
+
|
|
339
|
+
describe('Blacklist Management', () => {
|
|
340
|
+
it('Verify all accounts start authorized (AUTH_REQUIRED=false)', async () => {
|
|
341
|
+
// Check authorization status directly on the SAC
|
|
342
|
+
const userAAuthorized = await getTokenAuthorized(USER_A.publicKey(), sacTokenAddress);
|
|
343
|
+
const userBAuthorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
|
|
344
|
+
const userCAuthorized = await getTokenAuthorized(USER_C.publicKey(), sacTokenAddress);
|
|
345
|
+
|
|
346
|
+
expect(userAAuthorized).toBe(true);
|
|
347
|
+
expect(userBAuthorized).toBe(true);
|
|
348
|
+
expect(userCAuthorized).toBe(true);
|
|
349
|
+
|
|
350
|
+
console.log('All users start authorized');
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('Blacklist USER_B via set_authorized', async () => {
|
|
354
|
+
// Use DEFAULT_DEPLOYER (owner) to blacklist USER_B
|
|
355
|
+
const assembledTx = await sacManagerClient.set_authorized({
|
|
356
|
+
id: USER_B.publicKey(),
|
|
357
|
+
authorize: false,
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
await assembledTx.signAndSend();
|
|
361
|
+
console.log('USER_B blacklisted (authorized=false)');
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('Verify USER_B is blacklisted (not authorized on SAC)', async () => {
|
|
365
|
+
const authorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
|
|
366
|
+
expect(authorized).toBe(false);
|
|
367
|
+
console.log('USER_B authorized:', authorized);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it('Non-admin cannot call set_authorized', async () => {
|
|
371
|
+
const userClient = createClientWithSigner(sacManagerAddress, USER_A);
|
|
372
|
+
|
|
373
|
+
const assembledTx = await userClient.set_authorized({
|
|
374
|
+
id: USER_C.publicKey(),
|
|
375
|
+
authorize: false,
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
await expect(assembledTx.signAndSend()).rejects.toThrow();
|
|
379
|
+
console.log('Non-admin correctly rejected from calling set_authorized');
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('Un-blacklist USER_B via set_authorized', async () => {
|
|
383
|
+
// Re-authorize USER_B
|
|
384
|
+
const assembledTx = await sacManagerClient.set_authorized({
|
|
385
|
+
id: USER_B.publicKey(),
|
|
386
|
+
authorize: true,
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
await assembledTx.signAndSend();
|
|
390
|
+
|
|
391
|
+
// Verify
|
|
392
|
+
const authorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
|
|
393
|
+
expect(authorized).toBe(true);
|
|
394
|
+
|
|
395
|
+
const isAuthorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
|
|
396
|
+
expect(isAuthorized).toBe(true);
|
|
397
|
+
|
|
398
|
+
console.log('USER_B un-blacklisted');
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
it('Re-blacklist USER_B for mint redirection tests', async () => {
|
|
402
|
+
const assembledTx = await sacManagerClient.set_authorized({
|
|
403
|
+
id: USER_B.publicKey(),
|
|
404
|
+
authorize: false,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
await assembledTx.signAndSend();
|
|
408
|
+
|
|
409
|
+
const isAuthorized = await getTokenAuthorized(USER_B.publicKey(), sacTokenAddress);
|
|
410
|
+
expect(isAuthorized).toBe(false);
|
|
411
|
+
console.log('USER_B re-blacklisted for transfer tests');
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
// ========================================================================
|
|
416
|
+
// Mint Redirection (redistribution enabled)
|
|
417
|
+
// ========================================================================
|
|
418
|
+
|
|
419
|
+
describe('Mint Redirection', () => {
|
|
420
|
+
it('Verify initial balances', async () => {
|
|
421
|
+
const userABalance = await getTokenBalance(USER_A.publicKey(), sacTokenAddress);
|
|
422
|
+
const userBBalance = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
|
|
423
|
+
const userCBalance = await getTokenBalance(USER_C.publicKey(), sacTokenAddress);
|
|
424
|
+
const ownerBalance = await getTokenBalance(
|
|
425
|
+
DEFAULT_DEPLOYER.publicKey(),
|
|
426
|
+
sacTokenAddress,
|
|
427
|
+
);
|
|
428
|
+
|
|
429
|
+
console.log('\nInitial Balances:');
|
|
430
|
+
console.log(` USER_A: ${userABalance}`);
|
|
431
|
+
console.log(` USER_B: ${userBBalance}`);
|
|
432
|
+
console.log(` USER_C: ${userCBalance}`);
|
|
433
|
+
console.log(` Owner (DEFAULT_DEPLOYER): ${ownerBalance}`);
|
|
434
|
+
|
|
435
|
+
expect(userABalance).toBe(10000000000n); // 1000 tokens
|
|
436
|
+
expect(userBBalance).toBe(10000000000n); // 1000 tokens
|
|
437
|
+
expect(userCBalance).toBe(0n);
|
|
438
|
+
expect(ownerBalance).toBe(0n);
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
it('Admin mint to non-blacklisted address succeeds normally', async () => {
|
|
442
|
+
const userCBalanceBefore = await getTokenBalance(USER_C.publicKey(), sacTokenAddress);
|
|
443
|
+
|
|
444
|
+
const assembledTx = await sacManagerClient.authorized_mint({
|
|
445
|
+
sender: DEFAULT_DEPLOYER.publicKey(),
|
|
446
|
+
to: USER_C.publicKey(),
|
|
447
|
+
amount: TRANSFER_AMOUNT,
|
|
448
|
+
});
|
|
449
|
+
await assembledTx.signAndSend();
|
|
450
|
+
|
|
451
|
+
// Verify balance increased
|
|
452
|
+
const userCBalance = await getTokenBalance(USER_C.publicKey(), sacTokenAddress);
|
|
453
|
+
|
|
454
|
+
console.log('\nAfter authorized_mint to non-blacklisted (USER_C):');
|
|
455
|
+
console.log(` USER_C: ${userCBalance}`);
|
|
456
|
+
|
|
457
|
+
expect(userCBalance).toBe(userCBalanceBefore + TRANSFER_AMOUNT);
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it('Admin mint to blacklisted address redirects to redistribution target (owner)', async () => {
|
|
461
|
+
const ownerBalanceBefore = await getTokenBalance(
|
|
462
|
+
DEFAULT_DEPLOYER.publicKey(),
|
|
463
|
+
sacTokenAddress,
|
|
464
|
+
);
|
|
465
|
+
const userBBalanceBefore = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
|
|
466
|
+
|
|
467
|
+
const assembledTx = await sacManagerClient.authorized_mint({
|
|
468
|
+
sender: DEFAULT_DEPLOYER.publicKey(),
|
|
469
|
+
to: USER_B.publicKey(), // Blacklisted!
|
|
470
|
+
amount: TRANSFER_AMOUNT,
|
|
471
|
+
});
|
|
472
|
+
await assembledTx.signAndSend();
|
|
473
|
+
|
|
474
|
+
// Verify balances - USER_B should not receive, owner should
|
|
475
|
+
const userBBalance = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
|
|
476
|
+
const ownerBalance = await getTokenBalance(
|
|
477
|
+
DEFAULT_DEPLOYER.publicKey(),
|
|
478
|
+
sacTokenAddress,
|
|
479
|
+
);
|
|
480
|
+
|
|
481
|
+
console.log('\nAfter authorized_mint to blacklisted (USER_B):');
|
|
482
|
+
console.log(` USER_B: ${userBBalance} (unchanged)`);
|
|
483
|
+
console.log(` Owner (received redirected): ${ownerBalance}`);
|
|
484
|
+
|
|
485
|
+
// USER_B balance should be unchanged
|
|
486
|
+
expect(userBBalance).toBe(userBBalanceBefore);
|
|
487
|
+
// Owner should receive the redirected tokens
|
|
488
|
+
expect(ownerBalance).toBe(ownerBalanceBefore + TRANSFER_AMOUNT);
|
|
489
|
+
});
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
// ========================================================================
|
|
493
|
+
// Redistribute Funds
|
|
494
|
+
// ========================================================================
|
|
495
|
+
|
|
496
|
+
describe('Redistribute Funds', () => {
|
|
497
|
+
it('Redistribute funds from blacklisted account', async () => {
|
|
498
|
+
const ownerBalanceBefore = await getTokenBalance(
|
|
499
|
+
DEFAULT_DEPLOYER.publicKey(),
|
|
500
|
+
sacTokenAddress,
|
|
501
|
+
);
|
|
502
|
+
const userBBalanceBefore = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
|
|
503
|
+
|
|
504
|
+
console.log('\nBefore redistribute_blacklisted_funds:');
|
|
505
|
+
console.log(` USER_B: ${userBBalanceBefore}`);
|
|
506
|
+
console.log(` Owner: ${ownerBalanceBefore}`);
|
|
507
|
+
|
|
508
|
+
// Only owner can redistribute - use DEFAULT_DEPLOYER
|
|
509
|
+
const assembledTx = await sacManagerClient.redistribute_blacklisted_funds({
|
|
510
|
+
from: USER_B.publicKey(),
|
|
511
|
+
amount: REDISTRIBUTE_AMOUNT,
|
|
512
|
+
});
|
|
513
|
+
await assembledTx.signAndSend();
|
|
514
|
+
|
|
515
|
+
// Verify balances
|
|
516
|
+
const userBBalance = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
|
|
517
|
+
const ownerBalance = await getTokenBalance(
|
|
518
|
+
DEFAULT_DEPLOYER.publicKey(),
|
|
519
|
+
sacTokenAddress,
|
|
520
|
+
);
|
|
521
|
+
|
|
522
|
+
console.log('\nAfter redistribute_blacklisted_funds:');
|
|
523
|
+
console.log(` USER_B: ${userBBalance}`);
|
|
524
|
+
console.log(` Owner: ${ownerBalance}`);
|
|
525
|
+
|
|
526
|
+
expect(userBBalance).toBe(userBBalanceBefore - REDISTRIBUTE_AMOUNT);
|
|
527
|
+
expect(ownerBalance).toBe(ownerBalanceBefore + REDISTRIBUTE_AMOUNT);
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
it('Cannot redistribute from non-blacklisted account', async () => {
|
|
531
|
+
// USER_A is not blacklisted - this should fail even for owner
|
|
532
|
+
const assembledTx = await sacManagerClient.redistribute_blacklisted_funds({
|
|
533
|
+
from: USER_A.publicKey(),
|
|
534
|
+
amount: REDISTRIBUTE_AMOUNT,
|
|
535
|
+
});
|
|
536
|
+
await expect(assembledTx.signAndSend()).rejects.toThrow();
|
|
537
|
+
console.log('Correctly rejected redistribution from non-blacklisted account');
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
it('Non-owner cannot redistribute', async () => {
|
|
541
|
+
// USER_A is not the owner - this should fail
|
|
542
|
+
const userClient = createClientWithSigner(sacManagerAddress, USER_A);
|
|
543
|
+
const assembledTx = await userClient.redistribute_blacklisted_funds({
|
|
544
|
+
from: USER_B.publicKey(),
|
|
545
|
+
amount: REDISTRIBUTE_AMOUNT,
|
|
546
|
+
});
|
|
547
|
+
await expect(assembledTx.signAndSend()).rejects.toThrow();
|
|
548
|
+
console.log('Non-owner correctly rejected from redistributing');
|
|
549
|
+
});
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
// ========================================================================
|
|
553
|
+
// Final Summary
|
|
554
|
+
// ========================================================================
|
|
555
|
+
|
|
556
|
+
describe('Final Summary', () => {
|
|
557
|
+
it('Print final balances', async () => {
|
|
558
|
+
const userABalance = await getTokenBalance(USER_A.publicKey(), sacTokenAddress);
|
|
559
|
+
const userBBalance = await getTokenBalance(USER_B.publicKey(), sacTokenAddress);
|
|
560
|
+
const userCBalance = await getTokenBalance(USER_C.publicKey(), sacTokenAddress);
|
|
561
|
+
const ownerBalance = await getTokenBalance(
|
|
562
|
+
DEFAULT_DEPLOYER.publicKey(),
|
|
563
|
+
sacTokenAddress,
|
|
564
|
+
);
|
|
565
|
+
|
|
566
|
+
console.log('\n========================================');
|
|
567
|
+
console.log('Final Balance Summary');
|
|
568
|
+
console.log('========================================');
|
|
569
|
+
console.log(` USER_A: ${userABalance}`);
|
|
570
|
+
console.log(` USER_B (blacklisted): ${userBBalance}`);
|
|
571
|
+
console.log(` USER_C: ${userCBalance}`);
|
|
572
|
+
console.log(` Owner (redistribution target): ${ownerBalance}`);
|
|
573
|
+
console.log('========================================\n');
|
|
574
|
+
|
|
575
|
+
console.log('SAC Manager Redistribution E2E tests completed successfully!');
|
|
576
|
+
});
|
|
577
|
+
});
|
|
578
|
+
});
|
|
@@ -230,18 +230,12 @@ async function deployChainContracts(eid: number, chainLabel: string): Promise<Ch
|
|
|
230
230
|
|
|
231
231
|
// 10. Deploy Executor (supports both ULN302 and SML)
|
|
232
232
|
console.log(`🚀 [${chainLabel}] Deploying Executor...`);
|
|
233
|
-
const whitelist = [
|
|
234
|
-
[addresses.executorHelper, 'native_drop_and_execute'],
|
|
235
|
-
[addresses.executorHelper, 'execute'],
|
|
236
|
-
[addresses.executorHelper, 'compose'],
|
|
237
|
-
];
|
|
238
233
|
const executorClient = await deployContract<ExecutorClient>(
|
|
239
234
|
ExecutorClient,
|
|
240
235
|
path.join(wasmDir, 'executor.wasm'),
|
|
241
236
|
{
|
|
242
237
|
owner: DEFAULT_DEPLOYER.publicKey(),
|
|
243
238
|
endpoint: addresses.endpointV2,
|
|
244
|
-
whitelist,
|
|
245
239
|
admins: [EXECUTOR_ADMIN.publicKey(), DEFAULT_DEPLOYER.publicKey()],
|
|
246
240
|
message_libs: [addresses.uln302, addresses.sml],
|
|
247
241
|
price_feed: addresses.priceFeed,
|
|
@@ -254,6 +248,17 @@ async function deployChainContracts(eid: number, chainLabel: string): Promise<Ch
|
|
|
254
248
|
addresses.executor = executorClient.options.contractId;
|
|
255
249
|
console.log(`✅ [${chainLabel}] Executor deployed:`, addresses.executor);
|
|
256
250
|
|
|
251
|
+
// 11. Register Executor Helper with Executor
|
|
252
|
+
console.log(`🚀 [${chainLabel}] Registering Executor Helper with Executor...`);
|
|
253
|
+
await (
|
|
254
|
+
await executorClient.set_executor_helper({
|
|
255
|
+
admin: DEFAULT_DEPLOYER.publicKey(),
|
|
256
|
+
helper: addresses.executorHelper,
|
|
257
|
+
allowed_functions: ['execute', 'compose', 'native_drop_and_execute'],
|
|
258
|
+
})
|
|
259
|
+
).signAndSend();
|
|
260
|
+
console.log(`✅ [${chainLabel}] Executor Helper registered`);
|
|
261
|
+
|
|
257
262
|
const clients: ChainClients = {
|
|
258
263
|
endpointClient,
|
|
259
264
|
uln302Client,
|
|
Binary file
|