@layerzerolabs/layerzero-v2-ton 3.0.13-ton.0 → 3.0.18-ton.0

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.
Files changed (208) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +10 -4
  3. package/src/classes/lz/EpConfig.fc +3 -3
  4. package/src/classes/lz/Packet.fc +16 -3
  5. package/src/classes/lz/Path.fc +10 -1
  6. package/src/classes/msgdata/Deploy.fc +15 -3
  7. package/src/classes/msgdata/LzSend.fc +1 -1
  8. package/src/classes/msgdata/OptionsV2.fc +7 -4
  9. package/src/funC++/abstract/contractMainAbstract.fc +12 -1
  10. package/src/funC++/abstract/handlerAbstract.fc +10 -2
  11. package/src/funC++/actions/call.fc +5 -3
  12. package/src/funC++/baseInterface.fc +9 -8
  13. package/src/funC++/classlib.fc +30 -33
  14. package/src/funC++/constants.fc +2 -2
  15. package/src/funC++/contractMain.fc +2 -0
  16. package/src/funC++/dataStructures/AddressList.fc +89 -0
  17. package/src/funC++/dataStructures/DeterministicInsertionCircularQueue.fc +1 -1
  18. package/src/funC++/dataStructures/PipelinedOutOfOrder.fc +25 -1
  19. package/src/funC++/handlerCore.fc +2 -0
  20. package/src/funC++/stdlib.fc +1 -1
  21. package/src/funC++/testutils.fc +99 -0
  22. package/src/funC++/utils.fc +66 -2
  23. package/src/multisig/bocs/MultiSig.compiled.json +5 -0
  24. package/src/multisig/bocs/MultiSigOrder.compiled.json +5 -0
  25. package/tests/baseContractTest.fc +15 -12
  26. package/build/AllStorages.boc +0 -0
  27. package/build/AllStorages.compiled.json +0 -1
  28. package/build/AllStorages.fif +0 -4176
  29. package/build/AllStorages.test.boc +0 -0
  30. package/build/AllStorages.test.compiled.json +0 -1
  31. package/build/AllStorages.test.fif +0 -1831
  32. package/build/BaseContract.test.boc +0 -0
  33. package/build/BaseContract.test.compiled.json +0 -1
  34. package/build/BaseContract.test.fif +0 -3560
  35. package/build/Channel.boc +0 -0
  36. package/build/Channel.compiled.json +0 -1
  37. package/build/Channel.fif +0 -5109
  38. package/build/Channel.permissions.test.boc +0 -0
  39. package/build/Channel.permissions.test.compiled.json +0 -1
  40. package/build/Channel.permissions.test.fif +0 -7601
  41. package/build/ChannelBurn.test.boc +0 -0
  42. package/build/ChannelBurn.test.compiled.json +0 -1
  43. package/build/ChannelBurn.test.fif +0 -7486
  44. package/build/ChannelCommitPacket.test.boc +0 -0
  45. package/build/ChannelCommitPacket.test.compiled.json +0 -1
  46. package/build/ChannelCommitPacket.test.fif +0 -8001
  47. package/build/ChannelConfig.test.boc +0 -0
  48. package/build/ChannelConfig.test.compiled.json +0 -1
  49. package/build/ChannelConfig.test.fif +0 -7474
  50. package/build/ChannelInitialize.test.boc +0 -0
  51. package/build/ChannelInitialize.test.compiled.json +0 -1
  52. package/build/ChannelInitialize.test.fif +0 -7321
  53. package/build/ChannelMsglibIntegration.test.boc +0 -0
  54. package/build/ChannelMsglibIntegration.test.compiled.json +0 -1
  55. package/build/ChannelMsglibIntegration.test.fif +0 -7437
  56. package/build/ChannelMsglibSendCallback.test.boc +0 -0
  57. package/build/ChannelMsglibSendCallback.test.compiled.json +0 -1
  58. package/build/ChannelMsglibSendCallback.test.fif +0 -7743
  59. package/build/ChannelNilify.test.boc +0 -0
  60. package/build/ChannelNilify.test.compiled.json +0 -1
  61. package/build/ChannelNilify.test.fif +0 -7702
  62. package/build/ChannelReceive.test.boc +0 -0
  63. package/build/ChannelReceive.test.compiled.json +0 -1
  64. package/build/ChannelReceive.test.fif +0 -7742
  65. package/build/ChannelReceiveCallback.test.boc +0 -0
  66. package/build/ChannelReceiveCallback.test.compiled.json +0 -1
  67. package/build/ChannelReceiveCallback.test.fif +0 -7581
  68. package/build/ChannelReceiveView.test.boc +0 -0
  69. package/build/ChannelReceiveView.test.compiled.json +0 -1
  70. package/build/ChannelReceiveView.test.fif +0 -7384
  71. package/build/ChannelSend.test.boc +0 -0
  72. package/build/ChannelSend.test.compiled.json +0 -1
  73. package/build/ChannelSend.test.fif +0 -7690
  74. package/build/Classlib.test.boc +0 -0
  75. package/build/Classlib.test.compiled.json +0 -1
  76. package/build/Classlib.test.fif +0 -4728
  77. package/build/Connection.boc +0 -0
  78. package/build/Connection.compiled.json +0 -1
  79. package/build/Connection.fif +0 -3586
  80. package/build/Connection.test.boc +0 -0
  81. package/build/Connection.test.compiled.json +0 -1
  82. package/build/Connection.test.fif +0 -6582
  83. package/build/Controller.assertions.test.boc +0 -0
  84. package/build/Controller.assertions.test.compiled.json +0 -1
  85. package/build/Controller.assertions.test.fif +0 -6137
  86. package/build/Controller.boc +0 -0
  87. package/build/Controller.compiled.json +0 -1
  88. package/build/Controller.fif +0 -3278
  89. package/build/Controller.permissions.test.boc +0 -0
  90. package/build/Controller.permissions.test.compiled.json +0 -1
  91. package/build/Controller.permissions.test.fif +0 -6244
  92. package/build/Controller.test.boc +0 -0
  93. package/build/Controller.test.compiled.json +0 -1
  94. package/build/Controller.test.fif +0 -6407
  95. package/build/Counter.boc +0 -0
  96. package/build/Counter.compiled.json +0 -1
  97. package/build/Counter.fif +0 -4816
  98. package/build/Counter.permissions.test.boc +0 -0
  99. package/build/Counter.permissions.test.compiled.json +0 -1
  100. package/build/Counter.permissions.test.fif +0 -7113
  101. package/build/Counter.setters.test.boc +0 -0
  102. package/build/Counter.setters.test.compiled.json +0 -1
  103. package/build/Counter.setters.test.fif +0 -7090
  104. package/build/Counter.test.boc +0 -0
  105. package/build/Counter.test.compiled.json +0 -1
  106. package/build/Counter.test.fif +0 -7547
  107. package/build/Dvn.boc +0 -0
  108. package/build/Dvn.compiled.json +0 -1
  109. package/build/Dvn.fif +0 -2923
  110. package/build/Dvn.test.boc +0 -0
  111. package/build/Dvn.test.compiled.json +0 -1
  112. package/build/Dvn.test.fif +0 -5760
  113. package/build/Endpoint.boc +0 -0
  114. package/build/Endpoint.compiled.json +0 -1
  115. package/build/Endpoint.fif +0 -3777
  116. package/build/Endpoint.permissions.test.boc +0 -0
  117. package/build/Endpoint.permissions.test.compiled.json +0 -1
  118. package/build/Endpoint.permissions.test.fif +0 -6218
  119. package/build/Endpoint.test.boc +0 -0
  120. package/build/Endpoint.test.compiled.json +0 -1
  121. package/build/Endpoint.test.fif +0 -6906
  122. package/build/EndpointSetEpConfigDefaults.test.boc +0 -0
  123. package/build/EndpointSetEpConfigDefaults.test.compiled.json +0 -1
  124. package/build/EndpointSetEpConfigDefaults.test.fif +0 -6536
  125. package/build/Executor.boc +0 -0
  126. package/build/Executor.compiled.json +0 -1
  127. package/build/Executor.fif +0 -2731
  128. package/build/Executor.test.boc +0 -0
  129. package/build/Executor.test.compiled.json +0 -1
  130. package/build/Executor.test.fif +0 -5829
  131. package/build/LzClasses.test.boc +0 -0
  132. package/build/LzClasses.test.compiled.json +0 -1
  133. package/build/LzClasses.test.fif +0 -4457
  134. package/build/LzUtil.test.boc +0 -0
  135. package/build/LzUtil.test.compiled.json +0 -1
  136. package/build/LzUtil.test.fif +0 -1831
  137. package/build/MsgData.test.boc +0 -0
  138. package/build/MsgData.test.compiled.json +0 -1
  139. package/build/MsgData.test.fif +0 -4318
  140. package/build/MsglibPacketCodec.test.boc +0 -0
  141. package/build/MsglibPacketCodec.test.compiled.json +0 -1
  142. package/build/MsglibPacketCodec.test.fif +0 -4851
  143. package/build/MultiSig.boc +0 -0
  144. package/build/MultiSig.compiled.json +0 -1
  145. package/build/MultiSig.fif +0 -727
  146. package/build/MultiSigOrder.boc +0 -0
  147. package/build/MultiSigOrder.compiled.json +0 -1
  148. package/build/MultiSigOrder.fif +0 -650
  149. package/build/PipelinedOutOfOrder.test.boc +0 -0
  150. package/build/PipelinedOutOfOrder.test.compiled.json +0 -1
  151. package/build/PipelinedOutOfOrder.test.fif +0 -2188
  152. package/build/SmlConnection.boc +0 -0
  153. package/build/SmlConnection.compiled.json +0 -1
  154. package/build/SmlConnection.fif +0 -2600
  155. package/build/SmlConnection.permissions.test.boc +0 -0
  156. package/build/SmlConnection.permissions.test.compiled.json +0 -1
  157. package/build/SmlConnection.permissions.test.fif +0 -5504
  158. package/build/SmlConnection.test.boc +0 -0
  159. package/build/SmlConnection.test.compiled.json +0 -1
  160. package/build/SmlConnection.test.fif +0 -5501
  161. package/build/SmlManager.boc +0 -0
  162. package/build/SmlManager.compiled.json +0 -1
  163. package/build/SmlManager.fif +0 -3987
  164. package/build/SmlManager.permissions.test.boc +0 -0
  165. package/build/SmlManager.permissions.test.compiled.json +0 -1
  166. package/build/SmlManager.permissions.test.fif +0 -6025
  167. package/build/SmlManager.test.boc +0 -0
  168. package/build/SmlManager.test.compiled.json +0 -1
  169. package/build/SmlManager.test.fif +0 -6054
  170. package/build/Uln.boc +0 -0
  171. package/build/Uln.compiled.json +0 -1
  172. package/build/Uln.fif +0 -4924
  173. package/build/Uln.test.boc +0 -0
  174. package/build/Uln.test.compiled.json +0 -1
  175. package/build/Uln.test.fif +0 -7084
  176. package/build/UlnManager.boc +0 -0
  177. package/build/UlnManager.compiled.json +0 -1
  178. package/build/UlnManager.fif +0 -3934
  179. package/build/UlnManager.test.boc +0 -0
  180. package/build/UlnManager.test.compiled.json +0 -1
  181. package/build/UlnManager.test.fif +0 -6578
  182. package/build/UlnReceiveConfig.test.boc +0 -0
  183. package/build/UlnReceiveConfig.test.compiled.json +0 -1
  184. package/build/UlnReceiveConfig.test.fif +0 -4413
  185. package/build/UlnSend.test.boc +0 -0
  186. package/build/UlnSend.test.compiled.json +0 -1
  187. package/build/UlnSend.test.fif +0 -6583
  188. package/build/UlnSendConfig.test.boc +0 -0
  189. package/build/UlnSendConfig.test.compiled.json +0 -1
  190. package/build/UlnSendConfig.test.fif +0 -4431
  191. package/build/UlnSendWorkerFactory.test.boc +0 -0
  192. package/build/UlnSendWorkerFactory.test.compiled.json +0 -1
  193. package/build/UlnSendWorkerFactory.test.fif +0 -6683
  194. package/build/UlnUtil.test.boc +0 -0
  195. package/build/UlnUtil.test.compiled.json +0 -1
  196. package/build/UlnUtil.test.fif +0 -5873
  197. package/build/WorkerCore.test.boc +0 -0
  198. package/build/WorkerCore.test.compiled.json +0 -1
  199. package/build/WorkerCore.test.fif +0 -5637
  200. package/build/ZroMinter.boc +0 -0
  201. package/build/ZroMinter.compiled.json +0 -1
  202. package/build/ZroMinter.fif +0 -2300
  203. package/build/ZroWallet.boc +0 -0
  204. package/build/ZroWallet.compiled.json +0 -1
  205. package/build/ZroWallet.fif +0 -2471
  206. package/src/classes/lz/Attestation.fc +0 -23
  207. package/src/classes/msgdata/ClaimUnaccountedPoolFunds.fc +0 -0
  208. package/src/classes/msgdata/InitUlnConnection.fc +0 -18
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @layerzerolabs/layerzero-v2-ton
2
2
 
3
+ ## 3.0.18-ton.0
4
+
5
+ ### Patch Changes
6
+
7
+ - uln302
8
+
9
+ ## 3.0.14-ton.0
10
+
11
+ ### Patch Changes
12
+
13
+ - fix ton images
14
+
3
15
  ## 3.0.13-ton.0
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layerzerolabs/layerzero-v2-ton",
3
- "version": "3.0.13-ton.0",
3
+ "version": "3.0.18-ton.0",
4
4
  "exports": {
5
5
  ".": {
6
6
  "types": "./dist/index.d.ts",
@@ -12,6 +12,11 @@
12
12
  "import": "./build/*.json",
13
13
  "require": "./build/*.json"
14
14
  },
15
+ "./src/multisig/bocs/*.json": {
16
+ "default": "./src/multisig/bocs/*.json",
17
+ "import": "./src/multisig/bocs/*.json",
18
+ "require": "./src/multisig/bocs/*.json"
19
+ },
15
20
  "./package.json": "./package.json"
16
21
  },
17
22
  "main": "./dist/index.cjs",
@@ -27,11 +32,12 @@
27
32
  "src/protocol/",
28
33
  "src/jettons/zro/*.fc",
29
34
  "tests/testMain.fc",
30
- "tests/baseContractTest.fc"
35
+ "tests/baseContractTest.fc",
36
+ "src/multisig/bocs/MultiSig.compiled.json",
37
+ "src/multisig/bocs/MultiSigOrder.compiled.json"
31
38
  ],
32
39
  "scripts": {
33
- "build": "$npm_execpath clean-prebuild && $npm_execpath build-all && $npm_execpath compile",
34
- "build-all": "$npm_execpath blueprint build --all",
40
+ "build": "$npm_execpath clean-prebuild && $npm_execpath blueprint build --all",
35
41
  "build-single": "$npm_execpath blueprint build",
36
42
  "clean": "$npm_execpath clean-prebuild && rimraf .turbo",
37
43
  "clean-prebuild": "rimraf build",
@@ -1,9 +1,9 @@
1
1
  #include "../../funC++/classlib.fc";
2
2
 
3
3
  ;; ERRORS
4
- const int lz::EpConfig::ERROR::sameMsglib = "sameMsglib"c & ERRORCODE_MASK;
5
- const int lz::EpConfig::ERROR::invalidTimeoutExpiry = "invalidTimeoutExpiry"c & ERRORCODE_MASK;
6
- const int lz::EpConfig::ERROR::invalidTimeoutReceiveMsglib = "invalidTimeoutReceiveMsglib"c & ERRORCODE_MASK;
4
+ const int lz::EpConfig::ERROR::sameMsglib = 1025;
5
+ const int lz::EpConfig::ERROR::invalidTimeoutExpiry = 1026;
6
+ const int lz::EpConfig::ERROR::invalidTimeoutReceiveMsglib = 1027;
7
7
  const int lz::EpConfig::VALID = 42069 & ERRORCODE_MASK;
8
8
 
9
9
  ;; required storage name
@@ -12,9 +12,9 @@ const int lz::Packet::message = 1;
12
12
  const int lz::Packet::nonce = 2;
13
13
  const int lz::Packet::guid = 3;
14
14
 
15
- const int lz::Packet::ERROR::INVALID_MESSAGE = "invalid_message"c & ERRORCODE_MASK;
16
- const int lz::Packet::ERROR::INVALID_NONCE = "invalid_nonce"c & ERRORCODE_MASK;
17
- const int lz::Packet::ERROR::INVALID_PACKET_FIELD = "invalid_packet_field"c & ERRORCODE_MASK;
15
+ const int lz::Packet::ERROR::INVALID_MESSAGE = 1089;
16
+ const int lz::Packet::ERROR::INVALID_NONCE = 1090;
17
+ const int lz::Packet::ERROR::INVALID_PACKET_FIELD = 1091;
18
18
 
19
19
  const int lz::Packet::MAX_RECEIVE_MESSAGE_CELLS = 32;
20
20
  const int lz::Packet::MAX_SEND_MESSAGE_CELLS = 255;
@@ -35,6 +35,19 @@ cell lz::Packet::nonceless(cell $path, cell message) inline method_id {
35
35
  return lz::Packet::New($path, message, 0);
36
36
  }
37
37
 
38
+ ;; assumes that the message is a valid single-linked list
39
+ int lz::Packet::_messageBytes(cell $self) impure inline {
40
+ slice messageSlice = $self.cl::get<cellRef>(lz::Packet::message).begin_parse();
41
+ (int sliceBits, int sliceRefs) = messageSlice.slice_bits_refs();
42
+ int messageBytes = sliceBits / 8;
43
+ while (sliceRefs > 0) {
44
+ messageSlice = messageSlice.preload_first_ref().begin_parse();
45
+ (sliceBits, sliceRefs) = messageSlice.slice_bits_refs();
46
+ messageBytes += (sliceBits / 8);
47
+ }
48
+ return messageBytes;
49
+ }
50
+
38
51
  () lz::Packet::_assertValidLinkedList(cell head, int maxLen) impure inline {
39
52
  slice messageSlice = head.begin_parse();
40
53
  repeat (maxLen) {
@@ -46,7 +46,7 @@ const int lz::Path::_dstEidOffset = lz::Path::_srcOAppOffset + 256;
46
46
  ;; low-level optimized version
47
47
  ;; original: 12k gas
48
48
  ;; optimized: 1k gas
49
- cell lz::Path::optimizedReverse(cell $path) inline {
49
+ cell lz::Path::optimizedReverse(cell $path) impure inline {
50
50
  slice pathSlice = $path.begin_parse();
51
51
  return begin_cell()
52
52
  .store_slice(pathSlice.scutfirst(_HEADER_WIDTH, 0))
@@ -54,3 +54,12 @@ cell lz::Path::optimizedReverse(cell $path) inline {
54
54
  .store_slice(pathSlice.preload_bits_offset(lz::Path::_srcEidOffset, 288)) ;; eid + address
55
55
  .end_cell();
56
56
  }
57
+
58
+ cell lz::Path::sanitize(cell $path) impure {
59
+ return lz::Path::New(
60
+ $path.cl::get<uint32>(lz::Path::srcEid),
61
+ $path.cl::get<address>(lz::Path::srcOApp),
62
+ $path.cl::get<uint32>(lz::Path::dstEid),
63
+ $path.cl::get<address>(lz::Path::dstOApp)
64
+ );
65
+ }
@@ -7,14 +7,26 @@ const int md::Deploy::NAME = "deploy"u;
7
7
  const int md::Deploy::initialDeposit = 0;
8
8
  const int md::Deploy::dstEid = 1;
9
9
  const int md::Deploy::dstOApp = 2;
10
+ const int md::Deploy::extraInfo = 3;
10
11
 
11
12
  cell md::Deploy::New(int initialDeposit, int dstEid, int dstOApp) inline method_id {
12
13
  return cl::declare(
13
14
  md::Deploy::NAME,
14
15
  unsafeTuple([
15
- [cl::t::coins, initialDeposit], ;; md::Deploy::initialDeposit
16
- [cl::t::uint32, dstEid], ;; md::Deploy::dstEid
17
- [cl::t::uint256, dstOApp] ;; md::Deploy::dstOApp
16
+ [cl::t::coins, initialDeposit], ;; md::Deploy::initialDeposit
17
+ [cl::t::uint32, dstEid], ;; md::Deploy::dstEid
18
+ [cl::t::uint256, dstOApp], ;; md::Deploy::dstOApp
19
+ [cl::t::objRef, cl::nullObject()] ;; md::Deploy::extraInfo
18
20
  ])
19
21
  );
20
22
  }
23
+
24
+ cell md::Deploy::NewWithExtraInfo(
25
+ int initialDeposit,
26
+ int dstEid,
27
+ int dstOApp,
28
+ cell $extraInfo
29
+ ) method_id {
30
+ return md::Deploy::New(initialDeposit, dstEid, dstOApp)
31
+ .cl::set(md::Deploy::extraInfo, $extraInfo);
32
+ }
@@ -46,7 +46,7 @@ cell md::lzSend::fillRequestInfo(
46
46
  int requestId,
47
47
  int sendMsglib,
48
48
  int sendMsglibConnection
49
- ) inline {
49
+ ) inline method_id {
50
50
  slice lzSendSlice = $lzSend.begin_parse();
51
51
  return begin_cell()
52
52
  .store_slice(lzSendSlice.scutfirst(_HEADER_WIDTH, 0))
@@ -7,8 +7,9 @@ const int md::OptionsV2::NAME = "OptionsV2"u;
7
7
  const int md::OptionsV2::lzReceiveGas = 0;
8
8
  const int md::OptionsV2::lzReceiveValue = 1;
9
9
  const int md::OptionsV2::lzComposeGas = 2;
10
- const int md::OptionsV2::nativeDropAddress = 3;
11
- const int md::OptionsV2::nativeDropAmount = 4;
10
+ const int md::OptionsV2::lzComposeValue = 3;
11
+ const int md::OptionsV2::nativeDropAddress = 4;
12
+ const int md::OptionsV2::nativeDropAmount = 5;
12
13
 
13
14
  ;; This is used to demonstrate that we are capable of having different options objects
14
15
  ;; This is not finalized and the 'V2' shouldnt be considered a 'valid' options type in the protocol YET
@@ -18,16 +19,18 @@ cell md::OptionsV2::New(
18
19
  int lzReceiveGas,
19
20
  int lzReceiveValue,
20
21
  int lzComposeGas,
22
+ int lzComposeValue,
21
23
  int nativeDropAddress,
22
24
  int nativeDropAmount
23
- ) inline method_id {
25
+ ) inline {
24
26
  return cl::declare(
25
27
  md::OptionsV2::NAME,
26
28
  unsafeTuple([
27
29
  [cl::t::uint256, lzReceiveGas], ;; md::OptionsV2::lzReceiveGas
28
30
  [cl::t::uint256, lzReceiveValue], ;; md::OptionsV2::lzReceiveValue
29
31
  [cl::t::uint256, lzComposeGas], ;; md::OptionsV2::lzComposeGas
30
- [cl::t::address, nativeDropAddress], ;; md::OptionsV2::nativeDropAddress
32
+ [cl::t::uint256, lzComposeValue], ;; md::OptionsV2::lzComposeValue
33
+ [cl::t::address, nativeDropAddress], ;; md::OptionsV2::nativeDropAddress
31
34
  [cl::t::uint256, nativeDropAmount] ;; md::OptionsV2::nativeDropAmount
32
35
  ])
33
36
  );
@@ -1,3 +1,14 @@
1
- ;; todo: comments
1
+ ;; _executeOpcode is executed at the start of contractMain, after checking permissions.
2
+ ;; Each contract implements a list of opcodes, which calls a handler as the entry point
3
+ ;; of that opcode. The contract must be initialized in order to start executing opcodes.
4
+ ;; @in the opcode to execute
5
+ ;; @in the message data extracted from txnContext
6
+ ;; @out tuple of resultant actions
2
7
  tuple _executeOpcode(int op, cell $md) impure inline;
8
+
9
+ ;; Actions are executed after the opcode is executed. Each opcode must emit a tuple
10
+ ;; of actions, where each action is executed after the opcode is executed in order.
11
+ ;; @in the action to execute
12
+ ;; @in the value of the action
13
+ ;; @out a bool that determines if excess balance is to be sent back to the origin.
3
14
  int _executeAction(int actionType, tuple action) impure inline;
@@ -1,12 +1,20 @@
1
- ;; todo: comments
1
+ ;; Assert that the owner has sent an INITIALIZE opcode to this contract
2
2
  () assertInitialized() impure inline;
3
3
 
4
+ ;; Assert the identity of the caller for a given opcode
4
5
  () checkPermissions(int op, cell $md) impure inline;
5
6
 
7
+ ;; Initialize this contract
6
8
  tuple initialize(cell $md) impure inline;
7
9
 
10
+ ;; Authentication = the owner has deployed and sent at least one transaction to this contract
11
+ ;; unauthenticated contracts cannot perform any actions.
12
+ ;; Authentication enables sharded contracts to trust the identity and intention of other shards
8
13
  () authenticateIfNecessary() impure inline;
9
14
 
15
+ ;; Assert the caller is the owner of this contract
10
16
  () assertOwner() impure inline;
11
- () _checkPermissions(int op, cell $md) impure inline;
12
17
 
18
+ ;; Asserts permissions of caller for permissioned opcodes before executing opcode
19
+ ;; @see contractMainAbstract.fc
20
+ () _checkPermissions(int op, cell $md) impure inline;
@@ -1,6 +1,4 @@
1
1
  #include "utils.fc";
2
- #include "../stdlib.fc";
3
- #include "../stringlib.fc";
4
2
 
5
3
  const int action::call::NAME = "actionCall"u;
6
4
 
@@ -16,8 +14,12 @@ tuple action::call::New(int to, int opcode, cell $md) inline {
16
14
  }
17
15
 
18
16
  ;; returns true if equals
19
- int action::call::equals(tuple self, tuple other) {
17
+ int action::call::equals(tuple self, tuple other) inline {
20
18
  int equalMdField = compareObjectFields(self.cell_at(action::call::md), other.cell_at(action::call::md));
19
+ if (equalMdField != -1) {
20
+ ~strdump("call: not equal md field at idx ");
21
+ ~dump(equalMdField);
22
+ }
21
23
  return (
22
24
  (self.int_at(0) == other.int_at(0)) ;; NAME
23
25
  & (self.int_at(action::call::to) == other.int_at(action::call::to))
@@ -3,14 +3,15 @@
3
3
  const int BaseInterface::event::AUTHENTICATED = "AUTHENTICATED"u;
4
4
  const int BaseInterface::event::INITIALIZED = "INITIALIZED"u;
5
5
 
6
- const int BaseInterface::ERROR::notAuthenticated = "BaseInterface::ERROR::notAuthenticated"c & ERRORCODE_MASK;
7
- const int BaseInterface::ERROR::onlyOwner = "BaseInterface::ERROR::onlyOwner"c & ERRORCODE_MASK;
8
- const int BaseInterface::ERROR::notInitialized = "BaseInterface::ERROR::notInitialized"c & ERRORCODE_MASK;
9
- const int BaseInterface::ERROR::alreadyInitialized = "BaseInterface::ERROR::alreadyInitialized"c & ERRORCODE_MASK;
10
- const int BaseInterface::ERROR::invalidOpcode = "BaseInterface::ERROR::invalidOpcode"c & ERRORCODE_MASK;
11
- const int BaseInterface::ERROR::eventEmitted = "BaseInterface::ERROR::eventEmitted"c & ERRORCODE_MASK;
12
- const int BaseInterface::ERROR::invalidActionType = "BaseInterface::ERROR::invalidActionType"c & ERRORCODE_MASK;
13
- const int BaseInterface::ERROR::invalidEventSource = "BaseInterface::ERROR::invalidEventSource"c & ERRORCODE_MASK;
6
+ const int BaseInterface::ERROR::notAuthenticated = 257;
7
+ const int BaseInterface::ERROR::onlyOwner = 258;
8
+ const int BaseInterface::ERROR::notInitialized = 259;
9
+ const int BaseInterface::ERROR::alreadyInitialized = 260;
10
+ const int BaseInterface::ERROR::invalidOpcode = 261;
11
+ const int BaseInterface::ERROR::eventEmitted = 262;
12
+ const int BaseInterface::ERROR::invalidActionType = 263;
13
+ const int BaseInterface::ERROR::invalidEventSource = 264;
14
14
 
15
15
  const int BaseInterface::OP::INITIALIZE = "BaseInterface::OP::INITIALIZE"c;
16
+ const int BaseInterface::OP::EMPTY = 0;
16
17
  const int BaseInterface::OP::EVENT = "BaseInterface::OP::EVENT"c;
@@ -21,7 +21,8 @@ const int DICT256_KEYLEN = 256;
21
21
 
22
22
  const int cl::NULL_CLASS_NAME = "NULL"u;
23
23
 
24
- const int cl::ERROR::INVALID_CLASS = "cl::ERROR::INVALID_CLASS"c & ERRORCODE_MASK;
24
+ const int cl::ERROR::INVALID_CLASS = 1057;
25
+ const int cl::ERROR::MALFORMED_OBJECT = 1058;
25
26
 
26
27
  const int DEBUG = 0;
27
28
 
@@ -66,10 +67,6 @@ int getContractAddress() impure inline {
66
67
  return my_address().preload_bits_offset(11, 256).preload_uint(256);
67
68
  }
68
69
 
69
- slice cl::objToSlice(cell $obj) inline method_id {
70
- return $obj.begin_parse();
71
- }
72
-
73
70
  ;;; ====================== Class functions ======================
74
71
  ;; returns type width in bits
75
72
  int _getTypeWidth(int clType) inline {
@@ -171,7 +168,7 @@ int cl::typeof(cell $obj) inline method_id {
171
168
  return $obj.begin_parse().preload_uint(_NAME_WIDTH);
172
169
  }
173
170
 
174
- cell cl::declare(int name, tuple fields) inline method_id {
171
+ cell cl::declare(int name, tuple fields) inline {
175
172
  tuple classBuilder = unsafeTuple([null(), begin_cell()]);
176
173
 
177
174
  if (DEBUG) {
@@ -207,13 +204,15 @@ cell cl::declare(int name, tuple fields) inline method_id {
207
204
  classBuilder = classBuilder.tpush(begin_cell());
208
205
  }
209
206
  }
210
- if ((curRefOffset + 1) > curCellMaxRefs) {
211
- ;; move to the next cell
212
- curRefCell += 1;
213
- curRefOffset = 0;
214
- curCellMaxRefs = MAX_CELL_REFS;
215
- if (curRefCell >= classBuilder.tlen()) {
216
- classBuilder = classBuilder.tpush(begin_cell());
207
+ if (fieldBits == 0) {
208
+ if ((curRefOffset + 1) > curCellMaxRefs) {
209
+ ;; move to the next cell
210
+ curRefCell += 1;
211
+ curRefOffset = 0;
212
+ curCellMaxRefs = MAX_CELL_REFS;
213
+ if (curRefCell >= classBuilder.tlen()) {
214
+ classBuilder = classBuilder.tpush(begin_cell());
215
+ }
217
216
  }
218
217
  }
219
218
 
@@ -295,35 +294,35 @@ cell cl::nullObject() inline method_id {
295
294
  }
296
295
 
297
296
  ;;; ====================== Class Setter ======================
298
- int cl::getFieldType::asm(slice self, int fieldInfoOffset ) asm """
297
+ int cl::getFieldType::asm(slice self, int fieldInfoOffset) asm """
299
298
  // STACK [fieldInfoOffset, headerSlice]
300
299
  4 PUSHINT // STACK [_FIELD_TYPE_WIDTH, fieldInfoOffset, headerSlice]
301
300
  SDSUBSTR // STACK [substring]
302
301
  4 PLDU // STACK [2BitUnsignInt]
303
302
  """;
304
303
 
305
- int cl::getFieldCellIndex::asm(slice self, int fieldInfoOffset ) asm """
304
+ int cl::getFieldCellIndex::asm(slice self, int fieldInfoOffset) asm """
306
305
  4 ADDCONST // STACK [fieldInfoOffset + _FIELD_TYPE_WIDTH, headerSlice]
307
306
  2 PUSHINT // STACK [_CELL_ID_WIDTH, fieldInfoOffset + _FIELD_TYPE_WIDTH, headerSlice]
308
307
  SDSUBSTR // STACK [substring]
309
308
  2 PLDU // STACK [2BitUnsignInt]
310
309
  """;
311
310
 
312
- int cl::getFieldOffset::asm(slice self, int fieldInfoOffset ) asm """
311
+ int cl::getFieldOffset::asm(slice self, int fieldInfoOffset) asm """
313
312
  6 ADDCONST // STACK [fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH, headerSlice]
314
313
  10 PUSHINT // STACK [_DATA_OFFSET_WIDTH, fieldInfoOffset +_FIELD_TYPE_WIDTH + _CELL_ID_WIDTH, headerSlice]
315
314
  SDSUBSTR // STACK [substring]
316
315
  10 PLDU // STACK [10BitUnsignInt]
317
316
  """;
318
317
 
319
- int cl::getFieldCellOffset::asm(slice self, int fieldInfoOffset ) asm """
318
+ int cl::getFieldCellOffset::asm(slice self, int fieldInfoOffset) asm """
320
319
  16 ADDCONST // STACK [fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH + _DATA_OFFSET_WIDTH, headerSlice]
321
320
  2 PUSHINT // STACK [_REF_OFFSET_WIDTH, fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH + _DATA_OFFSET_WIDTH headerSlice]
322
321
  SDSUBSTR // STACK [substring]
323
322
  2 PLDU // STACK [10BitUnsignInt]
324
323
  """;
325
324
 
326
- int cl::preload_bits_offset_3::asm(int width1, slice self, int fieldOffset, int width2 ) asm """
325
+ int cl::preload_bits_offset_3::asm(int width1, slice self, int fieldOffset, int width2) asm """
327
326
  SDSUBSTR // STACK [substring]
328
327
  s1 XCHG0
329
328
  PLDUX // STACK [10BitUnsignInt] (CC +1 )
@@ -460,10 +459,6 @@ cell cl::get<cellRef>(cell $self, int fieldName) inline method_id {
460
459
  );
461
460
  }
462
461
 
463
- cell cl::getWithCell<cellRef>(cell $self, int fieldName) inline method_id {
464
- return $self.cl::get<cellRef>(fieldName);
465
- }
466
-
467
462
  cell cl::get<objRef>(cell $self, int fieldName) inline method_id {
468
463
  return cl::get<cellRef>($self, fieldName);
469
464
  }
@@ -523,6 +518,7 @@ int typeofField(cell $self, int fieldName) inline {
523
518
  }
524
519
 
525
520
  ;; returns -1 (true) if equal, otherwise the index of the first field that differs
521
+ ;; returns 16 if the types of the objects are not equal
526
522
  int compareObjectFields(cell $lhs, cell $rhs) impure inline {
527
523
  int malformed = cl::typeof($lhs) != cl::typeof($rhs);
528
524
  if (malformed) {
@@ -551,7 +547,8 @@ int compareObjectFields(cell $lhs, cell $rhs) impure inline {
551
547
  fieldIndex = INVALID_CLASS_MEMBER;
552
548
  }
553
549
  if (malformed) {
554
- str::console::log<int>("Malformed field: ", fieldIndex);
550
+ ~strdump("Malformed field");
551
+ ~dump(fieldIndex);
555
552
  return fieldIndex;
556
553
  }
557
554
  fieldIndex += 1;
@@ -634,17 +631,17 @@ slice _typeToStr(int fieldType) {
634
631
 
635
632
  ;;; ====================== Dictionary functions ======================
636
633
 
637
- slice uint256ToSlice(int val) inline method_id {
634
+ slice uint256ToSlice(int val) inline {
638
635
  return begin_cell().store_uint256(val).as_slice();
639
636
  }
640
637
 
641
- int sliceToUint256(slice s) inline method_id {
638
+ int sliceToUint256(slice s) inline {
642
639
  return s.preload_uint(256);
643
640
  }
644
641
 
645
642
  ;; override the insane behavior of TON to optimize out empty dictionaries
646
643
  ;; into a single bit
647
- cell cl::dict256::New() inline method_id {
644
+ cell cl::dict256::New() inline {
648
645
  return empty_cell();
649
646
  }
650
647
 
@@ -767,7 +764,7 @@ cell cl::dict256::delete(cell dict, int key) {
767
764
  return (-1, null());
768
765
  }
769
766
 
770
- int cl::dict256::size(cell dict) inline {
767
+ int cl::dict256::size(cell dict) inline method_id {
771
768
  int count = 0;
772
769
  (int pivot, _) = dict.cl::dict256::getMin<slice>();
773
770
  while (pivot >= 0) {
@@ -779,7 +776,7 @@ int cl::dict256::size(cell dict) inline {
779
776
 
780
777
  ;;; ====================== Nested Dict Helpers ======================
781
778
 
782
- forall X -> cell cl::nestedDict256::set(cell $self, int fieldName, int key, X val) inline method_id {
779
+ forall X -> cell cl::nestedDict256::set(cell $self, int fieldName, int key, X val) inline {
783
780
  return $self.cl::set(
784
781
  fieldName,
785
782
  $self
@@ -788,29 +785,29 @@ forall X -> cell cl::nestedDict256::set(cell $self, int fieldName, int key, X va
788
785
  );
789
786
  }
790
787
 
791
- cell cl::nestedDict256::setRef(cell $self, int fieldName, int key, cell val) inline method_id {
788
+ cell cl::nestedDict256::setRef(cell $self, int fieldName, int key, cell val) inline {
792
789
  return $self.cl::set(
793
790
  fieldName,
794
791
  $self.cl::get<dict256>(fieldName).cl::dict256::setRef(key, val)
795
792
  );
796
793
  }
797
794
 
798
- cell cl::nestedDict256::delete(cell $self, int fieldName, int key) inline method_id {
795
+ cell cl::nestedDict256::delete(cell $self, int fieldName, int key) inline {
799
796
  return $self.cl::set(
800
797
  fieldName,
801
798
  $self.cl::get<dict256>(fieldName).cl::dict256::delete(key)
802
799
  );
803
800
  }
804
801
 
805
- (int, int) cl::nestedDict256::get<uint256>(cell $self, int fieldName, int key) inline method_id {
802
+ (int, int) cl::nestedDict256::get<uint256>(cell $self, int fieldName, int key) inline {
806
803
  return $self.cl::get<dict256>(fieldName).cl::dict256::get<uint256>(key);
807
804
  }
808
805
 
809
- (slice, int) cl::nestedDict256::get<slice>(cell $self, int fieldName, int key) inline method_id {
806
+ (slice, int) cl::nestedDict256::get<slice>(cell $self, int fieldName, int key) inline {
810
807
  return $self.cl::get<dict256>(fieldName).cl::dict256::get(key);
811
808
  }
812
809
 
813
- (cell, int) cl::nestedDict256::get<cellRef>(cell $self, int fieldName, int key) inline method_id {
810
+ (cell, int) cl::nestedDict256::get<cellRef>(cell $self, int fieldName, int key) inline {
814
811
  (slice s, int exists) = $self.cl::get<dict256>(fieldName).cl::dict256::get(key);
815
812
  if (exists) {
816
813
  return (s.preload_first_ref(), exists);
@@ -1,6 +1,6 @@
1
1
  const int ERRORCODE_MASK = 0x7ff;
2
- const int CLASSLIB::ERROR::INVALID_FIELD_TYPE = "CLASSLIB::ERROR::INVALID_FIELD_TYPE"c & ERRORCODE_MASK;
3
- const int CLASSLIB::ERROR::WRONG_ORDER_CONSTRUCTOR = "CLASSLIB::ERROR::WRONG_ORDER_CONSTRUCTOR"c & ERRORCODE_MASK;
2
+ const int CLASSLIB::ERROR::INVALID_FIELD_TYPE = 1058;
3
+ const int CLASSLIB::ERROR::WRONG_ORDER_CONSTRUCTOR = 1059;
4
4
 
5
5
  const int MAX_U8 = 0xFF;
6
6
  const int MAX_U16 = 0xFFFF;
@@ -40,6 +40,8 @@
40
40
  tuple actions = null();
41
41
  if (op == BaseInterface::OP::INITIALIZE) {
42
42
  actions = initialize($md);
43
+ } elseif (op == BaseInterface::OP::EMPTY) {
44
+ actions = emptyActions();
43
45
  } else {
44
46
  assertInitialized();
45
47
  actions = _executeOpcode(op, $md);
@@ -0,0 +1,89 @@
1
+ #include "../utils.fc";
2
+
3
+ const int AddressList::addressBits = 256;
4
+ ;; you can create an address list from a tuple of addresses [integers]
5
+ cell AddressList::serialize(tuple addressList) impure inline {
6
+ tuple addressListBuilder = unsafeTuple([begin_cell()]);
7
+ int idx = 0;
8
+ while (idx < addressList.tlen()) {
9
+ builder curBuilder = addressListBuilder.at(addressListBuilder.tlen() - 1);
10
+ if ((curBuilder.builder_bits() + AddressList::addressBits) > MAX_CELL_BITS) {
11
+ addressListBuilder = addressListBuilder.tpush(begin_cell());
12
+ curBuilder = addressListBuilder.at(addressListBuilder.tlen() - 1);
13
+ }
14
+ addressListBuilder = addressListBuilder
15
+ .tset(
16
+ addressListBuilder.tlen() - 1,
17
+ curBuilder.store_uint256(addressList.int_at(idx))
18
+ );
19
+ idx = idx + 1;
20
+ }
21
+ builder ret = addressListBuilder~tpop();
22
+ while (addressListBuilder.tlen() > 0) {
23
+ builder head = addressListBuilder~tpop();
24
+ ret = head.store_ref(ret.end_cell());
25
+ }
26
+ return ret.end_cell();
27
+ }
28
+
29
+ ;; the "iterator" is the remaining slice
30
+ (slice, int) ~AddressList::next(slice addressListSlice) impure inline {
31
+ if (addressListSlice.slice_bits() == 0) {
32
+ if (addressListSlice.slice_refs_empty?()) {
33
+ return (addressListSlice, NULLADDRESS);
34
+ } else {
35
+ addressListSlice = addressListSlice.preload_first_ref().begin_parse();
36
+ }
37
+ }
38
+ return addressListSlice.load_uint256();
39
+ }
40
+
41
+ ;; Check that the addresslist is a valid linked list of addresses with no extra refs or bytes
42
+ int AddressList::isValid(cell addressList, int maxCount) {
43
+ slice addressListSlice = addressList.begin_parse();
44
+ int count = 0;
45
+ while (addressListSlice.slice_empty?() == false) {
46
+ (int bits, int refs) = addressListSlice.slice_bits_refs();
47
+ if ((refs > 1) | ((refs == 1) & ((bits % 256) != 0))) {
48
+ return false;
49
+ }
50
+ repeat (bits / 256) {
51
+ count += 1;
52
+ int address = addressListSlice~load_uint256();
53
+ if ((address == NULLADDRESS) | (count > maxCount)) {
54
+ return false;
55
+ }
56
+ }
57
+ if (addressListSlice.slice_refs() > 0) {
58
+ addressListSlice = addressListSlice.preload_first_ref().begin_parse();
59
+ }
60
+ }
61
+
62
+ return true;
63
+ }
64
+
65
+ int AddressList::includes(int address, slice addressListSlice) impure inline {
66
+ int storedAddress = addressListSlice~AddressList::next();
67
+ while (storedAddress > NULLADDRESS) {
68
+ if (storedAddress == address) {
69
+ return true;
70
+ }
71
+ storedAddress = addressListSlice~AddressList::next();
72
+ }
73
+ return false;
74
+ }
75
+
76
+ int AddressList::length(cell addressList) impure inline {
77
+ slice addressListSlice = addressList.begin_parse();
78
+ int count = 0;
79
+ int dvnAddress = addressListSlice~AddressList::next();
80
+ while (dvnAddress > NULLADDRESS) {
81
+ count += 1;
82
+ dvnAddress = addressListSlice~AddressList::next();
83
+ }
84
+ return count;
85
+ }
86
+
87
+ cell AddressList::empty() impure inline {
88
+ return empty_cell();
89
+ }
@@ -9,7 +9,7 @@ const int DeterministicInsertionCircularQueue::keyBits = 64;
9
9
 
10
10
  const int DeterministicInsertionCircularQueue::invalidKey = -1;
11
11
  const int DeterministicInsertionCircularQueue::invalidStatus = -1;
12
- const int DeterministicInsertionCircularQueue::ERROR::invalidObject = "DeterministicInsertionCircularQueue::ERROR::invalidObject"c & ERRORCODE_MASK;
12
+ const int DeterministicInsertionCircularQueue::ERROR::invalidObject = 1185;
13
13
 
14
14
  cell DeterministicInsertionCircularQueue::_buildLevel(int level, cell initialContents) inline {
15
15
  if (level == 0) {
@@ -10,7 +10,7 @@ const int POOO::NAME = "POOO"u;
10
10
  const int POOO::nextEmpty = 0;
11
11
  const int POOO::bitmap = 1;
12
12
 
13
- const int POOO::ERROR::negativeIndex = "POOO::ERROR::negativeIndex"c & ERRORCODE_MASK;
13
+ const int POOO::ERROR::negativeIndex = 1153;
14
14
 
15
15
  ;; Algorithm:
16
16
  ;; 1. Extract the first `index` bits from the original bitmap.
@@ -54,6 +54,30 @@ cell POOO::set(cell $self, int absoluteIndex) impure inline method_id {
54
54
  .cl::set(POOO::nextEmpty, nextEmpty + leadingOnes);
55
55
  }
56
56
 
57
+ cell POOO::unsafeSetBits(cell $self, int start, int end) impure inline method_id {
58
+ slice bitmapSlice = $self.cl::get<cellRef>(POOO::bitmap).begin_parse();
59
+ int nextEmpty = $self.cl::get<uint64>(POOO::nextEmpty);
60
+ int startIndex = start - nextEmpty;
61
+ int endIndex = end - nextEmpty;
62
+
63
+ (int leadingOnes, slice remainingBitmap) = ldones(
64
+ begin_cell()
65
+ .store_slice(scutfirst(bitmapSlice, startIndex, 0))
66
+ .store_ones(endIndex - startIndex)
67
+ .store_slice(scutlast(bitmapSlice, MAX_CELL_BITS - endIndex, 0))
68
+ .as_slice()
69
+ );
70
+ return $self
71
+ .cl::set(
72
+ POOO::bitmap,
73
+ begin_cell()
74
+ .store_slice(remainingBitmap)
75
+ .store_zeroes(leadingOnes)
76
+ .end_cell()
77
+ )
78
+ .cl::set(POOO::nextEmpty, nextEmpty + leadingOnes);
79
+ }
80
+
57
81
  cell POOO::New() inline method_id {
58
82
  return cl::declare(
59
83
  POOO::NAME,
@@ -24,6 +24,8 @@
24
24
  return ();
25
25
  } elseif (op == BaseInterface::OP::INITIALIZE) {
26
26
  assertOwner();
27
+ } elseif (op == BaseInterface::OP::EMPTY) {
28
+ return ();
27
29
  } else {
28
30
  _checkPermissions(op, $md);
29
31
  }
@@ -182,7 +182,7 @@ int check_data_signature(slice data, slice signature, int public_key) asm "CHKSI
182
182
  (int, int, int, int) compute_data_size?(cell c, int max_cells) asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT";
183
183
 
184
184
  ;;; A non-quiet version of [slice_compute_data_size?] that throws a cell overflow exception (8) on failure.
185
- (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT";
185
+ (int, int, int, int) slice_compute_data_size?(slice s, int max_cells) asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT";
186
186
 
187
187
  ;;; Throws an exception with exit_code excno if cond is not 0 (commented since implemented in compilator)
188
188
  ;; () throw_if(int excno, int cond) impure asm "THROWARGIF";