@layerzerolabs/ton-sdk-tools 3.0.59 → 3.0.60

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/dist/index.mjs CHANGED
@@ -340,6 +340,7 @@ import {
340
340
  TupleItem,
341
341
  TupleReader,
342
342
  contractAddress,
343
+ beginCell,
343
344
  } from '@ton/core'
344
345
 
345
346
  ${baseWrapper}
@@ -371,6 +372,18 @@ export class TonContractWrapper extends BaseWrapper {
371
372
  return this.buildSenderArguments(body, opts)
372
373
  }
373
374
 
375
+ async sendTonPayment(
376
+ provider: ContractProvider,
377
+ via: Sender,
378
+ opts: SendRequestOptions,
379
+ ): Promise<void> {
380
+ if (via.address === undefined) {
381
+ throw new Error('Sender address is not defined')
382
+ }
383
+ const request = this.buildSenderArguments(beginCell().endCell(), opts)
384
+ return this.sendRequest(provider, via, request)
385
+ }
386
+
374
387
  async sendInternalMessage(
375
388
  provider: ContractProvider,
376
389
  via: Sender,
@@ -1222,7 +1235,18 @@ var BaseWrapper = class {
1222
1235
  function generateCommonTestUtils(directory, filename) {
1223
1236
  const savedCode = `import fs from 'fs'
1224
1237
 
1225
- import { Address, Builder, Cell, Dictionary, SendMode, TupleItem, TupleItemCell, TupleItemInt, beginCell, toNano } from '@ton/core'
1238
+ import {
1239
+ Address,
1240
+ Builder,
1241
+ Cell,
1242
+ Dictionary,
1243
+ SendMode,
1244
+ TupleItem,
1245
+ TupleItemCell,
1246
+ TupleItemInt,
1247
+ beginCell,
1248
+ toNano,
1249
+ } from '@ton/core'
1226
1250
  import {
1227
1251
  Blockchain,
1228
1252
  BlockchainTransaction,
@@ -1461,7 +1485,7 @@ export interface ProtocolFixture {
1461
1485
  eid: bigint
1462
1486
  controller: SandboxContract<TonContractWrapper>
1463
1487
  endpoint: SandboxContract<TonContractWrapper>
1464
- msglib: SandboxContract<TonContractWrapper>
1488
+ msglib: Map<bigint, SandboxContract<TonContractWrapper>>
1465
1489
  msglibManager: SandboxContract<TonContractWrapper>
1466
1490
  msglibManagerCustom?: SandboxContract<TonContractWrapper>
1467
1491
  }
@@ -1493,17 +1517,18 @@ export function logAddresses(
1493
1517
  prefix: string,
1494
1518
  protocolHeader: string,
1495
1519
  oappHeader: string,
1496
- fixture: OAppFixture
1520
+ fixture: OAppFixture,
1521
+ eid: bigint
1497
1522
  ) => {
1498
1523
  [p: string]: string | bigint | null
1499
- } = function (prefix: string, protocolHeader: string, oappHeader: string, fixture: OAppFixture) {
1524
+ } = function (prefix: string, protocolHeader: string, oappHeader: string, fixture: OAppFixture, eid: bigint) {
1500
1525
  return {
1501
1526
  [\`--- \${protocolHeader} ---\`]: '', // Custom separator
1502
1527
  [\`\${prefix}.multisig.address\`]: formatAddress(fixture.multisig.address),
1503
1528
  [\`\${prefix}.controller.address\`]: formatAddress(fixture.controller.address),
1504
1529
  [\`\${prefix}.endpoint.address\`]: formatAddress(fixture.endpoint.address),
1505
1530
  [\`\${prefix}.msglibManager.address\`]: formatAddress(fixture.msglibManager.address),
1506
- [\`\${prefix}.msglib.address\`]: formatAddress(fixture.msglib.address),
1531
+ [\`\${prefix}.msglib.address\`]: formatAddress(fixture.msglib.get(eid)?.address ?? ''),
1507
1532
  [\`\${prefix}.smlManagerCustom.address\`]: formatAddress(fixture.msglibManagerCustom?.address ?? ''),
1508
1533
  [\`--- \${oappHeader} ---\`]: '', // Custom separator
1509
1534
  [\`\${prefix}.owner.address\`]: formatAddress(fixture.owner.address),
@@ -1520,9 +1545,21 @@ export function logAddresses(
1520
1545
  'multiSigOwner1.address': formatAddress(multiSigOwner1.address),
1521
1546
  'multiSigOwner2.address': formatAddress(multiSigOwner2.address),
1522
1547
  'multiSigOwner3.address': formatAddress(multiSigOwner3.address),
1523
- ...collectAddresses('srcFixture', 'Source Protocol Addresses', 'Source OApp Addresses', srcFixture),
1548
+ ...collectAddresses(
1549
+ 'srcFixture',
1550
+ 'Source Protocol Addresses',
1551
+ 'Source OApp Addresses',
1552
+ srcFixture,
1553
+ dstFixture?.eid ?? 0n
1554
+ ),
1524
1555
  ...(dstFixture
1525
- ? collectAddresses('dstFixture', 'Destination Protocol Addresses', 'Destination OApp Addresses', dstFixture)
1556
+ ? collectAddresses(
1557
+ 'dstFixture',
1558
+ 'Destination Protocol Addresses',
1559
+ 'Destination OApp Addresses',
1560
+ dstFixture,
1561
+ srcFixture.eid
1562
+ )
1526
1563
  : {}),
1527
1564
  }
1528
1565
 
@@ -2698,12 +2735,12 @@ export async function assertZroBalance(
2698
2735
  }
2699
2736
 
2700
2737
  export function isValidAscii(input: string): boolean {
2701
- for (var i=0; i < input.length; i++) {
2702
- if (input.charCodeAt(i)>127) {
2703
- return false;
2738
+ for (let i = 0; i < input.length; i++) {
2739
+ if (input.charCodeAt(i) > 127) {
2740
+ return false
2704
2741
  }
2705
2742
  }
2706
- return true;
2743
+ return true
2707
2744
  }
2708
2745
 
2709
2746
  export async function txDecoder(
@@ -2802,432 +2839,427 @@ export async function runtimeDecoder(contract: SandboxContract<TonContractWrappe
2802
2839
  }
2803
2840
  function generateSmlTestUtils(directory, filename) {
2804
2841
  const savedCode = `import { Cell, toNano } from '@ton/core'
2805
- import { Blockchain, SandboxContract, SendMessageResult, TreasuryContract } from '@ton/sandbox'
2806
- import '@ton/test-utils'
2807
-
2808
- import ChannelArtifact from '@layerzerolabs/layerzero-v2-ton/build/Channel.compiled.json'
2809
- import EndpointArtifact from '@layerzerolabs/layerzero-v2-ton/build/Endpoint.compiled.json'
2810
- import SmlConnectionArtifact from '@layerzerolabs/layerzero-v2-ton/build/SmlConnection.compiled.json'
2811
- import SmlManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/SmlManager.compiled.json'
2812
- import { Profile, addressToBigInt, cellFromArtifact } from '@layerzerolabs/ton-sdk-tools'
2813
-
2814
- import {
2815
- OAppFixture,
2816
- OAppFlowGas,
2817
- addMsgLibToController,
2818
- emptyObject,
2819
- protocolSetupGas,
2820
- sendInternalMessageAndExpect,
2821
- setDefaultEndpointConfig,
2822
- wireChannels,
2823
- } from './auto-utils-common'
2824
- import { LzEventHandler, OPCODES, TonContractWrapper } from '../../src'
2825
-
2826
- const SML_MANAGER_DEFAULT_VERSION = BigInt(1)
2827
- const SML_MANAGER_CUSTOM_VERSION = BigInt(2)
2828
-
2829
- // ==============================SML INTEGRATION FUNCTIONS==============================
2830
-
2831
- export async function commitVerificationAndExpectSml(
2832
- lzPacketCell: Cell,
2833
- deployer: SandboxContract<TreasuryContract>,
2834
- eventHandler: LzEventHandler,
2835
- {
2836
- endpoint,
2837
- channel,
2838
- msglibManager: smlManager,
2839
- msglibConnection: smlConnection,
2840
- controller,
2841
- }: OAppFixture,
2842
- profile?: Profile
2843
- ): Promise<void> {
2844
- const internalMsgResults: SendMessageResult = await sendInternalMessageAndExpect({
2845
- profile,
2846
- value: OAppFlowGas['Msglib.COMMIT_PACKET'],
2847
- sender: deployer.getSender(),
2848
- contract: smlManager,
2849
- opCode: OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET,
2850
- md: await smlManager.getNewMdMdAddress({
2851
- md: lzPacketCell,
2852
- address: addressToBigInt(endpoint.address),
2853
- }),
2854
- expectedTransactions: [
2855
- {
2856
- from: deployer.address,
2857
- to: smlManager.address,
2858
- op: Number(OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET),
2859
- success: true,
2860
- },
2861
- {
2862
- from: smlManager.address,
2863
- to: smlConnection.address,
2864
- op: Number(OPCODES.SmlConnection_OP_SML_CONNECTION_COMMIT_PACKET),
2865
- success: true,
2866
- },
2867
- {
2868
- from: smlConnection.address,
2869
- to: endpoint.address,
2870
- op: Number(OPCODES.Endpoint_OP_ENDPOINT_COMMIT_PACKET),
2871
- success: true,
2872
- },
2873
- {
2874
- from: endpoint.address,
2875
- to: channel.address,
2876
- op: Number(OPCODES.Channel_OP_CHANNEL_COMMIT_PACKET),
2877
- success: true,
2878
- },
2879
- // emit event channel::EVENT::MESSAGE_COMMITTED
2880
- {
2881
- from: channel.address,
2882
- to: controller.address,
2883
- op: Number(OPCODES.BaseInterface_OP_EVENT),
2884
- success: false, // events are supposed to fail
2885
- },
2886
- {
2887
- from: channel.address,
2888
- to: smlConnection.address,
2889
- op: Number(OPCODES.MsglibConnection_OP_MSGLIB_CONNECTION_COMMIT_PACKET_CALLBACK),
2890
- success: true,
2891
- },
2892
- {
2893
- from: smlConnection.address,
2894
- to: smlManager.address,
2895
- op: Number(OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET_CALLBACK),
2896
- success: true,
2897
- },
2898
- // refund excess ton
2899
- {
2900
- from: smlManager.address,
2901
- to: deployer.address,
2902
- success: true,
2903
- },
2904
- ],
2905
- })
2906
-
2907
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, smlManager)
2908
- expect(eventHandler.allFailures.txList).toHaveLength(0)
2909
- }
2910
-
2911
- // ===============================HELPER ASSERTS===============================
2912
-
2913
- export async function openAndDeploySmlManager(
2914
- blockchain: Blockchain,
2915
- allStorages: SandboxContract<TonContractWrapper>,
2916
- fixture: OAppFixture,
2917
- version: bigint
2918
- ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
2919
- const smlManager: SandboxContract<TonContractWrapper> = blockchain.openContract(
2920
- TonContractWrapper.create(
2921
- cellFromArtifact(SmlManagerArtifact),
2922
- await allStorages.getNewSmlManager({
2923
- owner: addressToBigInt(fixture.owner.address),
2924
- eid: fixture.eid,
2925
- version,
2926
- controllerAddress: addressToBigInt(fixture.controller.address),
2927
- endpointCode: cellFromArtifact(EndpointArtifact),
2928
- channelCode: cellFromArtifact(ChannelArtifact),
2929
- smlConnectionCode: cellFromArtifact(SmlConnectionArtifact),
2930
- })
2931
- )
2932
- )
2933
-
2934
- const internalMsgResults = await sendInternalMessageAndExpect({
2935
- value: protocolSetupGas['MsgLib.INITIALIZE'],
2936
- sender: fixture.owner.getSender(),
2937
- contract: smlManager,
2938
- expectedTransactions: [
2939
- {
2940
- from: fixture.owner.address,
2941
- to: smlManager.address,
2942
- success: true,
2943
- },
2944
- ],
2945
- opCode: OPCODES.BaseInterface_OP_INITIALIZE,
2946
- md: emptyObject,
2947
- balanceRefill: toNano('1'),
2948
- })
2949
-
2950
- return [smlManager, internalMsgResults]
2951
- }
2952
-
2953
- export async function openAndDeploySmlConnection(
2954
- blockchain: Blockchain,
2955
- allStorages: SandboxContract<TonContractWrapper>,
2956
- srcFixture: OAppFixture,
2957
- dstFixture: OAppFixture,
2958
- smlManager: SandboxContract<TonContractWrapper>
2959
- ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
2960
- const smlConnection: SandboxContract<TonContractWrapper> = blockchain.openContract(
2961
- TonContractWrapper.create(
2962
- cellFromArtifact(SmlConnectionArtifact),
2963
- await allStorages.getNewSmlConnection({
2964
- owner: addressToBigInt(smlManager.address),
2965
- path: srcFixture.path,
2966
- })
2967
- )
2968
- )
2969
-
2970
- const internalMsgResults = await sendInternalMessageAndExpect({
2971
- value: toNano('10'),
2972
- sender: srcFixture.owner.getSender(),
2973
- contract: srcFixture.oApp,
2974
- opCode: OPCODES.OP_DeployConnection,
2975
- md: await allStorages.getNewMdMdAddress({
2976
- md: await allStorages.getNewMdDeploy({
2977
- dstEid: dstFixture.eid,
2978
- dstOApp: addressToBigInt(dstFixture.oApp.address),
2979
- initialDeposit: toNano('1'),
2980
- }),
2981
- address: addressToBigInt(smlManager.address),
2982
- }),
2983
- expectedTransactions: [
2984
- {
2985
- from: srcFixture.owner.address,
2986
- to: srcFixture.oApp.address,
2987
- op: Number(OPCODES.OP_DeployConnection),
2988
- success: true,
2989
- },
2990
- {
2991
- from: srcFixture.oApp.address,
2992
- to: smlManager.address,
2993
- op: Number(OPCODES.MsglibManager_OP_DEPLOY_CONNECTION),
2994
- success: true,
2995
- },
2996
- {
2997
- from: smlManager.address,
2998
- to: smlConnection.address,
2999
- op: Number(OPCODES.BaseInterface_OP_INITIALIZE),
3000
- deploy: true,
3001
- success: true,
3002
- },
3003
- ],
3004
- })
3005
-
3006
- return [smlConnection, internalMsgResults]
3007
- }
3008
-
3009
- export async function deployConfigAndRegisterSml(
3010
- blockchain: Blockchain,
3011
- multiSigners: SandboxContract<TreasuryContract>[],
3012
- allStorages: SandboxContract<TonContractWrapper>,
3013
- srcFixture: OAppFixture,
3014
- dstFixture: OAppFixture,
3015
- version: bigint,
3016
- nativeFee: bigint,
3017
- zroFee: bigint,
3018
- eventHandler: LzEventHandler
3019
- ): Promise<[SandboxContract<TonContractWrapper>, SandboxContract<TonContractWrapper>]> {
3020
- // ===================================open and deploy sml manager =====================================
3021
- const [msglibManager, internalMsgResults_1] = await openAndDeploySmlManager(
3022
- blockchain,
3023
- allStorages,
3024
- srcFixture,
3025
- version
3026
- )
3027
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults_1, msglibManager)
3028
-
3029
- // ===================================open and deploy sml connection =====================================
3030
- const [msglibConnection, internalMsgResults_2] = await openAndDeploySmlConnection(
3031
- blockchain,
3032
- allStorages,
3033
- srcFixture,
3034
- dstFixture,
3035
- msglibManager
3036
- )
3037
-
3038
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults_2, srcFixture.oApp)
3039
-
3040
- // ===================================configure sml =====================================
3041
-
3042
- const set_sml_config_md = await msglibManager.getNewMdSetSmlManagerConfig({
3043
- nativeFee,
3044
- zroFee,
3045
- })
3046
-
3047
- const set_sml_config_extended_md = await msglibManager.getNewMdExtendedMd({
3048
- md: set_sml_config_md,
3049
- obj: emptyObject,
3050
- forwardingAddress: BigInt(0),
3051
- })
3052
-
3053
- let internalMsgResults: SendMessageResult = await msglibManager.sendInternalMessage(
3054
- srcFixture.owner.getSender(),
3055
- OPCODES.SmlManager_OP_SET_MSGLIB_CONFIG,
3056
- set_sml_config_extended_md,
3057
- { value: protocolSetupGas['Msglib.SET_MSGLIB_CONFIG'] }
3058
- )
3059
-
3060
- // emits 1 event
3061
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, msglibManager)
3062
-
3063
- internalMsgResults = await addMsgLibToController(blockchain, multiSigners, srcFixture, dstFixture, msglibManager)
3064
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
3065
-
3066
- return [msglibManager, msglibConnection]
3067
- }
3068
-
3069
- export async function wireFixtureWithSML(
3070
- blockchain: Blockchain,
3071
- allStorages: SandboxContract<TonContractWrapper>,
3072
- multiSigners: SandboxContract<TreasuryContract>[],
3073
- srcFixture: OAppFixture,
3074
- dstFixture: OAppFixture,
3075
- customNativeFee: bigint = toNano('0'),
3076
- customZroFee: bigint = toNano('0.000000050'),
3077
- defaultNativeFee: bigint = toNano('0.000000100'),
3078
- defaultZroFee: bigint = toNano('0'),
3079
- eventHandler: LzEventHandler
3080
- ): Promise<void> {
3081
- // ===================================wire channels=====================================
3082
-
3083
- await wireChannels(blockchain, allStorages, srcFixture, dstFixture, eventHandler)
3084
-
3085
- // ===================================deploy and configure sml custom=====================================
3086
- ;[srcFixture.msglibManagerCustom, srcFixture.msglibConnectionCustom] = await deployConfigAndRegisterSml(
3087
- blockchain,
3088
- multiSigners,
3089
- allStorages,
3090
- srcFixture,
3091
- dstFixture,
3092
- SML_MANAGER_CUSTOM_VERSION,
3093
- customNativeFee,
3094
- customZroFee,
3095
- eventHandler
3096
- )
3097
-
3098
- // ===================================deploy and configure sml default=====================================
3099
- ;[srcFixture.msglibManager, srcFixture.msglibConnection] = await deployConfigAndRegisterSml(
3100
- blockchain,
3101
- multiSigners,
3102
- allStorages,
3103
- srcFixture,
3104
- dstFixture,
3105
- SML_MANAGER_DEFAULT_VERSION,
3106
- defaultNativeFee,
3107
- defaultZroFee,
3108
- eventHandler
3109
- )
3110
-
3111
- // ===================================set default endpoint config=====================================
3112
-
3113
- const internalMsgResults = await setDefaultEndpointConfig(
3114
- blockchain,
3115
- allStorages,
3116
- multiSigners,
3117
- srcFixture.msglibManager,
3118
- srcFixture.msglibManager,
3119
- srcFixture,
3120
- dstFixture
3121
- )
3122
-
3123
- // in SML, the connection is the Msglib
3124
- srcFixture.msglib = srcFixture.msglibConnection
3125
-
3126
- await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
3127
- expect(eventHandler.allFailures.txList).toHaveLength(0)
3128
- }
3129
-
3130
- export async function wireFixturesTogetherWithSML(
3131
- blockchain: Blockchain,
3132
- allStorages: SandboxContract<TonContractWrapper>,
3133
- multiSigners: SandboxContract<TreasuryContract>[],
3134
- srcFixture: OAppFixture,
3135
- dstFixture: OAppFixture,
3136
- customNativeFee: bigint = toNano('0'),
3137
- customZroFee: bigint = toNano('0.000000050'),
3138
- defaultNativeFee: bigint = toNano('0.000000100'),
3139
- defaultZroFee: bigint = toNano('0'),
3140
- eventHandler: LzEventHandler
3141
- ): Promise<void> {
3142
- await wireFixtureWithSML(
3143
- blockchain,
3144
- allStorages,
3145
- multiSigners,
3146
- srcFixture,
3147
- dstFixture,
3148
- customNativeFee,
3149
- customZroFee,
3150
- defaultNativeFee,
3151
- defaultZroFee,
3152
- eventHandler
3153
- )
3154
- await wireFixtureWithSML(
3155
- blockchain,
3156
- allStorages,
3157
- multiSigners,
3158
- dstFixture,
3159
- srcFixture,
3160
- customNativeFee,
3161
- customZroFee,
3162
- defaultNativeFee,
3163
- defaultZroFee,
3164
- eventHandler
3165
- )
3166
- }
3167
- `;
3168
- fs__default.writeFileSync(path__default.join(directory, filename), savedCode);
3169
- }
3170
- function generateUlnTestUtils(directory, filename) {
3171
- const savedCode = `import { Address, Cell, TupleItemCell, beginCell, toNano } from '@ton/core'
3172
2842
  import { Blockchain, SandboxContract, SendMessageResult, TreasuryContract } from '@ton/sandbox'
3173
- import { FlatTransactionComparable } from '@ton/test-utils'
3174
- import { ethers } from 'ethers'
2843
+ import '@ton/test-utils'
3175
2844
 
3176
2845
  import ChannelArtifact from '@layerzerolabs/layerzero-v2-ton/build/Channel.compiled.json'
3177
- import DvnArtifact from '@layerzerolabs/layerzero-v2-ton/build/Dvn.compiled.json'
3178
- import DvnFeelibArtifact from '@layerzerolabs/layerzero-v2-ton/build/DvnFeeLib.compiled.json'
3179
2846
  import EndpointArtifact from '@layerzerolabs/layerzero-v2-ton/build/Endpoint.compiled.json'
3180
- import ExecutorArtifact from '@layerzerolabs/layerzero-v2-ton/build/Executor.compiled.json'
3181
- import ExecutorFeelibArtifact from '@layerzerolabs/layerzero-v2-ton/build/ExecutorFeeLib.compiled.json'
3182
- import PriceFeedCacheArtifact from '@layerzerolabs/layerzero-v2-ton/build/PriceFeedCache.compiled.json'
3183
- import PriceFeedFeeLibDefaultArtifact from '@layerzerolabs/layerzero-v2-ton/build/PriceFeedFeeLibDefault.compiled.json'
3184
- import ProxyArtifact from '@layerzerolabs/layerzero-v2-ton/build/Proxy.compiled.json'
3185
- import UlnArtifact from '@layerzerolabs/layerzero-v2-ton/build/Uln.compiled.json'
3186
- import UlnConnectionArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnConnection.compiled.json'
3187
- import UlnManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnManager.compiled.json'
2847
+ import SmlConnectionArtifact from '@layerzerolabs/layerzero-v2-ton/build/SmlConnection.compiled.json'
2848
+ import SmlManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/SmlManager.compiled.json'
3188
2849
  import { Profile, addressToBigInt, cellFromArtifact } from '@layerzerolabs/ton-sdk-tools'
3189
2850
 
3190
2851
  import {
3191
2852
  OAppFixture,
3192
2853
  OAppFlowGas,
3193
- ProtocolFixture,
3194
- SIGNATURE_BYTE_LENGTH,
3195
2854
  addMsgLibToController,
3196
- createLzPacketFromPacketEncoded,
3197
- createVerifierDictSet,
3198
2855
  emptyObject,
3199
- generateRandomVerifierSet,
3200
2856
  protocolSetupGas,
3201
- publicKeyToHash,
3202
- requireDefined,
3203
2857
  sendInternalMessageAndExpect,
3204
- sendMessageViaMultisigAndExpect,
3205
- serializeAddressList,
3206
2858
  setDefaultEndpointConfig,
3207
2859
  wireChannels,
3208
2860
  } from './auto-utils-common'
3209
- import {
3210
- ExtendedContract,
3211
- LzDict,
3212
- LzEventHandler,
3213
- MdPacketSent,
3214
- OPCODES,
3215
- TonContractWrapper,
3216
- TonObjectUnwrapper,
3217
- } from '../../src'
2861
+ import { LzEventHandler, OPCODES, TonContractWrapper } from '../../src'
3218
2862
 
3219
- const ULN_MANAGER_DEFAULT_VERSION = BigInt(1)
2863
+ const SML_MANAGER_DEFAULT_VERSION = BigInt(1)
2864
+ const SML_MANAGER_CUSTOM_VERSION = BigInt(2)
3220
2865
 
3221
- export const TRUE = BigInt(-1)
3222
- export const FALSE = BigInt(0)
3223
- export const UlnConnectionVerificationStatusVerifying = BigInt(0)
3224
- export const UlnConnectionVerificationStatusCommittable = BigInt(1)
3225
- export const ChannelExecutionStatusExecutable = BigInt(2)
2866
+ // ==============================SML INTEGRATION FUNCTIONS==============================
3226
2867
 
3227
- export interface SendUlnConfig {
3228
- workerQuoteGasLimit: bigint
3229
- maxMessageBytes: bigint
3230
- }
2868
+ export async function commitVerificationAndExpectSml(
2869
+ lzPacketCell: Cell,
2870
+ deployer: SandboxContract<TreasuryContract>,
2871
+ eventHandler: LzEventHandler,
2872
+ { endpoint, channel, msglibManager: smlManager, msglibConnection: smlConnection, controller }: OAppFixture,
2873
+ profile?: Profile
2874
+ ): Promise<void> {
2875
+ const internalMsgResults: SendMessageResult = await sendInternalMessageAndExpect({
2876
+ profile,
2877
+ value: OAppFlowGas['Msglib.COMMIT_PACKET'],
2878
+ sender: deployer.getSender(),
2879
+ contract: smlManager,
2880
+ opCode: OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET,
2881
+ md: await smlManager.getNewMdMdAddress({
2882
+ md: lzPacketCell,
2883
+ address: addressToBigInt(endpoint.address),
2884
+ }),
2885
+ expectedTransactions: [
2886
+ {
2887
+ from: deployer.address,
2888
+ to: smlManager.address,
2889
+ op: Number(OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET),
2890
+ success: true,
2891
+ },
2892
+ {
2893
+ from: smlManager.address,
2894
+ to: smlConnection.address,
2895
+ op: Number(OPCODES.SmlConnection_OP_SML_CONNECTION_COMMIT_PACKET),
2896
+ success: true,
2897
+ },
2898
+ {
2899
+ from: smlConnection.address,
2900
+ to: endpoint.address,
2901
+ op: Number(OPCODES.Endpoint_OP_ENDPOINT_COMMIT_PACKET),
2902
+ success: true,
2903
+ },
2904
+ {
2905
+ from: endpoint.address,
2906
+ to: channel.address,
2907
+ op: Number(OPCODES.Channel_OP_CHANNEL_COMMIT_PACKET),
2908
+ success: true,
2909
+ },
2910
+ // emit event channel::EVENT::MESSAGE_COMMITTED
2911
+ {
2912
+ from: channel.address,
2913
+ to: controller.address,
2914
+ op: Number(OPCODES.BaseInterface_OP_EVENT),
2915
+ success: false, // events are supposed to fail
2916
+ },
2917
+ {
2918
+ from: channel.address,
2919
+ to: smlConnection.address,
2920
+ op: Number(OPCODES.MsglibConnection_OP_MSGLIB_CONNECTION_COMMIT_PACKET_CALLBACK),
2921
+ success: true,
2922
+ },
2923
+ {
2924
+ from: smlConnection.address,
2925
+ to: smlManager.address,
2926
+ op: Number(OPCODES.SmlManager_OP_SML_MANAGER_COMMIT_PACKET_CALLBACK),
2927
+ success: true,
2928
+ },
2929
+ // refund excess ton
2930
+ {
2931
+ from: smlManager.address,
2932
+ to: deployer.address,
2933
+ success: true,
2934
+ },
2935
+ ],
2936
+ })
2937
+
2938
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, smlManager)
2939
+ expect(eventHandler.allFailures.txList).toHaveLength(0)
2940
+ }
2941
+
2942
+ // ===============================HELPER ASSERTS===============================
2943
+
2944
+ export async function openAndDeploySmlManager(
2945
+ blockchain: Blockchain,
2946
+ allStorages: SandboxContract<TonContractWrapper>,
2947
+ fixture: OAppFixture,
2948
+ version: bigint
2949
+ ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
2950
+ const smlManager: SandboxContract<TonContractWrapper> = blockchain.openContract(
2951
+ TonContractWrapper.create(
2952
+ cellFromArtifact(SmlManagerArtifact),
2953
+ await allStorages.getNewSmlManager({
2954
+ owner: addressToBigInt(fixture.owner.address),
2955
+ eid: fixture.eid,
2956
+ version,
2957
+ controllerAddress: addressToBigInt(fixture.controller.address),
2958
+ endpointCode: cellFromArtifact(EndpointArtifact),
2959
+ channelCode: cellFromArtifact(ChannelArtifact),
2960
+ smlConnectionCode: cellFromArtifact(SmlConnectionArtifact),
2961
+ })
2962
+ )
2963
+ )
2964
+
2965
+ const internalMsgResults = await sendInternalMessageAndExpect({
2966
+ value: protocolSetupGas['MsgLib.INITIALIZE'],
2967
+ sender: fixture.owner.getSender(),
2968
+ contract: smlManager,
2969
+ expectedTransactions: [
2970
+ {
2971
+ from: fixture.owner.address,
2972
+ to: smlManager.address,
2973
+ success: true,
2974
+ },
2975
+ ],
2976
+ opCode: OPCODES.BaseInterface_OP_INITIALIZE,
2977
+ md: emptyObject,
2978
+ balanceRefill: toNano('1'),
2979
+ })
2980
+
2981
+ return [smlManager, internalMsgResults]
2982
+ }
2983
+
2984
+ export async function openAndDeploySmlConnection(
2985
+ blockchain: Blockchain,
2986
+ allStorages: SandboxContract<TonContractWrapper>,
2987
+ srcFixture: OAppFixture,
2988
+ dstFixture: OAppFixture,
2989
+ smlManager: SandboxContract<TonContractWrapper>
2990
+ ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
2991
+ const smlConnection: SandboxContract<TonContractWrapper> = blockchain.openContract(
2992
+ TonContractWrapper.create(
2993
+ cellFromArtifact(SmlConnectionArtifact),
2994
+ await allStorages.getNewSmlConnection({
2995
+ owner: addressToBigInt(smlManager.address),
2996
+ path: srcFixture.path,
2997
+ })
2998
+ )
2999
+ )
3000
+
3001
+ const internalMsgResults = await sendInternalMessageAndExpect({
3002
+ value: toNano('10'),
3003
+ sender: srcFixture.owner.getSender(),
3004
+ contract: srcFixture.oApp,
3005
+ opCode: OPCODES.OP_DeployConnection,
3006
+ md: await allStorages.getNewMdMdAddress({
3007
+ md: await allStorages.getNewMdDeploy({
3008
+ dstEid: dstFixture.eid,
3009
+ dstOApp: addressToBigInt(dstFixture.oApp.address),
3010
+ initialDeposit: toNano('1'),
3011
+ }),
3012
+ address: addressToBigInt(smlManager.address),
3013
+ }),
3014
+ expectedTransactions: [
3015
+ {
3016
+ from: srcFixture.owner.address,
3017
+ to: srcFixture.oApp.address,
3018
+ op: Number(OPCODES.OP_DeployConnection),
3019
+ success: true,
3020
+ },
3021
+ {
3022
+ from: srcFixture.oApp.address,
3023
+ to: smlManager.address,
3024
+ op: Number(OPCODES.MsglibManager_OP_DEPLOY_CONNECTION),
3025
+ success: true,
3026
+ },
3027
+ {
3028
+ from: smlManager.address,
3029
+ to: smlConnection.address,
3030
+ op: Number(OPCODES.BaseInterface_OP_INITIALIZE),
3031
+ deploy: true,
3032
+ success: true,
3033
+ },
3034
+ ],
3035
+ })
3036
+
3037
+ return [smlConnection, internalMsgResults]
3038
+ }
3039
+
3040
+ export async function deployConfigAndRegisterSml(
3041
+ blockchain: Blockchain,
3042
+ multiSigners: SandboxContract<TreasuryContract>[],
3043
+ allStorages: SandboxContract<TonContractWrapper>,
3044
+ srcFixture: OAppFixture,
3045
+ dstFixture: OAppFixture,
3046
+ version: bigint,
3047
+ nativeFee: bigint,
3048
+ zroFee: bigint,
3049
+ eventHandler: LzEventHandler
3050
+ ): Promise<[SandboxContract<TonContractWrapper>, SandboxContract<TonContractWrapper>]> {
3051
+ // ===================================open and deploy sml manager =====================================
3052
+ const [msglibManager, internalMsgResults_1] = await openAndDeploySmlManager(
3053
+ blockchain,
3054
+ allStorages,
3055
+ srcFixture,
3056
+ version
3057
+ )
3058
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults_1, msglibManager)
3059
+
3060
+ // ===================================open and deploy sml connection =====================================
3061
+ const [msglibConnection, internalMsgResults_2] = await openAndDeploySmlConnection(
3062
+ blockchain,
3063
+ allStorages,
3064
+ srcFixture,
3065
+ dstFixture,
3066
+ msglibManager
3067
+ )
3068
+
3069
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults_2, srcFixture.oApp)
3070
+
3071
+ // ===================================configure sml =====================================
3072
+
3073
+ const set_sml_config_md = await msglibManager.getNewMdSetSmlManagerConfig({
3074
+ nativeFee,
3075
+ zroFee,
3076
+ })
3077
+
3078
+ const set_sml_config_extended_md = await msglibManager.getNewMdExtendedMd({
3079
+ md: set_sml_config_md,
3080
+ obj: emptyObject,
3081
+ forwardingAddress: BigInt(0),
3082
+ })
3083
+
3084
+ let internalMsgResults: SendMessageResult = await msglibManager.sendInternalMessage(
3085
+ srcFixture.owner.getSender(),
3086
+ OPCODES.SmlManager_OP_SET_MSGLIB_CONFIG,
3087
+ set_sml_config_extended_md,
3088
+ { value: protocolSetupGas['Msglib.SET_MSGLIB_CONFIG'] }
3089
+ )
3090
+
3091
+ // emits 1 event
3092
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, msglibManager)
3093
+
3094
+ internalMsgResults = await addMsgLibToController(blockchain, multiSigners, srcFixture, dstFixture, msglibManager)
3095
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
3096
+
3097
+ return [msglibManager, msglibConnection]
3098
+ }
3099
+
3100
+ export async function wireFixtureWithSML(
3101
+ blockchain: Blockchain,
3102
+ allStorages: SandboxContract<TonContractWrapper>,
3103
+ multiSigners: SandboxContract<TreasuryContract>[],
3104
+ srcFixture: OAppFixture,
3105
+ dstFixture: OAppFixture,
3106
+ customNativeFee: bigint = toNano('0'),
3107
+ customZroFee: bigint = toNano('0.000000050'),
3108
+ defaultNativeFee: bigint = toNano('0.000000100'),
3109
+ defaultZroFee: bigint = toNano('0'),
3110
+ eventHandler: LzEventHandler
3111
+ ): Promise<void> {
3112
+ // ===================================wire channels=====================================
3113
+
3114
+ await wireChannels(blockchain, allStorages, srcFixture, dstFixture, eventHandler)
3115
+
3116
+ // ===================================deploy and configure sml custom=====================================
3117
+ ;[srcFixture.msglibManagerCustom, srcFixture.msglibConnectionCustom] = await deployConfigAndRegisterSml(
3118
+ blockchain,
3119
+ multiSigners,
3120
+ allStorages,
3121
+ srcFixture,
3122
+ dstFixture,
3123
+ SML_MANAGER_CUSTOM_VERSION,
3124
+ customNativeFee,
3125
+ customZroFee,
3126
+ eventHandler
3127
+ )
3128
+
3129
+ // ===================================deploy and configure sml default=====================================
3130
+ ;[srcFixture.msglibManager, srcFixture.msglibConnection] = await deployConfigAndRegisterSml(
3131
+ blockchain,
3132
+ multiSigners,
3133
+ allStorages,
3134
+ srcFixture,
3135
+ dstFixture,
3136
+ SML_MANAGER_DEFAULT_VERSION,
3137
+ defaultNativeFee,
3138
+ defaultZroFee,
3139
+ eventHandler
3140
+ )
3141
+
3142
+ // ===================================set default endpoint config=====================================
3143
+
3144
+ const internalMsgResults = await setDefaultEndpointConfig(
3145
+ blockchain,
3146
+ allStorages,
3147
+ multiSigners,
3148
+ srcFixture.msglibManager,
3149
+ srcFixture.msglibManager,
3150
+ srcFixture,
3151
+ dstFixture
3152
+ )
3153
+
3154
+ // in SML, the connection is the Msglib
3155
+ srcFixture.msglib = new Map()
3156
+ srcFixture.msglib.set(srcFixture.eid, srcFixture.msglibConnection)
3157
+
3158
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
3159
+ expect(eventHandler.allFailures.txList).toHaveLength(0)
3160
+ }
3161
+
3162
+ export async function wireFixturesTogetherWithSML(
3163
+ blockchain: Blockchain,
3164
+ allStorages: SandboxContract<TonContractWrapper>,
3165
+ multiSigners: SandboxContract<TreasuryContract>[],
3166
+ srcFixture: OAppFixture,
3167
+ dstFixture: OAppFixture,
3168
+ customNativeFee: bigint = toNano('0'),
3169
+ customZroFee: bigint = toNano('0.000000050'),
3170
+ defaultNativeFee: bigint = toNano('0.000000100'),
3171
+ defaultZroFee: bigint = toNano('0'),
3172
+ eventHandler: LzEventHandler
3173
+ ): Promise<void> {
3174
+ await wireFixtureWithSML(
3175
+ blockchain,
3176
+ allStorages,
3177
+ multiSigners,
3178
+ srcFixture,
3179
+ dstFixture,
3180
+ customNativeFee,
3181
+ customZroFee,
3182
+ defaultNativeFee,
3183
+ defaultZroFee,
3184
+ eventHandler
3185
+ )
3186
+ await wireFixtureWithSML(
3187
+ blockchain,
3188
+ allStorages,
3189
+ multiSigners,
3190
+ dstFixture,
3191
+ srcFixture,
3192
+ customNativeFee,
3193
+ customZroFee,
3194
+ defaultNativeFee,
3195
+ defaultZroFee,
3196
+ eventHandler
3197
+ )
3198
+ }
3199
+ `;
3200
+ fs__default.writeFileSync(path__default.join(directory, filename), savedCode);
3201
+ }
3202
+ function generateUlnTestUtils(directory, filename) {
3203
+ const savedCode = `import { Address, Cell, TupleItemCell, beginCell, toNano } from '@ton/core'
3204
+ import { Blockchain, SandboxContract, SendMessageResult, TreasuryContract } from '@ton/sandbox'
3205
+ import { FlatTransactionComparable } from '@ton/test-utils'
3206
+ import { ethers } from 'ethers'
3207
+
3208
+ import ChannelArtifact from '@layerzerolabs/layerzero-v2-ton/build/Channel.compiled.json'
3209
+ import DvnArtifact from '@layerzerolabs/layerzero-v2-ton/build/Dvn.compiled.json'
3210
+ import DvnFeelibArtifact from '@layerzerolabs/layerzero-v2-ton/build/DvnFeeLib.compiled.json'
3211
+ import EndpointArtifact from '@layerzerolabs/layerzero-v2-ton/build/Endpoint.compiled.json'
3212
+ import ExecutorArtifact from '@layerzerolabs/layerzero-v2-ton/build/Executor.compiled.json'
3213
+ import ExecutorFeelibArtifact from '@layerzerolabs/layerzero-v2-ton/build/ExecutorFeeLib.compiled.json'
3214
+ import PriceFeedCacheArtifact from '@layerzerolabs/layerzero-v2-ton/build/PriceFeedCache.compiled.json'
3215
+ import PriceFeedFeeLibDefaultArtifact from '@layerzerolabs/layerzero-v2-ton/build/PriceFeedFeeLibDefault.compiled.json'
3216
+ import ProxyArtifact from '@layerzerolabs/layerzero-v2-ton/build/Proxy.compiled.json'
3217
+ import UlnArtifact from '@layerzerolabs/layerzero-v2-ton/build/Uln.compiled.json'
3218
+ import UlnConnectionArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnConnection.compiled.json'
3219
+ import UlnManagerArtifact from '@layerzerolabs/layerzero-v2-ton/build/UlnManager.compiled.json'
3220
+ import { Profile, addressToBigInt, cellFromArtifact } from '@layerzerolabs/ton-sdk-tools'
3221
+
3222
+ import {
3223
+ OAppFixture,
3224
+ OAppFlowGas,
3225
+ ProtocolFixture,
3226
+ SIGNATURE_BYTE_LENGTH,
3227
+ addMsgLibToController,
3228
+ createLzPacketFromPacketEncoded,
3229
+ createVerifierDictSet,
3230
+ emptyObject,
3231
+ generateRandomVerifierSet,
3232
+ protocolSetupGas,
3233
+ publicKeyToHash,
3234
+ requireDefined,
3235
+ sendInternalMessageAndExpect,
3236
+ sendMessageViaMultisigAndExpect,
3237
+ serializeAddressList,
3238
+ setDefaultEndpointConfig,
3239
+ wireChannels,
3240
+ } from './auto-utils-common'
3241
+ import {
3242
+ ExtendedContract,
3243
+ LzDict,
3244
+ LzEventHandler,
3245
+ MdPacketSent,
3246
+ OPCODES,
3247
+ TonContractWrapper,
3248
+ TonObjectUnwrapper,
3249
+ } from '../../src'
3250
+
3251
+ const ULN_MANAGER_DEFAULT_VERSION = BigInt(1)
3252
+
3253
+ export const TRUE = BigInt(-1)
3254
+ export const FALSE = BigInt(0)
3255
+ export const UlnConnectionVerificationStatusVerifying = BigInt(0)
3256
+ export const UlnConnectionVerificationStatusCommittable = BigInt(1)
3257
+ export const ChannelExecutionStatusExecutable = BigInt(2)
3258
+
3259
+ export interface SendUlnConfig {
3260
+ workerQuoteGasLimit: bigint
3261
+ maxMessageBytes: bigint
3262
+ }
3231
3263
 
3232
3264
  export interface ReceiveUlnConfig {
3233
3265
  minCommitPacketGas: bigint
@@ -3288,7 +3320,7 @@ export interface ProtocolFixtureULN extends ProtocolFixture {
3288
3320
  receiveDvnFixtures: DvnFixture[]
3289
3321
  receiveDvnFixturesCustom: DvnFixture[]
3290
3322
  executorFixtures: ExecutorFixture
3291
- priceFeedCacheFixture: PricedfeedCacheFixture
3323
+ priceFeedCacheFixtures: Map<bigint, PricedfeedCacheFixture>
3292
3324
  defaultUlnSendConfig: Cell
3293
3325
  defaultUlnReceiveConfig: Cell
3294
3326
  }
@@ -3335,14 +3367,16 @@ export async function commitVerificationAndExpect(
3335
3367
  msglibConnection: ulnConnection,
3336
3368
  controller,
3337
3369
  }: OAppFixture,
3370
+ dstEid: bigint,
3338
3371
  profile?: Profile
3339
3372
  ): Promise<void> {
3340
- requireDefined(uln)
3373
+ const msglib = uln.get(dstEid)
3374
+ requireDefined(msglib)
3341
3375
  const internalMsgResults: SendMessageResult = await sendInternalMessageAndExpect({
3342
3376
  profile,
3343
3377
  value: OAppFlowGas['Msglib.COMMIT_PACKET'],
3344
3378
  sender: deployer.getSender(),
3345
- contract: uln,
3379
+ contract: msglib,
3346
3380
  opCode: OPCODES.Uln_OP_ULN_COMMIT_PACKET,
3347
3381
  md: await ulnManager.getNewMdMdAddress({
3348
3382
  md: lzPacketCell,
@@ -3351,12 +3385,12 @@ export async function commitVerificationAndExpect(
3351
3385
  expectedTransactions: [
3352
3386
  {
3353
3387
  from: deployer.address,
3354
- to: uln.address,
3388
+ to: msglib.address,
3355
3389
  op: Number(OPCODES.Uln_OP_ULN_COMMIT_PACKET),
3356
3390
  success: true,
3357
3391
  },
3358
3392
  {
3359
- from: uln.address,
3393
+ from: msglib.address,
3360
3394
  to: ulnConnection.address,
3361
3395
  op: Number(OPCODES.UlnConnection_OP_ULN_CONNECTION_COMMIT_PACKET),
3362
3396
  success: true,
@@ -3429,7 +3463,8 @@ export async function addDvnWorkers(
3429
3463
  ): Promise<void> {
3430
3464
  requireDefined(sendDvnFixtures)
3431
3465
  requireDefined(receiveDvnFixtures)
3432
- requireDefined(uln)
3466
+ const msglib = uln.get(dstEid)
3467
+ requireDefined(msglib)
3433
3468
  for (const dvnFixture of [...sendDvnFixtures, ...receiveDvnFixtures]) {
3434
3469
  const dvnWorkerCallMd = await allStorages.getNewMdExecuteParams({
3435
3470
  target: addressToBigInt(msglibManager.address),
@@ -3473,13 +3508,13 @@ export async function addDvnWorkers(
3473
3508
  },
3474
3509
  {
3475
3510
  from: msglibManager.address,
3476
- to: uln.address,
3511
+ to: msglib.address,
3477
3512
  success: true,
3478
3513
  op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
3479
3514
  },
3480
3515
  // emit event Uln::EVENT::ULN_WORKER_REGISTERED
3481
3516
  {
3482
- from: uln.address,
3517
+ from: msglib.address,
3483
3518
  to: msglibManager.address,
3484
3519
  op: Number(OPCODES.BaseInterface_OP_EVENT),
3485
3520
  success: false, // events are supposed to fail
@@ -3511,7 +3546,7 @@ export async function openAndDeployUln(
3511
3546
  multiSigners: SandboxContract<TreasuryContract>[],
3512
3547
  deployMd: Cell,
3513
3548
  srcFixture: OAppFixture,
3514
- dstFixture: OAppFixture
3549
+ dstEid: bigint
3515
3550
  ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
3516
3551
  const uln: SandboxContract<TonContractWrapper> = blockchain.openContract(
3517
3552
  TonContractWrapper.create(
@@ -3519,7 +3554,7 @@ export async function openAndDeployUln(
3519
3554
  await allStorages.getNewUln({
3520
3555
  owner: addressToBigInt(srcFixture.msglibManager.address),
3521
3556
  eid: srcFixture.eid,
3522
- dstEid: dstFixture.eid,
3557
+ dstEid,
3523
3558
  })
3524
3559
  )
3525
3560
  )
@@ -3558,6 +3593,13 @@ export async function openAndDeployUln(
3558
3593
  ],
3559
3594
  })
3560
3595
 
3596
+ requireDefined(uln)
3597
+ // Initialize Map if it doesn't exist , otherwise preserve existing entries
3598
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
3599
+ if (srcFixture.msglib == undefined) {
3600
+ srcFixture.msglib = new Map()
3601
+ }
3602
+ srcFixture.msglib.set(dstEid, uln)
3561
3603
  return [uln, internalMsgResults]
3562
3604
  }
3563
3605
 
@@ -3613,13 +3655,15 @@ export async function openAndDeployUlnConnection(
3613
3655
  srcFixture: OAppFixtureULN,
3614
3656
  dstFixture: OAppFixtureULN
3615
3657
  ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
3658
+ const msglib = srcFixture.msglib.get(dstFixture.eid)
3659
+ requireDefined(msglib)
3616
3660
  const ulnConnection: SandboxContract<TonContractWrapper> = blockchain.openContract(
3617
3661
  TonContractWrapper.create(
3618
3662
  cellFromArtifact(UlnConnectionArtifact),
3619
3663
  await allStorages.getNewUlnConnection({
3620
3664
  owner: addressToBigInt(srcFixture.msglibManager.address),
3621
3665
  path: srcFixture.path,
3622
- ulnAddress: addressToBigInt(srcFixture.msglib.address),
3666
+ ulnAddress: addressToBigInt(msglib.address),
3623
3667
  })
3624
3668
  )
3625
3669
  )
@@ -3711,7 +3755,7 @@ export async function openAndDeployProxyWorker(
3711
3755
  TonContractWrapper.create(
3712
3756
  cellFromArtifact(ProxyArtifact),
3713
3757
  await allStorages.getNewProxy({
3714
- admins: serializeAddressList([worker]),
3758
+ admins: serializeAddressList([srcFixture.owner, worker]),
3715
3759
  version: 0n,
3716
3760
  })
3717
3761
  )
@@ -3804,7 +3848,7 @@ export async function openAndDeployPriceFeedCacheAndProxy(
3804
3848
  blockchain: Blockchain,
3805
3849
  allStorages: SandboxContract<TonContractWrapper>,
3806
3850
  srcFixture: OAppFixture,
3807
- dstFixture: OAppFixture,
3851
+ dstEid: bigint,
3808
3852
  adminSet: SandboxContract<TreasuryContract>[]
3809
3853
  ): Promise<[SandboxContract<TonContractWrapper>, SandboxContract<TonContractWrapper>, SendMessageResult]> {
3810
3854
  // todo: fix this with real values
@@ -3815,7 +3859,7 @@ export async function openAndDeployPriceFeedCacheAndProxy(
3815
3859
  // owner: addressToBigInt(srcFixture.multisig.address),
3816
3860
  admins: serializeAddressList(adminSet),
3817
3861
  version: 0n,
3818
- dstEid: dstFixture.eid,
3862
+ dstEid,
3819
3863
  priceFeedFeeLib: await allStorages.getNewPriceFeedFeelib({
3820
3864
  priceRatio: BigInt(1851851),
3821
3865
  gasPriceInRemoteUnit: BigInt(36000000000),
@@ -3973,14 +4017,19 @@ export async function deployConfigAndRegisterUln(
3973
4017
  blockchain,
3974
4018
  allStorages,
3975
4019
  srcFixture,
3976
- dstFixture,
4020
+ dstFixture.eid,
3977
4021
  priceFeedCacheAdmins
3978
4022
  )
3979
- srcFixture.priceFeedCacheFixture = {
3980
- priceFeedCache,
3981
- proxy: priceFeedCacheProxy,
3982
- admins: priceFeedCacheAdmins,
3983
- }
4023
+ srcFixture.priceFeedCacheFixtures = new Map([
4024
+ [
4025
+ dstFixture.eid,
4026
+ {
4027
+ priceFeedCache,
4028
+ proxy: priceFeedCacheProxy,
4029
+ admins: priceFeedCacheAdmins,
4030
+ },
4031
+ ],
4032
+ ])
3984
4033
  await eventHandler.addCurrentEventsToAllEvents(priceFeedCacheMsgResults, priceFeedCache)
3985
4034
 
3986
4035
  // ===================================registerUlnWorkerInfo - dvnFeeLib=======================================
@@ -4035,21 +4084,329 @@ export async function deployConfigAndRegisterUln(
4035
4084
  }),
4036
4085
  }),
4037
4086
  srcFixture,
4038
- dstFixture
4087
+ dstFixture.eid
4039
4088
  )
4040
4089
  requireDefined(uln)
4041
- srcFixture.msglib = uln
4042
- await eventHandler.addCurrentEventsToAllEvents(ulnMsgResults, srcFixture.msglib)
4090
+ // Initialize Map if it doesn't exist, otherwise preserve existing entries
4091
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
4092
+ if (srcFixture.msglib === undefined) {
4093
+ srcFixture.msglib = new Map()
4094
+ }
4095
+ srcFixture.msglib.set(dstFixture.eid, uln)
4096
+ await eventHandler.addCurrentEventsToAllEvents(ulnMsgResults, uln)
4043
4097
 
4044
4098
  // ===================================addUlnWorker - dvn =======================================
4045
4099
 
4100
+ const priceFeedCacheFixture = srcFixture.priceFeedCacheFixtures.get(dstFixture.eid)
4101
+ requireDefined(priceFeedCacheFixture)
4046
4102
  await addDvnWorkers(
4047
4103
  allStorages,
4048
4104
  srcFixture,
4049
4105
  srcFixture.sendDvnFixtures,
4050
4106
  srcFixture.receiveDvnFixtures,
4051
4107
  dstFixture.eid,
4052
- priceFeedCacheProxy.address,
4108
+ priceFeedCacheFixture.proxy.address,
4109
+ eventHandler
4110
+ )
4111
+
4112
+ // ===================================addUlnWorker - executor =======================================
4113
+
4114
+ const executorWorkerCallMd = await allStorages.getNewMdExecuteParams({
4115
+ target: addressToBigInt(srcFixture.msglibManager.address),
4116
+ callData: await allStorages.getNewUlnWorkerFeelibInfo({
4117
+ workerAddress: addressToBigInt(executor.address),
4118
+ workerFeelibBytecode: cellFromArtifact(ExecutorFeelibArtifact),
4119
+ workerFeelibStorage: await allStorages.getNewExecutorFeelib({
4120
+ lzReceiveBaseGas: BigInt(0),
4121
+ multiplierBps: BigInt(0),
4122
+ floorMarginUSD: BigInt(0),
4123
+ nativeCap: BigInt(0),
4124
+ lzComposeBaseGas: BigInt(0),
4125
+ }),
4126
+ friendWorkerAddress: addressToBigInt(priceFeedCacheProxy.address),
4127
+ dstEid: dstFixture.eid,
4128
+ rentBalance: toNano('260'),
4129
+ isAdmin: BigInt(0),
4130
+ }),
4131
+ expiration: BigInt(0),
4132
+ opcode: OPCODES.UlnManager_OP_ADD_ULN_WORKER,
4133
+ forwardingAddress: 0n,
4134
+ })
4135
+ const msglib = srcFixture.msglib.get(dstFixture.eid)
4136
+ requireDefined(msglib)
4137
+
4138
+ internalMsgResults = await addUlnWorker(srcFixture.executorFixtures.admins[0], executor, executorWorkerCallMd, [
4139
+ {
4140
+ from: srcFixture.executorFixtures.admins[0].address,
4141
+ to: executor.address,
4142
+ op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4143
+ success: true,
4144
+ },
4145
+ {
4146
+ from: executor.address,
4147
+ to: srcFixture.executorFixtures.proxy.address,
4148
+ op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4149
+ success: true,
4150
+ },
4151
+ {
4152
+ from: srcFixture.executorFixtures.proxy.address,
4153
+ to: srcFixture.msglibManager.address,
4154
+ op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4155
+ success: true,
4156
+ },
4157
+ {
4158
+ from: srcFixture.msglibManager.address,
4159
+ to: msglib.address,
4160
+ success: true,
4161
+ op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4162
+ },
4163
+ // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4164
+ {
4165
+ from: msglib.address,
4166
+ to: srcFixture.msglibManager.address,
4167
+ op: Number(OPCODES.BaseInterface_OP_EVENT),
4168
+ success: false, // events are supposed to fail
4169
+ },
4170
+ ])
4171
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.msglibManager)
4172
+
4173
+ // ===================================addUlnWorker - priceFeedCache =======================================
4174
+
4175
+ const priceFeedCacheWorkerCallMd = await allStorages.getNewMdExecuteParams({
4176
+ target: addressToBigInt(srcFixture.msglibManager.address),
4177
+ callData: await allStorages.getNewUlnWorkerFeelibInfo({
4178
+ workerAddress: addressToBigInt(priceFeedCacheProxy.address),
4179
+ workerFeelibBytecode: cellFromArtifact(PriceFeedFeeLibDefaultArtifact),
4180
+ workerFeelibStorage: await allStorages.getNewPriceFeedFeelib({
4181
+ // priceRatio: BigInt(0),
4182
+ // gasPriceInUnit: BigInt(0),
4183
+ // gasPerByte: BigInt(0),
4184
+ // nativePriceUsd: BigInt(0),
4185
+ priceRatio: BigInt(1851851),
4186
+ gasPriceInRemoteUnit: BigInt(36000000000),
4187
+ gasPerByte: BigInt(1000),
4188
+ nativePriceUsd: BigInt(1),
4189
+ arbitrumExtension: beginCell().endCell(),
4190
+ optimismExtension: beginCell().endCell(),
4191
+ }),
4192
+ friendWorkerAddress: BigInt(0),
4193
+ dstEid: dstFixture.eid,
4194
+ rentBalance: toNano('260'),
4195
+ isAdmin: BigInt(0),
4196
+ }),
4197
+ expiration: BigInt(0),
4198
+ opcode: OPCODES.UlnManager_OP_ADD_ULN_WORKER,
4199
+ forwardingAddress: 0n,
4200
+ })
4201
+
4202
+ internalMsgResults = await addUlnWorker(
4203
+ priceFeedCacheFixture.admins[0],
4204
+ priceFeedCache,
4205
+ priceFeedCacheWorkerCallMd,
4206
+ [
4207
+ {
4208
+ from: priceFeedCacheFixture.admins[0].address,
4209
+ to: priceFeedCache.address,
4210
+ op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4211
+ success: true,
4212
+ },
4213
+ {
4214
+ from: priceFeedCache.address,
4215
+ to: priceFeedCacheProxy.address,
4216
+ op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4217
+ success: true,
4218
+ },
4219
+ {
4220
+ from: priceFeedCacheProxy.address,
4221
+ to: srcFixture.msglibManager.address,
4222
+ op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4223
+ success: true,
4224
+ },
4225
+ {
4226
+ from: srcFixture.msglibManager.address,
4227
+ to: msglib.address,
4228
+ success: true,
4229
+ op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4230
+ },
4231
+ // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4232
+ {
4233
+ from: msglib.address,
4234
+ to: srcFixture.msglibManager.address,
4235
+ op: Number(OPCODES.BaseInterface_OP_EVENT),
4236
+ success: false, // events are supposed to fail
4237
+ },
4238
+ ]
4239
+ )
4240
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.msglibManager)
4241
+
4242
+ // ===================================configure default send and receive config =====================================
4243
+
4244
+ // requireDefined(srcFixture.dvnFixtures)
4245
+ // const [reqDvns, optDvns, optThreshold] = getDvnArrayFromDvnFixtures(srcFixture.dvnFixtures, dvnConfig)
4246
+ requireDefined(srcFixture.sendDvnFixtures)
4247
+ const [reqSendDvns, optSendDvns] = getDvnArrayFromDvnFixtures(srcFixture.sendDvnFixtures, dvnConfigs.send)
4248
+
4249
+ const ulnSendConfig = await allStorages.getNewUlnSendConfig({
4250
+ workerQuoteGasLimit: ulnConfigs.send.workerQuoteGasLimit,
4251
+ maxMessageBytes: ulnConfigs.send.maxMessageBytes,
4252
+ executorNull: BigInt(0),
4253
+ executor: addressToBigInt(executorProxy.address),
4254
+ requiredDVNsNull: BigInt(0),
4255
+ requiredDVNs: serializeDvns(reqSendDvns),
4256
+ optionalDVNsNull: BigInt(0),
4257
+ optionalDVNs: serializeDvns(optSendDvns),
4258
+ confirmationsNull: BigInt(0),
4259
+ confirmations: BigInt(1),
4260
+ })
4261
+
4262
+ srcFixture.defaultUlnSendConfig = ulnSendConfig
4263
+
4264
+ await sendMessageViaMultisigAndExpect({
4265
+ blockchain,
4266
+ multiSigContract: srcFixture.multisig,
4267
+ messageBody: allStorages.buildRequest(
4268
+ OPCODES.UlnManager_OP_SET_DEFAULT_ULN_SEND_CONFIG,
4269
+ await allStorages.getNewMdMdEid({
4270
+ md: ulnSendConfig,
4271
+ eid: dstFixture.eid,
4272
+ }),
4273
+ { value: toNano('10') },
4274
+ toNano('0.1')
4275
+ ).body!,
4276
+ signers: multiSigners,
4277
+ targetContract: srcFixture.msglibManager,
4278
+ deploy: false,
4279
+ expectedTransactions: [
4280
+ {
4281
+ from: srcFixture.multisig.address,
4282
+ to: srcFixture.msglibManager.address,
4283
+ success: true,
4284
+ op: Number(OPCODES.UlnManager_OP_SET_DEFAULT_ULN_SEND_CONFIG),
4285
+ },
4286
+ {
4287
+ from: srcFixture.msglibManager.address,
4288
+ to: msglib.address,
4289
+ success: true,
4290
+ op: Number(OPCODES.Uln_OP_SET_DEFAULT_ULN_SEND_CONFIG),
4291
+ },
4292
+ ],
4293
+ })
4294
+
4295
+ requireDefined(srcFixture.receiveDvnFixtures)
4296
+ const [reqReceiveDvns, optReceiveDvns, optReceiveQuorum] = getDvnArrayFromDvnFixtures(
4297
+ srcFixture.receiveDvnFixtures,
4298
+ dvnConfigs.receive
4299
+ )
4300
+
4301
+ const ulnReceiveConfig = await allStorages.getNewUlnReceiveConfig({
4302
+ minCommitPacketGasNull: BigInt(0),
4303
+ minCommitPacketGas: ulnConfigs.receive.minCommitPacketGas,
4304
+ confirmationsNull: BigInt(0),
4305
+ confirmations: BigInt(1),
4306
+ requiredDVNsNull: BigInt(0),
4307
+ requiredDVNs: serializeDvns(reqReceiveDvns),
4308
+ optionalDVNsNull: BigInt(0),
4309
+ optionalDVNs: serializeDvns(optReceiveDvns),
4310
+ optionalDVNThreshold: BigInt(optReceiveQuorum),
4311
+ })
4312
+
4313
+ srcFixture.defaultUlnReceiveConfig = ulnReceiveConfig
4314
+
4315
+ await sendMessageViaMultisigAndExpect({
4316
+ blockchain,
4317
+ multiSigContract: srcFixture.multisig,
4318
+ messageBody: allStorages.buildRequest(
4319
+ OPCODES.UlnManager_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG,
4320
+ await allStorages.getNewMdMdEid({
4321
+ md: ulnReceiveConfig,
4322
+ eid: dstFixture.eid,
4323
+ }),
4324
+ { value: toNano('10') },
4325
+ toNano('0.1')
4326
+ ).body!,
4327
+ signers: multiSigners,
4328
+ targetContract: srcFixture.msglibManager,
4329
+ deploy: false,
4330
+ expectedTransactions: [
4331
+ {
4332
+ from: srcFixture.multisig.address,
4333
+ to: srcFixture.msglibManager.address,
4334
+ success: true,
4335
+ op: Number(OPCODES.UlnManager_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG),
4336
+ },
4337
+ {
4338
+ from: srcFixture.msglibManager.address,
4339
+ to: msglib.address,
4340
+ success: true,
4341
+ op: Number(OPCODES.Uln_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG),
4342
+ },
4343
+ ],
4344
+ })
4345
+
4346
+ return msglibManager
4347
+ }
4348
+
4349
+ export async function deployAndRegisterNewUln(
4350
+ blockchain: Blockchain,
4351
+ multiSigners: SandboxContract<TreasuryContract>[],
4352
+ allStorages: SandboxContract<TonContractWrapper>,
4353
+ srcFixture: OAppFixtureULN,
4354
+ priceFeedFeeLib: Cell,
4355
+ dstEid: bigint,
4356
+ dstOApp: SandboxContract<TonContractWrapper>,
4357
+ existingDstEid: bigint,
4358
+ eventHandler: LzEventHandler
4359
+ ): Promise<void> {
4360
+ // ===================================open and deploy PriceFeedCache & Proxy=======================
4361
+
4362
+ const priceFeedCacheAdmins = [srcFixture.owner]
4363
+ const existingPriceFeedCacheFixture = srcFixture.priceFeedCacheFixtures.get(existingDstEid)
4364
+ requireDefined(existingPriceFeedCacheFixture)
4365
+ const currentAdminsWorkers = [existingPriceFeedCacheFixture.priceFeedCache]
4366
+
4367
+ await registerAdditionalPriceFeedCache(
4368
+ blockchain,
4369
+ allStorages,
4370
+ srcFixture,
4371
+ dstEid,
4372
+ priceFeedCacheAdmins,
4373
+ existingPriceFeedCacheFixture.proxy,
4374
+ priceFeedFeeLib,
4375
+ currentAdminsWorkers
4376
+ )
4377
+
4378
+ // ===================================open and deploy uln =============================================
4379
+
4380
+ const [uln, ulnMsgResults] = await openAndDeployUln(
4381
+ blockchain,
4382
+ allStorages,
4383
+ multiSigners,
4384
+ await allStorages.getNewMdDeployNewWithExtraInfo({
4385
+ initialDeposit: toNano('2'),
4386
+ dstEid,
4387
+ dstOApp: addressToBigInt(dstOApp.address),
4388
+ extraInfo: await allStorages.getNewMdInitUln({
4389
+ connectionCode: beginCell().endCell(),
4390
+ treasuryFeeBps: 100n, // 100bps todo: turn this into a constant
4391
+ }),
4392
+ }),
4393
+ srcFixture,
4394
+ dstEid
4395
+ )
4396
+ srcFixture.msglib.set(dstEid, uln)
4397
+ await eventHandler.addCurrentEventsToAllEvents(ulnMsgResults, uln)
4398
+
4399
+ // ===================================addUlnWorker - dvn =======================================
4400
+
4401
+ const priceFeedCacheFixture = srcFixture.priceFeedCacheFixtures.get(dstEid)
4402
+ requireDefined(priceFeedCacheFixture)
4403
+ await addDvnWorkers(
4404
+ allStorages,
4405
+ srcFixture,
4406
+ srcFixture.sendDvnFixtures,
4407
+ srcFixture.receiveDvnFixtures,
4408
+ dstEid,
4409
+ priceFeedCacheFixture.proxy.address,
4053
4410
  eventHandler
4054
4411
  )
4055
4412
 
@@ -4058,7 +4415,7 @@ export async function deployConfigAndRegisterUln(
4058
4415
  const executorWorkerCallMd = await allStorages.getNewMdExecuteParams({
4059
4416
  target: addressToBigInt(srcFixture.msglibManager.address),
4060
4417
  callData: await allStorages.getNewUlnWorkerFeelibInfo({
4061
- workerAddress: addressToBigInt(executor.address),
4418
+ workerAddress: addressToBigInt(srcFixture.executorFixtures.executor.address),
4062
4419
  workerFeelibBytecode: cellFromArtifact(ExecutorFeelibArtifact),
4063
4420
  workerFeelibStorage: await allStorages.getNewExecutorFeelib({
4064
4421
  lzReceiveBaseGas: BigInt(0),
@@ -4067,8 +4424,8 @@ export async function deployConfigAndRegisterUln(
4067
4424
  nativeCap: BigInt(0),
4068
4425
  lzComposeBaseGas: BigInt(0),
4069
4426
  }),
4070
- friendWorkerAddress: addressToBigInt(priceFeedCacheProxy.address),
4071
- dstEid: dstFixture.eid,
4427
+ friendWorkerAddress: addressToBigInt(existingPriceFeedCacheFixture.proxy.address),
4428
+ dstEid: dstEid,
4072
4429
  rentBalance: toNano('260'),
4073
4430
  isAdmin: BigInt(0),
4074
4431
  }),
@@ -4076,40 +4433,47 @@ export async function deployConfigAndRegisterUln(
4076
4433
  opcode: OPCODES.UlnManager_OP_ADD_ULN_WORKER,
4077
4434
  forwardingAddress: 0n,
4078
4435
  })
4436
+ const msglib = srcFixture.msglib.get(dstEid)
4437
+ requireDefined(msglib)
4079
4438
 
4080
- internalMsgResults = await addUlnWorker(srcFixture.executorFixtures.admins[0], executor, executorWorkerCallMd, [
4081
- {
4082
- from: srcFixture.executorFixtures.admins[0].address,
4083
- to: executor.address,
4084
- op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4085
- success: true,
4086
- },
4087
- {
4088
- from: executor.address,
4089
- to: srcFixture.executorFixtures.proxy.address,
4090
- op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4091
- success: true,
4092
- },
4093
- {
4094
- from: srcFixture.executorFixtures.proxy.address,
4095
- to: srcFixture.msglibManager.address,
4096
- op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4097
- success: true,
4098
- },
4099
- {
4100
- from: srcFixture.msglibManager.address,
4101
- to: srcFixture.msglib.address,
4102
- success: true,
4103
- op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4104
- },
4105
- // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4106
- {
4107
- from: srcFixture.msglib.address,
4108
- to: srcFixture.msglibManager.address,
4109
- op: Number(OPCODES.BaseInterface_OP_EVENT),
4110
- success: false, // events are supposed to fail
4111
- },
4112
- ])
4439
+ let internalMsgResults = await addUlnWorker(
4440
+ srcFixture.executorFixtures.admins[0],
4441
+ srcFixture.executorFixtures.executor,
4442
+ executorWorkerCallMd,
4443
+ [
4444
+ {
4445
+ from: srcFixture.executorFixtures.admins[0].address,
4446
+ to: srcFixture.executorFixtures.executor.address,
4447
+ op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4448
+ success: true,
4449
+ },
4450
+ {
4451
+ from: srcFixture.executorFixtures.executor.address,
4452
+ to: srcFixture.executorFixtures.proxy.address,
4453
+ op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4454
+ success: true,
4455
+ },
4456
+ {
4457
+ from: srcFixture.executorFixtures.proxy.address,
4458
+ to: srcFixture.msglibManager.address,
4459
+ op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4460
+ success: true,
4461
+ },
4462
+ {
4463
+ from: srcFixture.msglibManager.address,
4464
+ to: msglib.address,
4465
+ success: true,
4466
+ op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4467
+ },
4468
+ // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4469
+ {
4470
+ from: msglib.address,
4471
+ to: srcFixture.msglibManager.address,
4472
+ op: Number(OPCODES.BaseInterface_OP_EVENT),
4473
+ success: false, // events are supposed to fail
4474
+ },
4475
+ ]
4476
+ )
4113
4477
  await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.msglibManager)
4114
4478
 
4115
4479
  // ===================================addUlnWorker - priceFeedCache =======================================
@@ -4117,7 +4481,7 @@ export async function deployConfigAndRegisterUln(
4117
4481
  const priceFeedCacheWorkerCallMd = await allStorages.getNewMdExecuteParams({
4118
4482
  target: addressToBigInt(srcFixture.msglibManager.address),
4119
4483
  callData: await allStorages.getNewUlnWorkerFeelibInfo({
4120
- workerAddress: addressToBigInt(priceFeedCacheProxy.address),
4484
+ workerAddress: addressToBigInt(existingPriceFeedCacheFixture.proxy.address),
4121
4485
  workerFeelibBytecode: cellFromArtifact(PriceFeedFeeLibDefaultArtifact),
4122
4486
  workerFeelibStorage: await allStorages.getNewPriceFeedFeelib({
4123
4487
  // priceRatio: BigInt(0),
@@ -4132,7 +4496,7 @@ export async function deployConfigAndRegisterUln(
4132
4496
  optimismExtension: beginCell().endCell(),
4133
4497
  }),
4134
4498
  friendWorkerAddress: BigInt(0),
4135
- dstEid: dstFixture.eid,
4499
+ dstEid,
4136
4500
  rentBalance: toNano('260'),
4137
4501
  isAdmin: BigInt(0),
4138
4502
  }),
@@ -4142,37 +4506,37 @@ export async function deployConfigAndRegisterUln(
4142
4506
  })
4143
4507
 
4144
4508
  internalMsgResults = await addUlnWorker(
4145
- srcFixture.priceFeedCacheFixture.admins[0],
4146
- priceFeedCache,
4509
+ priceFeedCacheFixture.admins[0],
4510
+ priceFeedCacheFixture.priceFeedCache,
4147
4511
  priceFeedCacheWorkerCallMd,
4148
4512
  [
4149
4513
  {
4150
- from: srcFixture.priceFeedCacheFixture.admins[0].address,
4151
- to: priceFeedCache.address,
4514
+ from: priceFeedCacheFixture.admins[0].address,
4515
+ to: priceFeedCacheFixture.priceFeedCache.address,
4152
4516
  op: Number(OPCODES.Worker_OP_CALL_VIA_PROXY),
4153
4517
  success: true,
4154
4518
  },
4155
4519
  {
4156
- from: priceFeedCache.address,
4157
- to: priceFeedCacheProxy.address,
4520
+ from: priceFeedCacheFixture.priceFeedCache.address,
4521
+ to: priceFeedCacheFixture.proxy.address,
4158
4522
  op: Number(OPCODES.Proxy_OP_CALL_CONTRACT),
4159
4523
  success: true,
4160
4524
  },
4161
4525
  {
4162
- from: priceFeedCacheProxy.address,
4526
+ from: priceFeedCacheFixture.proxy.address,
4163
4527
  to: srcFixture.msglibManager.address,
4164
4528
  op: Number(OPCODES.UlnManager_OP_ADD_ULN_WORKER),
4165
4529
  success: true,
4166
4530
  },
4167
4531
  {
4168
4532
  from: srcFixture.msglibManager.address,
4169
- to: srcFixture.msglib.address,
4533
+ to: msglib.address,
4170
4534
  success: true,
4171
4535
  op: Number(OPCODES.Uln_OP_UPDATE_WORKER_FEELIB),
4172
4536
  },
4173
4537
  // emit event Uln::EVENT::ULN_WORKER_REGISTERED
4174
4538
  {
4175
- from: srcFixture.msglib.address,
4539
+ from: msglib.address,
4176
4540
  to: srcFixture.msglibManager.address,
4177
4541
  op: Number(OPCODES.BaseInterface_OP_EVENT),
4178
4542
  success: false, // events are supposed to fail
@@ -4183,34 +4547,14 @@ export async function deployConfigAndRegisterUln(
4183
4547
 
4184
4548
  // ===================================configure default send and receive config =====================================
4185
4549
 
4186
- // requireDefined(srcFixture.dvnFixtures)
4187
- // const [reqDvns, optDvns, optThreshold] = getDvnArrayFromDvnFixtures(srcFixture.dvnFixtures, dvnConfig)
4188
- requireDefined(srcFixture.sendDvnFixtures)
4189
- const [reqSendDvns, optSendDvns] = getDvnArrayFromDvnFixtures(srcFixture.sendDvnFixtures, dvnConfigs.send)
4190
-
4191
- const ulnSendConfig = await allStorages.getNewUlnSendConfig({
4192
- workerQuoteGasLimit: ulnConfigs.send.workerQuoteGasLimit,
4193
- maxMessageBytes: ulnConfigs.send.maxMessageBytes,
4194
- executorNull: BigInt(0),
4195
- executor: addressToBigInt(executorProxy.address),
4196
- requiredDVNsNull: BigInt(0),
4197
- requiredDVNs: serializeDvns(reqSendDvns),
4198
- optionalDVNsNull: BigInt(0),
4199
- optionalDVNs: serializeDvns(optSendDvns),
4200
- confirmationsNull: BigInt(0),
4201
- confirmations: BigInt(1),
4202
- })
4203
-
4204
- srcFixture.defaultUlnSendConfig = ulnSendConfig
4205
-
4206
4550
  await sendMessageViaMultisigAndExpect({
4207
4551
  blockchain,
4208
4552
  multiSigContract: srcFixture.multisig,
4209
4553
  messageBody: allStorages.buildRequest(
4210
4554
  OPCODES.UlnManager_OP_SET_DEFAULT_ULN_SEND_CONFIG,
4211
4555
  await allStorages.getNewMdMdEid({
4212
- md: ulnSendConfig,
4213
- eid: dstFixture.eid,
4556
+ md: srcFixture.defaultUlnSendConfig,
4557
+ eid: dstEid,
4214
4558
  }),
4215
4559
  { value: toNano('10') },
4216
4560
  toNano('0.1')
@@ -4227,41 +4571,21 @@ export async function deployConfigAndRegisterUln(
4227
4571
  },
4228
4572
  {
4229
4573
  from: srcFixture.msglibManager.address,
4230
- to: srcFixture.msglib.address,
4574
+ to: msglib.address,
4231
4575
  success: true,
4232
4576
  op: Number(OPCODES.Uln_OP_SET_DEFAULT_ULN_SEND_CONFIG),
4233
4577
  },
4234
4578
  ],
4235
4579
  })
4236
4580
 
4237
- requireDefined(srcFixture.receiveDvnFixtures)
4238
- const [reqReceiveDvns, optReceiveDvns, optReceiveQuorum] = getDvnArrayFromDvnFixtures(
4239
- srcFixture.receiveDvnFixtures,
4240
- dvnConfigs.receive
4241
- )
4242
-
4243
- const ulnReceiveConfig = await allStorages.getNewUlnReceiveConfig({
4244
- minCommitPacketGasNull: BigInt(0),
4245
- minCommitPacketGas: ulnConfigs.receive.minCommitPacketGas,
4246
- confirmationsNull: BigInt(0),
4247
- confirmations: BigInt(1),
4248
- requiredDVNsNull: BigInt(0),
4249
- requiredDVNs: serializeDvns(reqReceiveDvns),
4250
- optionalDVNsNull: BigInt(0),
4251
- optionalDVNs: serializeDvns(optReceiveDvns),
4252
- optionalDVNThreshold: BigInt(optReceiveQuorum),
4253
- })
4254
-
4255
- srcFixture.defaultUlnReceiveConfig = ulnReceiveConfig
4256
-
4257
4581
  await sendMessageViaMultisigAndExpect({
4258
4582
  blockchain,
4259
4583
  multiSigContract: srcFixture.multisig,
4260
4584
  messageBody: allStorages.buildRequest(
4261
4585
  OPCODES.UlnManager_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG,
4262
4586
  await allStorages.getNewMdMdEid({
4263
- md: ulnReceiveConfig,
4264
- eid: dstFixture.eid,
4587
+ md: srcFixture.defaultUlnReceiveConfig,
4588
+ eid: dstEid,
4265
4589
  }),
4266
4590
  { value: toNano('10') },
4267
4591
  toNano('0.1')
@@ -4278,14 +4602,12 @@ export async function deployConfigAndRegisterUln(
4278
4602
  },
4279
4603
  {
4280
4604
  from: srcFixture.msglibManager.address,
4281
- to: srcFixture.msglib.address,
4605
+ to: msglib.address,
4282
4606
  success: true,
4283
4607
  op: Number(OPCODES.Uln_OP_SET_DEFAULT_ULN_RECEIVE_CONFIG),
4284
4608
  },
4285
4609
  ],
4286
4610
  })
4287
-
4288
- return msglibManager
4289
4611
  }
4290
4612
 
4291
4613
  export async function wireFixtureWithUln(
@@ -4392,13 +4714,15 @@ export async function wireFixtureWithUln(
4392
4714
 
4393
4715
  // ===================================addUlnWorker - dvn =======================================
4394
4716
 
4717
+ const priceFeedCacheFixture = srcFixture.priceFeedCacheFixtures.get(dstFixture.eid)
4718
+ requireDefined(priceFeedCacheFixture)
4395
4719
  await addDvnWorkers(
4396
4720
  allStorages,
4397
4721
  srcFixture,
4398
4722
  srcFixture.sendDvnFixturesCustom,
4399
4723
  srcFixture.receiveDvnFixturesCustom,
4400
4724
  dstFixture.eid,
4401
- srcFixture.priceFeedCacheFixture.proxy.address,
4725
+ priceFeedCacheFixture.proxy.address,
4402
4726
  eventHandler
4403
4727
  )
4404
4728
 
@@ -4859,7 +5183,7 @@ export async function callVerifyOnDvn({
4859
5183
  export async function ulnVerifyAndExpect(
4860
5184
  allStorages: SandboxContract<TonContractWrapper>,
4861
5185
  mdPacketSent: MdPacketSent,
4862
- { msglib: uln }: OAppFixtureULN,
5186
+ msglib: SandboxContract<TonContractWrapper>,
4863
5187
  receiveDvnFixtures: DvnFixture[],
4864
5188
  msglibManager: SandboxContract<TonContractWrapper>,
4865
5189
  msglibConnection: SandboxContract<TonContractWrapper>,
@@ -4867,12 +5191,9 @@ export async function ulnVerifyAndExpect(
4867
5191
  confirmations = 1n,
4868
5192
  profile?: Profile
4869
5193
  ): Promise<Cell> {
4870
- requireDefined(uln)
4871
-
4872
5194
  const oneDayFromNow = BigInt(Math.floor(Date.now() / 1000) + 86400)
4873
5195
 
4874
5196
  const lzPacket = await createLzPacketFromPacketEncoded(mdPacketSent.packetEncoded, allStorages)
4875
-
4876
5197
  for (const { dvn, proxy, admins, verifiers } of receiveDvnFixtures) {
4877
5198
  const requestMd = await allStorages.getNewMdExecuteParams({
4878
5199
  target: addressToBigInt(dvn.address),
@@ -4886,7 +5207,7 @@ export async function ulnVerifyAndExpect(
4886
5207
  }),
4887
5208
  expiration: oneDayFromNow,
4888
5209
  opcode: OPCODES.Uln_OP_ULN_VERIFY,
4889
- forwardingAddress: addressToBigInt(uln.address),
5210
+ forwardingAddress: addressToBigInt(msglib.address),
4890
5211
  })
4891
5212
 
4892
5213
  const internalMsgResults: SendMessageResult = await sendInternalMessageAndExpect({
@@ -4914,12 +5235,12 @@ export async function ulnVerifyAndExpect(
4914
5235
  },
4915
5236
  {
4916
5237
  from: proxy.address,
4917
- to: uln.address,
5238
+ to: msglib.address,
4918
5239
  op: Number(OPCODES.Uln_OP_ULN_VERIFY),
4919
5240
  success: true,
4920
5241
  },
4921
5242
  {
4922
- from: uln.address,
5243
+ from: msglib.address,
4923
5244
  to: msglibConnection.address,
4924
5245
  op: Number(OPCODES.UlnConnection_OP_ULN_CONNECTION_VERIFY),
4925
5246
  success: true,
@@ -4945,6 +5266,167 @@ export async function ulnVerifyAndExpect(
4945
5266
 
4946
5267
  return lzPacket
4947
5268
  }
5269
+
5270
+ export async function registerAdditionalPriceFeedCache(
5271
+ blockchain: Blockchain,
5272
+ allStorages: SandboxContract<TonContractWrapper>,
5273
+ srcFixture: OAppFixtureULN,
5274
+ dstEid: bigint,
5275
+ adminSet: SandboxContract<TreasuryContract>[],
5276
+ existingProxy: SandboxContract<TonContractWrapper>,
5277
+ priceFeedFeeLib: Cell,
5278
+ currentAdminsWorkers: SandboxContract<TonContractWrapper>[]
5279
+ ): Promise<[SandboxContract<TonContractWrapper>, SendMessageResult]> {
5280
+ // Create new price feed cache worker
5281
+ const priceFeedCache = blockchain.openContract(
5282
+ TonContractWrapper.create(
5283
+ cellFromArtifact(PriceFeedCacheArtifact),
5284
+ await allStorages.getNewPriceFeedCache({
5285
+ admins: serializeAddressList(adminSet),
5286
+ version: 0n,
5287
+ dstEid,
5288
+ priceFeedFeeLib,
5289
+ })
5290
+ )
5291
+ )
5292
+
5293
+ // 1) Deploy the worker
5294
+ const internalMsgResults = await sendInternalMessageAndExpect({
5295
+ value: protocolSetupGas['MsgLib.INITIALIZE'],
5296
+ sender: srcFixture.owner.getSender(),
5297
+ contract: priceFeedCache,
5298
+ expectedTransactions: [
5299
+ {
5300
+ from: srcFixture.owner.address,
5301
+ to: priceFeedCache.address,
5302
+ deploy: true,
5303
+ success: true,
5304
+ },
5305
+ ],
5306
+ opCode: OPCODES.BaseInterface_OP_INITIALIZE,
5307
+ md: emptyObject,
5308
+ balanceRefill: toNano('1'),
5309
+ })
5310
+
5311
+ // 2) Update proxy admins list (including the new worker)
5312
+ await sendInternalMessageAndExpect({
5313
+ value: protocolSetupGas['MsgLib.INITIALIZE'],
5314
+ sender: srcFixture.owner.getSender(),
5315
+ contract: existingProxy,
5316
+ expectedTransactions: [
5317
+ {
5318
+ from: srcFixture.owner.address,
5319
+ to: existingProxy.address,
5320
+ success: true,
5321
+ },
5322
+ ],
5323
+ opCode: OPCODES.Worker_OP_SET_ADMINS,
5324
+ md: serializeAddressList([...currentAdminsWorkers, priceFeedCache]),
5325
+ balanceRefill: toNano('0'),
5326
+ })
5327
+
5328
+ // 3) Set proxy on worker
5329
+ await sendInternalMessageAndExpect({
5330
+ value: protocolSetupGas['MsgLib.INITIALIZE'],
5331
+ sender: srcFixture.owner.getSender(),
5332
+ contract: priceFeedCache,
5333
+ expectedTransactions: [
5334
+ {
5335
+ from: srcFixture.owner.address,
5336
+ to: priceFeedCache.address,
5337
+ success: true,
5338
+ },
5339
+ ],
5340
+ opCode: OPCODES.Worker_OP_SET_PROXY,
5341
+ md: await allStorages.getNewMdSetAddress({
5342
+ address: addressToBigInt(existingProxy.address),
5343
+ }),
5344
+ balanceRefill: toNano('0'),
5345
+ })
5346
+
5347
+ srcFixture.priceFeedCacheFixtures.set(dstEid, {
5348
+ priceFeedCache,
5349
+ proxy: existingProxy,
5350
+ admins: [...adminSet],
5351
+ })
5352
+
5353
+ return [priceFeedCache, internalMsgResults]
5354
+ }
5355
+
5356
+ export async function wireFixtureWithNewUln(
5357
+ blockchain: Blockchain,
5358
+ allStorages: SandboxContract<TonContractWrapper>,
5359
+ multiSigners: SandboxContract<TreasuryContract>[],
5360
+ srcFixture: OAppFixtureULN,
5361
+ dstFixture: OAppFixtureULN,
5362
+ eventHandler: LzEventHandler
5363
+ ): Promise<void> {
5364
+ // ===================================default config =====================================
5365
+
5366
+ const ulnConfigDefault: UlnConfig = {
5367
+ send: {
5368
+ workerQuoteGasLimit: BigInt(100000000),
5369
+ maxMessageBytes: BigInt(100000000),
5370
+ },
5371
+ receive: {
5372
+ minCommitPacketGas: BigInt(1),
5373
+ },
5374
+ }
5375
+
5376
+ const dvnConfigsDefault: DvnConfigs = {
5377
+ send: {
5378
+ numReqDvns: 2n,
5379
+ numOptDvns: 0n,
5380
+ },
5381
+ receive: {
5382
+ numReqDvns: 2n,
5383
+ numOptDvns: 0n,
5384
+ optDvnQuorum: 0n,
5385
+ },
5386
+ }
5387
+
5388
+ // ===================================deploy, configue, and register uln =====================================
5389
+
5390
+ srcFixture.msglibManager = await deployConfigAndRegisterUln(
5391
+ blockchain,
5392
+ multiSigners,
5393
+ allStorages,
5394
+ srcFixture,
5395
+ dstFixture,
5396
+ ulnConfigDefault,
5397
+ ULN_MANAGER_DEFAULT_VERSION,
5398
+ eventHandler,
5399
+ dvnConfigsDefault
5400
+ )
5401
+
5402
+ // ===================================add msg lib to controller =====================================
5403
+
5404
+ let internalMsgResults = await addMsgLibToController(
5405
+ blockchain,
5406
+ multiSigners,
5407
+ srcFixture,
5408
+ dstFixture,
5409
+ srcFixture.msglibManager
5410
+ )
5411
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
5412
+
5413
+ // ===================================set default endpoint config=====================================
5414
+
5415
+ internalMsgResults = await setDefaultEndpointConfig(
5416
+ blockchain,
5417
+ allStorages,
5418
+ multiSigners,
5419
+ srcFixture.msglibManager,
5420
+ srcFixture.msglibManager,
5421
+ srcFixture,
5422
+ dstFixture
5423
+ )
5424
+
5425
+ await eventHandler.addCurrentEventsToAllEvents(internalMsgResults, srcFixture.controller)
5426
+
5427
+ // expect no failures
5428
+ expect(eventHandler.allFailures.txList).toHaveLength(0)
5429
+ }
4948
5430
  `;
4949
5431
  fs__default.writeFileSync(path__default.join(directory, filename), savedCode);
4950
5432
  }