@townsq/mm-sdk 1.0.1

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 (390) hide show
  1. package/README.md +95 -0
  2. package/dist/chains/evm/common/constant/abi/arbitrum-node-interface-abi.d.ts +25 -0
  3. package/dist/chains/evm/common/constant/abi/arbitrum-node-interface-abi.js +18 -0
  4. package/dist/chains/evm/common/constant/abi/arbitrum-node-interface-abi.js.map +1 -0
  5. package/dist/chains/evm/common/constant/abi/bridge-router-abi.d.ts +1030 -0
  6. package/dist/chains/evm/common/constant/abi/bridge-router-abi.js +794 -0
  7. package/dist/chains/evm/common/constant/abi/bridge-router-abi.js.map +1 -0
  8. package/dist/chains/evm/common/constant/abi/ccip-data-adapter-abi.d.ts +796 -0
  9. package/dist/chains/evm/common/constant/abi/ccip-data-adapter-abi.js +622 -0
  10. package/dist/chains/evm/common/constant/abi/ccip-data-adapter-abi.js.map +1 -0
  11. package/dist/chains/evm/common/constant/abi/erc-20-abi.d.ts +235 -0
  12. package/dist/chains/evm/common/constant/abi/erc-20-abi.js +157 -0
  13. package/dist/chains/evm/common/constant/abi/erc-20-abi.js.map +1 -0
  14. package/dist/chains/evm/common/constant/abi/wormhole-data-adapter-abi.d.ts +821 -0
  15. package/dist/chains/evm/common/constant/abi/wormhole-data-adapter-abi.js +645 -0
  16. package/dist/chains/evm/common/constant/abi/wormhole-data-adapter-abi.js.map +1 -0
  17. package/dist/chains/evm/common/constant/abi/wormhole-relayer-abi.d.ts +783 -0
  18. package/dist/chains/evm/common/constant/abi/wormhole-relayer-abi.js +501 -0
  19. package/dist/chains/evm/common/constant/abi/wormhole-relayer-abi.js.map +1 -0
  20. package/dist/chains/evm/common/constant/chain.d.ts +128 -0
  21. package/dist/chains/evm/common/constant/chain.js +62 -0
  22. package/dist/chains/evm/common/constant/chain.js.map +1 -0
  23. package/dist/chains/evm/common/constant/contract.d.ts +9 -0
  24. package/dist/chains/evm/common/constant/contract.js +13 -0
  25. package/dist/chains/evm/common/constant/contract.js.map +1 -0
  26. package/dist/chains/evm/common/constant/tokens.d.ts +6 -0
  27. package/dist/chains/evm/common/constant/tokens.js +21 -0
  28. package/dist/chains/evm/common/constant/tokens.js.map +1 -0
  29. package/dist/chains/evm/common/types/chain.d.ts +9 -0
  30. package/dist/chains/evm/common/types/chain.js +2 -0
  31. package/dist/chains/evm/common/types/chain.js.map +1 -0
  32. package/dist/chains/evm/common/types/contract.d.ts +8 -0
  33. package/dist/chains/evm/common/types/contract.js +2 -0
  34. package/dist/chains/evm/common/types/contract.js.map +1 -0
  35. package/dist/chains/evm/common/types/gmp.d.ts +37 -0
  36. package/dist/chains/evm/common/types/gmp.js +2 -0
  37. package/dist/chains/evm/common/types/gmp.js.map +1 -0
  38. package/dist/chains/evm/common/types/module.d.ts +90 -0
  39. package/dist/chains/evm/common/types/module.js +2 -0
  40. package/dist/chains/evm/common/types/module.js.map +1 -0
  41. package/dist/chains/evm/common/types/token.d.ts +28 -0
  42. package/dist/chains/evm/common/types/token.js +2 -0
  43. package/dist/chains/evm/common/types/token.js.map +1 -0
  44. package/dist/chains/evm/common/utils/chain.d.ts +7 -0
  45. package/dist/chains/evm/common/utils/chain.js +24 -0
  46. package/dist/chains/evm/common/utils/chain.js.map +1 -0
  47. package/dist/chains/evm/common/utils/contract.d.ts +7387 -0
  48. package/dist/chains/evm/common/utils/contract.js +67 -0
  49. package/dist/chains/evm/common/utils/contract.js.map +1 -0
  50. package/dist/chains/evm/common/utils/gmp.d.ts +7 -0
  51. package/dist/chains/evm/common/utils/gmp.js +32 -0
  52. package/dist/chains/evm/common/utils/gmp.js.map +1 -0
  53. package/dist/chains/evm/common/utils/message.d.ts +21 -0
  54. package/dist/chains/evm/common/utils/message.js +426 -0
  55. package/dist/chains/evm/common/utils/message.js.map +1 -0
  56. package/dist/chains/evm/common/utils/provider.d.ts +5 -0
  57. package/dist/chains/evm/common/utils/provider.js +24 -0
  58. package/dist/chains/evm/common/utils/provider.js.map +1 -0
  59. package/dist/chains/evm/common/utils/tokens.d.ts +11 -0
  60. package/dist/chains/evm/common/utils/tokens.js +58 -0
  61. package/dist/chains/evm/common/utils/tokens.js.map +1 -0
  62. package/dist/chains/evm/hub/constants/abi/account-manager-abi.d.ts +945 -0
  63. package/dist/chains/evm/hub/constants/abi/account-manager-abi.js +709 -0
  64. package/dist/chains/evm/hub/constants/abi/account-manager-abi.js.map +1 -0
  65. package/dist/chains/evm/hub/constants/abi/bridge-router-hub-abi.d.ts +1062 -0
  66. package/dist/chains/evm/hub/constants/abi/bridge-router-hub-abi.js +816 -0
  67. package/dist/chains/evm/hub/constants/abi/bridge-router-hub-abi.js.map +1 -0
  68. package/dist/chains/evm/hub/constants/abi/hub-abi.d.ts +344 -0
  69. package/dist/chains/evm/hub/constants/abi/hub-abi.js +229 -0
  70. package/dist/chains/evm/hub/constants/abi/hub-abi.js.map +1 -0
  71. package/dist/chains/evm/hub/constants/abi/hub-pool-abi.d.ts +1999 -0
  72. package/dist/chains/evm/hub/constants/abi/hub-pool-abi.js +1558 -0
  73. package/dist/chains/evm/hub/constants/abi/hub-pool-abi.js.map +1 -0
  74. package/dist/chains/evm/hub/constants/abi/hub-rewards-v1-abi.d.ts +850 -0
  75. package/dist/chains/evm/hub/constants/abi/hub-rewards-v1-abi.js +649 -0
  76. package/dist/chains/evm/hub/constants/abi/hub-rewards-v1-abi.js.map +1 -0
  77. package/dist/chains/evm/hub/constants/abi/hub-rewards-v2-abi.d.ts +1213 -0
  78. package/dist/chains/evm/hub/constants/abi/hub-rewards-v2-abi.js +890 -0
  79. package/dist/chains/evm/hub/constants/abi/hub-rewards-v2-abi.js.map +1 -0
  80. package/dist/chains/evm/hub/constants/abi/loan-manager-abi.d.ts +1573 -0
  81. package/dist/chains/evm/hub/constants/abi/loan-manager-abi.js +1055 -0
  82. package/dist/chains/evm/hub/constants/abi/loan-manager-abi.js.map +1 -0
  83. package/dist/chains/evm/hub/constants/abi/node-manager-abi.d.ts +269 -0
  84. package/dist/chains/evm/hub/constants/abi/node-manager-abi.js +228 -0
  85. package/dist/chains/evm/hub/constants/abi/node-manager-abi.js.map +1 -0
  86. package/dist/chains/evm/hub/constants/abi/oracle-manager-abi.d.ts +495 -0
  87. package/dist/chains/evm/hub/constants/abi/oracle-manager-abi.js +391 -0
  88. package/dist/chains/evm/hub/constants/abi/oracle-manager-abi.js.map +1 -0
  89. package/dist/chains/evm/hub/constants/chain.d.ts +3 -0
  90. package/dist/chains/evm/hub/constants/chain.js +242 -0
  91. package/dist/chains/evm/hub/constants/chain.js.map +1 -0
  92. package/dist/chains/evm/hub/modules/index.d.ts +5 -0
  93. package/dist/chains/evm/hub/modules/index.js +6 -0
  94. package/dist/chains/evm/hub/modules/index.js.map +1 -0
  95. package/dist/chains/evm/hub/modules/ts-hub-account.d.ts +8 -0
  96. package/dist/chains/evm/hub/modules/ts-hub-account.js +75 -0
  97. package/dist/chains/evm/hub/modules/ts-hub-account.js.map +1 -0
  98. package/dist/chains/evm/hub/modules/ts-hub-gmp.d.ts +18 -0
  99. package/dist/chains/evm/hub/modules/ts-hub-gmp.js +98 -0
  100. package/dist/chains/evm/hub/modules/ts-hub-gmp.js.map +1 -0
  101. package/dist/chains/evm/hub/modules/ts-hub-loan.d.ts +27 -0
  102. package/dist/chains/evm/hub/modules/ts-hub-loan.js +484 -0
  103. package/dist/chains/evm/hub/modules/ts-hub-loan.js.map +1 -0
  104. package/dist/chains/evm/hub/modules/ts-hub-oracle.d.ts +8 -0
  105. package/dist/chains/evm/hub/modules/ts-hub-oracle.js +58 -0
  106. package/dist/chains/evm/hub/modules/ts-hub-oracle.js.map +1 -0
  107. package/dist/chains/evm/hub/modules/ts-hub-pool.d.ts +5 -0
  108. package/dist/chains/evm/hub/modules/ts-hub-pool.js +138 -0
  109. package/dist/chains/evm/hub/modules/ts-hub-pool.js.map +1 -0
  110. package/dist/chains/evm/hub/types/account.d.ts +23 -0
  111. package/dist/chains/evm/hub/types/account.js +2 -0
  112. package/dist/chains/evm/hub/types/account.js.map +1 -0
  113. package/dist/chains/evm/hub/types/chain.d.ts +20 -0
  114. package/dist/chains/evm/hub/types/chain.js +2 -0
  115. package/dist/chains/evm/hub/types/chain.js.map +1 -0
  116. package/dist/chains/evm/hub/types/loan.d.ts +148 -0
  117. package/dist/chains/evm/hub/types/loan.js +9 -0
  118. package/dist/chains/evm/hub/types/loan.js.map +1 -0
  119. package/dist/chains/evm/hub/types/oracle.d.ts +19 -0
  120. package/dist/chains/evm/hub/types/oracle.js +2 -0
  121. package/dist/chains/evm/hub/types/oracle.js.map +1 -0
  122. package/dist/chains/evm/hub/types/pool.d.ts +66 -0
  123. package/dist/chains/evm/hub/types/pool.js +2 -0
  124. package/dist/chains/evm/hub/types/pool.js.map +1 -0
  125. package/dist/chains/evm/hub/types/token.d.ts +9 -0
  126. package/dist/chains/evm/hub/types/token.js +2 -0
  127. package/dist/chains/evm/hub/types/token.js.map +1 -0
  128. package/dist/chains/evm/hub/utils/chain.d.ts +15 -0
  129. package/dist/chains/evm/hub/utils/chain.js +37 -0
  130. package/dist/chains/evm/hub/utils/chain.js.map +1 -0
  131. package/dist/chains/evm/hub/utils/contract.d.ts +26 -0
  132. package/dist/chains/evm/hub/utils/contract.js +76 -0
  133. package/dist/chains/evm/hub/utils/contract.js.map +1 -0
  134. package/dist/chains/evm/hub/utils/events.d.ts +23 -0
  135. package/dist/chains/evm/hub/utils/events.js +100 -0
  136. package/dist/chains/evm/hub/utils/events.js.map +1 -0
  137. package/dist/chains/evm/hub/utils/loan.d.ts +4 -0
  138. package/dist/chains/evm/hub/utils/loan.js +37 -0
  139. package/dist/chains/evm/hub/utils/loan.js.map +1 -0
  140. package/dist/chains/evm/spoke/constants/abi/bridge-router-spoke-abi.d.ts +1044 -0
  141. package/dist/chains/evm/spoke/constants/abi/bridge-router-spoke-abi.js +806 -0
  142. package/dist/chains/evm/spoke/constants/abi/bridge-router-spoke-abi.js.map +1 -0
  143. package/dist/chains/evm/spoke/constants/abi/spoke-common-abi.d.ts +1152 -0
  144. package/dist/chains/evm/spoke/constants/abi/spoke-common-abi.js +735 -0
  145. package/dist/chains/evm/spoke/constants/abi/spoke-common-abi.js.map +1 -0
  146. package/dist/chains/evm/spoke/constants/abi/spoke-rewards-v2-common-abi.d.ts +697 -0
  147. package/dist/chains/evm/spoke/constants/abi/spoke-rewards-v2-common-abi.js +501 -0
  148. package/dist/chains/evm/spoke/constants/abi/spoke-rewards-v2-common-abi.js.map +1 -0
  149. package/dist/chains/evm/spoke/constants/abi/spoke-token-abi.d.ts +986 -0
  150. package/dist/chains/evm/spoke/constants/abi/spoke-token-abi.js +705 -0
  151. package/dist/chains/evm/spoke/constants/abi/spoke-token-abi.js.map +1 -0
  152. package/dist/chains/evm/spoke/modules/index.d.ts +3 -0
  153. package/dist/chains/evm/spoke/modules/index.js +4 -0
  154. package/dist/chains/evm/spoke/modules/index.js.map +1 -0
  155. package/dist/chains/evm/spoke/modules/ts-evm-account.d.ts +18 -0
  156. package/dist/chains/evm/spoke/modules/ts-evm-account.js +141 -0
  157. package/dist/chains/evm/spoke/modules/ts-evm-account.js.map +1 -0
  158. package/dist/chains/evm/spoke/modules/ts-evm-gmp.d.ts +20 -0
  159. package/dist/chains/evm/spoke/modules/ts-evm-gmp.js +163 -0
  160. package/dist/chains/evm/spoke/modules/ts-evm-gmp.js.map +1 -0
  161. package/dist/chains/evm/spoke/modules/ts-evm-loan.d.ts +38 -0
  162. package/dist/chains/evm/spoke/modules/ts-evm-loan.js +461 -0
  163. package/dist/chains/evm/spoke/modules/ts-evm-loan.js.map +1 -0
  164. package/dist/chains/evm/spoke/types/pool.d.ts +7 -0
  165. package/dist/chains/evm/spoke/types/pool.js +2 -0
  166. package/dist/chains/evm/spoke/types/pool.js.map +1 -0
  167. package/dist/chains/evm/spoke/utils/contract.d.ts +18 -0
  168. package/dist/chains/evm/spoke/utils/contract.js +46 -0
  169. package/dist/chains/evm/spoke/utils/contract.js.map +1 -0
  170. package/dist/common/constants/adapter.d.ts +2 -0
  171. package/dist/common/constants/adapter.js +6 -0
  172. package/dist/common/constants/adapter.js.map +1 -0
  173. package/dist/common/constants/byte.d.ts +6 -0
  174. package/dist/common/constants/byte.js +7 -0
  175. package/dist/common/constants/byte.js.map +1 -0
  176. package/dist/common/constants/chain.d.ts +10 -0
  177. package/dist/common/constants/chain.js +224 -0
  178. package/dist/common/constants/chain.js.map +1 -0
  179. package/dist/common/constants/gmp.d.ts +3 -0
  180. package/dist/common/constants/gmp.js +10 -0
  181. package/dist/common/constants/gmp.js.map +1 -0
  182. package/dist/common/constants/lending.d.ts +2 -0
  183. package/dist/common/constants/lending.js +4 -0
  184. package/dist/common/constants/lending.js.map +1 -0
  185. package/dist/common/constants/message.d.ts +9 -0
  186. package/dist/common/constants/message.js +23 -0
  187. package/dist/common/constants/message.js.map +1 -0
  188. package/dist/common/constants/pool.d.ts +14 -0
  189. package/dist/common/constants/pool.js +24 -0
  190. package/dist/common/constants/pool.js.map +1 -0
  191. package/dist/common/types/adapter.d.ts +30 -0
  192. package/dist/common/types/adapter.js +7 -0
  193. package/dist/common/types/adapter.js.map +1 -0
  194. package/dist/common/types/address.d.ts +9 -0
  195. package/dist/common/types/address.js +2 -0
  196. package/dist/common/types/address.js.map +1 -0
  197. package/dist/common/types/brand.d.ts +6 -0
  198. package/dist/common/types/brand.js +2 -0
  199. package/dist/common/types/brand.js.map +1 -0
  200. package/dist/common/types/chain.d.ts +29 -0
  201. package/dist/common/types/chain.js +9 -0
  202. package/dist/common/types/chain.js.map +1 -0
  203. package/dist/common/types/core.d.ts +28 -0
  204. package/dist/common/types/core.js +2 -0
  205. package/dist/common/types/core.js.map +1 -0
  206. package/dist/common/types/gmp.d.ts +15 -0
  207. package/dist/common/types/gmp.js +6 -0
  208. package/dist/common/types/gmp.js.map +1 -0
  209. package/dist/common/types/lending.d.ts +20 -0
  210. package/dist/common/types/lending.js +13 -0
  211. package/dist/common/types/lending.js.map +1 -0
  212. package/dist/common/types/message.d.ts +280 -0
  213. package/dist/common/types/message.js +32 -0
  214. package/dist/common/types/message.js.map +1 -0
  215. package/dist/common/types/module.d.ts +20 -0
  216. package/dist/common/types/module.js +2 -0
  217. package/dist/common/types/module.js.map +1 -0
  218. package/dist/common/types/token.d.ts +49 -0
  219. package/dist/common/types/token.js +24 -0
  220. package/dist/common/types/token.js.map +1 -0
  221. package/dist/common/utils/adapter.d.ts +17 -0
  222. package/dist/common/utils/adapter.js +98 -0
  223. package/dist/common/utils/adapter.js.map +1 -0
  224. package/dist/common/utils/address.d.ts +6 -0
  225. package/dist/common/utils/address.js +32 -0
  226. package/dist/common/utils/address.js.map +1 -0
  227. package/dist/common/utils/bytes.d.ts +6 -0
  228. package/dist/common/utils/bytes.js +25 -0
  229. package/dist/common/utils/bytes.js.map +1 -0
  230. package/dist/common/utils/chain.d.ts +20 -0
  231. package/dist/common/utils/chain.js +79 -0
  232. package/dist/common/utils/chain.js.map +1 -0
  233. package/dist/common/utils/formulae.d.ts +19 -0
  234. package/dist/common/utils/formulae.js +118 -0
  235. package/dist/common/utils/formulae.js.map +1 -0
  236. package/dist/common/utils/gmp.d.ts +3 -0
  237. package/dist/common/utils/gmp.js +5 -0
  238. package/dist/common/utils/gmp.js.map +1 -0
  239. package/dist/common/utils/lending.d.ts +7 -0
  240. package/dist/common/utils/lending.js +16 -0
  241. package/dist/common/utils/lending.js.map +1 -0
  242. package/dist/common/utils/math-lib.d.ts +10 -0
  243. package/dist/common/utils/math-lib.js +41 -0
  244. package/dist/common/utils/math-lib.js.map +1 -0
  245. package/dist/common/utils/messages.d.ts +16 -0
  246. package/dist/common/utils/messages.js +124 -0
  247. package/dist/common/utils/messages.js.map +1 -0
  248. package/dist/common/utils/token.d.ts +3 -0
  249. package/dist/common/utils/token.js +8 -0
  250. package/dist/common/utils/token.js.map +1 -0
  251. package/dist/common/utils/transaction.d.ts +4 -0
  252. package/dist/common/utils/transaction.js +18 -0
  253. package/dist/common/utils/transaction.js.map +1 -0
  254. package/dist/index.d.ts +38 -0
  255. package/dist/index.js +50 -0
  256. package/dist/index.js.map +1 -0
  257. package/dist/lifeline/core/ts-core.d.ts +24 -0
  258. package/dist/lifeline/core/ts-core.js +101 -0
  259. package/dist/lifeline/core/ts-core.js.map +1 -0
  260. package/dist/lifeline/modules/index.d.ts +5 -0
  261. package/dist/lifeline/modules/index.js +6 -0
  262. package/dist/lifeline/modules/index.js.map +1 -0
  263. package/dist/lifeline/modules/ts-account.d.ts +23 -0
  264. package/dist/lifeline/modules/ts-account.js +205 -0
  265. package/dist/lifeline/modules/ts-account.js.map +1 -0
  266. package/dist/lifeline/modules/ts-gmp.d.ts +3 -0
  267. package/dist/lifeline/modules/ts-gmp.js +4 -0
  268. package/dist/lifeline/modules/ts-gmp.js.map +1 -0
  269. package/dist/lifeline/modules/ts-loan.d.ts +48 -0
  270. package/dist/lifeline/modules/ts-loan.js +580 -0
  271. package/dist/lifeline/modules/ts-loan.js.map +1 -0
  272. package/dist/lifeline/modules/ts-oracle.d.ts +8 -0
  273. package/dist/lifeline/modules/ts-oracle.js +27 -0
  274. package/dist/lifeline/modules/ts-oracle.js.map +1 -0
  275. package/dist/lifeline/modules/ts-pool.d.ts +5 -0
  276. package/dist/lifeline/modules/ts-pool.js +8 -0
  277. package/dist/lifeline/modules/ts-pool.js.map +1 -0
  278. package/dist/types/generics.d.ts +1 -0
  279. package/dist/types/generics.js +2 -0
  280. package/dist/types/generics.js.map +1 -0
  281. package/dist/utils/address.d.ts +1 -0
  282. package/dist/utils/address.js +2 -0
  283. package/dist/utils/address.js.map +1 -0
  284. package/dist/utils/array.d.ts +3 -0
  285. package/dist/utils/array.js +7 -0
  286. package/dist/utils/array.js.map +1 -0
  287. package/dist/utils/exhaustive-check.d.ts +1 -0
  288. package/dist/utils/exhaustive-check.js +4 -0
  289. package/dist/utils/exhaustive-check.js.map +1 -0
  290. package/dist/utils/random.d.ts +1 -0
  291. package/dist/utils/random.js +4 -0
  292. package/dist/utils/random.js.map +1 -0
  293. package/package.json +56 -0
  294. package/src/chains/evm/common/constant/abi/arbitrum-node-interface-abi.ts +17 -0
  295. package/src/chains/evm/common/constant/abi/bridge-router-abi.ts +793 -0
  296. package/src/chains/evm/common/constant/abi/ccip-data-adapter-abi.ts +621 -0
  297. package/src/chains/evm/common/constant/abi/erc-20-abi.ts +156 -0
  298. package/src/chains/evm/common/constant/abi/wormhole-data-adapter-abi.ts +644 -0
  299. package/src/chains/evm/common/constant/abi/wormhole-relayer-abi.ts +500 -0
  300. package/src/chains/evm/common/constant/chain.ts +88 -0
  301. package/src/chains/evm/common/constant/contract.ts +15 -0
  302. package/src/chains/evm/common/constant/tokens.ts +33 -0
  303. package/src/chains/evm/common/types/chain.ts +26 -0
  304. package/src/chains/evm/common/types/contract.ts +17 -0
  305. package/src/chains/evm/common/types/gmp.ts +43 -0
  306. package/src/chains/evm/common/types/module.ts +115 -0
  307. package/src/chains/evm/common/types/token.ts +35 -0
  308. package/src/chains/evm/common/utils/chain.ts +33 -0
  309. package/src/chains/evm/common/utils/contract.ts +120 -0
  310. package/src/chains/evm/common/utils/gmp.ts +54 -0
  311. package/src/chains/evm/common/utils/message.ts +648 -0
  312. package/src/chains/evm/common/utils/provider.ts +38 -0
  313. package/src/chains/evm/common/utils/tokens.ts +102 -0
  314. package/src/chains/evm/hub/constants/abi/account-manager-abi.ts +708 -0
  315. package/src/chains/evm/hub/constants/abi/bridge-router-hub-abi.ts +815 -0
  316. package/src/chains/evm/hub/constants/abi/hub-abi.ts +228 -0
  317. package/src/chains/evm/hub/constants/abi/hub-pool-abi.ts +1557 -0
  318. package/src/chains/evm/hub/constants/abi/hub-rewards-v1-abi.ts +648 -0
  319. package/src/chains/evm/hub/constants/abi/hub-rewards-v2-abi.ts +889 -0
  320. package/src/chains/evm/hub/constants/abi/loan-manager-abi.ts +1054 -0
  321. package/src/chains/evm/hub/constants/abi/node-manager-abi.ts +227 -0
  322. package/src/chains/evm/hub/constants/abi/oracle-manager-abi.ts +390 -0
  323. package/src/chains/evm/hub/constants/chain.ts +305 -0
  324. package/src/chains/evm/hub/modules/index.ts +5 -0
  325. package/src/chains/evm/hub/modules/ts-hub-account.ts +117 -0
  326. package/src/chains/evm/hub/modules/ts-hub-gmp.ts +231 -0
  327. package/src/chains/evm/hub/modules/ts-hub-loan.ts +915 -0
  328. package/src/chains/evm/hub/modules/ts-hub-oracle.ts +131 -0
  329. package/src/chains/evm/hub/modules/ts-hub-pool.ts +241 -0
  330. package/src/chains/evm/hub/types/account.ts +30 -0
  331. package/src/chains/evm/hub/types/chain.ts +22 -0
  332. package/src/chains/evm/hub/types/loan.ts +188 -0
  333. package/src/chains/evm/hub/types/oracle.ts +25 -0
  334. package/src/chains/evm/hub/types/pool.ts +75 -0
  335. package/src/chains/evm/hub/types/token.ts +10 -0
  336. package/src/chains/evm/hub/utils/chain.ts +78 -0
  337. package/src/chains/evm/hub/utils/contract.ts +178 -0
  338. package/src/chains/evm/hub/utils/events.ts +160 -0
  339. package/src/chains/evm/hub/utils/loan.ts +72 -0
  340. package/src/chains/evm/spoke/constants/abi/bridge-router-spoke-abi.ts +805 -0
  341. package/src/chains/evm/spoke/constants/abi/spoke-common-abi.ts +734 -0
  342. package/src/chains/evm/spoke/constants/abi/spoke-rewards-v2-common-abi.ts +500 -0
  343. package/src/chains/evm/spoke/constants/abi/spoke-token-abi.ts +704 -0
  344. package/src/chains/evm/spoke/modules/index.ts +3 -0
  345. package/src/chains/evm/spoke/modules/ts-evm-account.ts +341 -0
  346. package/src/chains/evm/spoke/modules/ts-evm-gmp.ts +353 -0
  347. package/src/chains/evm/spoke/modules/ts-evm-loan.ts +1032 -0
  348. package/src/chains/evm/spoke/types/pool.ts +7 -0
  349. package/src/chains/evm/spoke/utils/contract.ts +123 -0
  350. package/src/common/constants/adapter.ts +6 -0
  351. package/src/common/constants/byte.ts +7 -0
  352. package/src/common/constants/chain.ts +319 -0
  353. package/src/common/constants/gmp.ts +19 -0
  354. package/src/common/constants/lending.ts +9 -0
  355. package/src/common/constants/message.ts +25 -0
  356. package/src/common/constants/pool.ts +30 -0
  357. package/src/common/types/adapter.ts +44 -0
  358. package/src/common/types/address.ts +11 -0
  359. package/src/common/types/brand.ts +3 -0
  360. package/src/common/types/chain.ts +42 -0
  361. package/src/common/types/core.ts +31 -0
  362. package/src/common/types/gmp.ts +19 -0
  363. package/src/common/types/lending.ts +26 -0
  364. package/src/common/types/message.ts +401 -0
  365. package/src/common/types/module.ts +46 -0
  366. package/src/common/types/token.ts +72 -0
  367. package/src/common/utils/adapter.ts +197 -0
  368. package/src/common/utils/address.ts +50 -0
  369. package/src/common/utils/bytes.ts +36 -0
  370. package/src/common/utils/chain.ts +163 -0
  371. package/src/common/utils/formulae.ts +270 -0
  372. package/src/common/utils/gmp.ts +8 -0
  373. package/src/common/utils/lending.ts +31 -0
  374. package/src/common/utils/math-lib.ts +50 -0
  375. package/src/common/utils/messages.ts +283 -0
  376. package/src/common/utils/token.ts +13 -0
  377. package/src/common/utils/transaction.ts +27 -0
  378. package/src/index.ts +73 -0
  379. package/src/lifeline/core/ts-core.ts +136 -0
  380. package/src/lifeline/modules/index.ts +5 -0
  381. package/src/lifeline/modules/ts-account.ts +420 -0
  382. package/src/lifeline/modules/ts-gmp.ts +5 -0
  383. package/src/lifeline/modules/ts-loan.ts +1268 -0
  384. package/src/lifeline/modules/ts-oracle.ts +68 -0
  385. package/src/lifeline/modules/ts-pool.ts +19 -0
  386. package/src/types/generics.ts +1 -0
  387. package/src/utils/address.ts +0 -0
  388. package/src/utils/array.ts +11 -0
  389. package/src/utils/exhaustive-check.ts +3 -0
  390. package/src/utils/random.ts +3 -0
@@ -0,0 +1,915 @@
1
+ import * as dn from 'dnum';
2
+ import { multicall } from 'viem/actions';
3
+
4
+ import { UINT256_LENGTH } from '../../../../common/constants/byte.js';
5
+ import { FINALITY } from '../../../../common/constants/message.js';
6
+ import { Action } from '../../../../common/types/message.js';
7
+ import { getRandomGenericAddress } from '../../../../common/utils/address.js';
8
+ import { convertNumberToBytes } from '../../../../common/utils/bytes.js';
9
+ import {
10
+ getSpokeChain,
11
+ getSpokeTokenData,
12
+ } from '../../../../common/utils/chain.js';
13
+ import {
14
+ calcBorrowAssetLoanValue,
15
+ calcBorrowBalance,
16
+ calcBorrowInterestIndex,
17
+ calcBorrowUtilisationRatio,
18
+ calcCollateralAssetLoanValue,
19
+ calcLiquidationMargin,
20
+ calcLtvRatio,
21
+ calcRewardIndex,
22
+ toFAmount,
23
+ toUnderlyingAmount,
24
+ } from '../../../../common/utils/formulae.js';
25
+ import {
26
+ bigIntMin,
27
+ compoundEverySecond,
28
+ increaseByPercent,
29
+ } from '../../../../common/utils/math-lib.js';
30
+ import { exhaustiveCheck } from '../../../../utils/exhaustive-check.js';
31
+ import {
32
+ defaultEventParams,
33
+ GAS_LIMIT_ESTIMATE_INCREASE,
34
+ RECEIVER_VALUE_SLIPPAGE,
35
+ UPDATE_USER_POINTS_IN_LOANS_GAS_LIMIT_SLIPPAGE,
36
+ } from '../../common/constant/contract.js';
37
+ import { getEvmSignerAccount } from '../../common/utils/chain.js';
38
+ import { extractRevertErrorName } from '../../common/utils/contract.js';
39
+ import {
40
+ buildEvmMessageData,
41
+ buildMessageParams,
42
+ buildMessagePayload,
43
+ buildSendTokenExtraArgsWhenRemoving,
44
+ } from '../../common/utils/message.js';
45
+ import { LoanChangeType } from '../types/loan.js';
46
+ import { getHubChain, getHubTokenData } from '../utils/chain.js';
47
+ import {
48
+ getBridgeRouterHubContract,
49
+ getHubContract,
50
+ getLoanControllerContract,
51
+ } from '../utils/contract.js';
52
+ import { fetchUserLoanIds } from '../utils/events.js';
53
+ import {
54
+ initLoanBorrowInterests,
55
+ updateLoanBorrowInterests,
56
+ } from '../utils/loan.js';
57
+
58
+ import type { EvmAddress } from '../../../../common/types/address.js';
59
+ import type { TSChainId, NetworkType } from '../../../../common/types/chain.js';
60
+ import type {
61
+ AccountId,
62
+ LoanId,
63
+ LoanTypeId,
64
+ } from '../../../../common/types/lending.js';
65
+ import type {
66
+ MessageAdapters,
67
+ MessageToSend,
68
+ OptionalFeeParams,
69
+ AdapterType,
70
+ LiquidateMessageData,
71
+ LiquidateMessageDataParams,
72
+ } from '../../../../common/types/message.js';
73
+ import type { TSTokenId } from '../../../../common/types/token.js';
74
+ import type {
75
+ PrepareLiquidateCall,
76
+ PrepareUpdateUserPointsInLoansCall,
77
+ } from '../../common/types/module.js';
78
+ import type { LoanControllerAbi } from '../constants/abi/loan-manager-abi.js';
79
+ import type { HubChain } from '../types/chain.js';
80
+ import type {
81
+ AssetsAdditionalInterest,
82
+ LoanChange,
83
+ LoanControllerUserLoan,
84
+ LoanControllerUserLoanAbi,
85
+ LoanPoolInfo,
86
+ LoanTypeInfo,
87
+ UserLoanInfo,
88
+ UserLoanInfoBorrow,
89
+ UserLoanInfoCollateral,
90
+ } from '../types/loan.js';
91
+ import type { OraclePrice, OraclePrices } from '../types/oracle.js';
92
+ import type { PoolInfo } from '../types/pool.js';
93
+ import type { HubTokenData } from '../types/token.js';
94
+ import type { Dnum } from 'dnum';
95
+ import type {
96
+ Client,
97
+ ContractFunctionParameters,
98
+ EstimateGasParameters,
99
+ ReadContractReturnType,
100
+ WalletClient,
101
+ } from 'viem';
102
+
103
+ export const prepare = {
104
+ async liquidate(
105
+ provider: Client,
106
+ sender: EvmAddress,
107
+ data: LiquidateMessageData,
108
+ accountId: AccountId,
109
+ hubChain: HubChain,
110
+ transactionOptions: EstimateGasParameters = {
111
+ account: sender,
112
+ }
113
+ ): Promise<PrepareLiquidateCall> {
114
+ const hub = getHubContract(provider, hubChain.hubAddress);
115
+
116
+ const liquidateMessageDataParams: LiquidateMessageDataParams = {
117
+ action: Action.Liquidate,
118
+ data,
119
+ extraArgs: '0x',
120
+ };
121
+
122
+ const messageData = buildEvmMessageData(liquidateMessageDataParams);
123
+
124
+ const gasLimit = await hub.estimateGas.directOperation(
125
+ [Action.Liquidate, accountId, messageData],
126
+ {
127
+ ...transactionOptions,
128
+ value: undefined,
129
+ }
130
+ );
131
+
132
+ return {
133
+ gasLimit: gasLimit + GAS_LIMIT_ESTIMATE_INCREASE,
134
+ hubAddress: hubChain.hubAddress,
135
+ messageData,
136
+ };
137
+ },
138
+ };
139
+
140
+ export const write = {
141
+ async liquidate(
142
+ provider: Client,
143
+ signer: WalletClient,
144
+ accountId: AccountId,
145
+ prepareCall: PrepareLiquidateCall
146
+ ) {
147
+ const {
148
+ gasLimit,
149
+ maxFeePerGas,
150
+ maxPriorityFeePerGas,
151
+ messageData,
152
+ hubAddress,
153
+ } = prepareCall;
154
+
155
+ const hub = getHubContract(provider, hubAddress, signer);
156
+
157
+ return await hub.write.directOperation(
158
+ [Action.Liquidate, accountId, messageData],
159
+ {
160
+ account: getEvmSignerAccount(signer),
161
+ chain: signer.chain,
162
+ maxFeePerGas,
163
+ maxPriorityFeePerGas,
164
+ gas: gasLimit,
165
+ }
166
+ );
167
+ },
168
+ };
169
+
170
+ export async function getSendTokenAdapterFees(
171
+ provider: Client,
172
+ network: NetworkType,
173
+ accountId: AccountId,
174
+ tsTokenId: TSTokenId,
175
+ amount: bigint,
176
+ receiverTsChainId: TSChainId,
177
+ adapters: MessageAdapters,
178
+ feeParams: OptionalFeeParams = {}
179
+ ): Promise<bigint> {
180
+ const hubChain = getHubChain(network);
181
+ const hubTokenData = getHubTokenData(tsTokenId, network);
182
+ const hubBridgeRouter = getBridgeRouterHubContract(
183
+ provider,
184
+ hubChain.hubMessageDispatcher
185
+ );
186
+
187
+ const spokeChain = getSpokeChain(receiverTsChainId, network);
188
+ const spokeTokenData = getSpokeTokenData(spokeChain, tsTokenId);
189
+
190
+ // construct return message
191
+ const returnParams = buildMessageParams({
192
+ adapters: {
193
+ adapterId: adapters.returnAdapterId,
194
+ returnAdapterId: 0 as AdapterType,
195
+ },
196
+ gasLimit: feeParams.returnGasLimit,
197
+ });
198
+ const returnMessage: MessageToSend = {
199
+ params: returnParams,
200
+ sender: hubChain.hubAddress,
201
+ destinationChainId: receiverTsChainId,
202
+ handler: getRandomGenericAddress(),
203
+ payload: buildMessagePayload(
204
+ Action.SendToken,
205
+ accountId,
206
+ getRandomGenericAddress(),
207
+ convertNumberToBytes(amount, UINT256_LENGTH)
208
+ ),
209
+ finalityLevel: FINALITY.FINALISED,
210
+ extraArgs: buildSendTokenExtraArgsWhenRemoving(
211
+ spokeTokenData.spokeAddress,
212
+ hubTokenData.token,
213
+ amount
214
+ ),
215
+ };
216
+
217
+ // get return adapter fee increased by 1%
218
+ return increaseByPercent(
219
+ await hubBridgeRouter.read.getSendFee([returnMessage]),
220
+ RECEIVER_VALUE_SLIPPAGE
221
+ );
222
+ }
223
+
224
+ export async function getLoanTypeInfo(
225
+ provider: Client,
226
+ network: NetworkType,
227
+ loanTypeId: LoanTypeId,
228
+ tokens: Array<HubTokenData>
229
+ ): Promise<LoanTypeInfo> {
230
+ const hubChain = getHubChain(network);
231
+ const loanController = getLoanControllerContract(
232
+ provider,
233
+ hubChain.loanControllerAddress
234
+ );
235
+
236
+ const getLoanPools: Array<ContractFunctionParameters> = tokens.map(
237
+ (token) => ({
238
+ address: loanController.address,
239
+ abi: loanController.abi,
240
+ functionName: 'getLoanPool',
241
+ args: [loanTypeId, token.poolId],
242
+ })
243
+ );
244
+
245
+ const [deprecated, loanTargetHealth, ...loanPools] = (await multicall(
246
+ provider,
247
+ {
248
+ contracts: [
249
+ {
250
+ address: loanController.address,
251
+ abi: loanController.abi,
252
+ functionName: 'isLoanTypeDeprecated',
253
+ args: [loanTypeId],
254
+ },
255
+ {
256
+ address: loanController.address,
257
+ abi: loanController.abi,
258
+ functionName: 'getLoanTypeLoanTargetHealth',
259
+ args: [loanTypeId],
260
+ },
261
+ ...getLoanPools,
262
+ ],
263
+ allowFailure: false,
264
+ }
265
+ )) as [
266
+ ReadContractReturnType<typeof LoanControllerAbi, 'isLoanTypeDeprecated'>,
267
+ ReadContractReturnType<
268
+ typeof LoanControllerAbi,
269
+ 'getLoanTypeLoanTargetHealth'
270
+ >,
271
+ ...Array<ReadContractReturnType<typeof LoanControllerAbi, 'getLoanPool'>>
272
+ ];
273
+
274
+ const pools: Partial<Record<TSTokenId, LoanPoolInfo>> = {};
275
+ for (const [
276
+ i,
277
+ {
278
+ collateralUsed,
279
+ borrowUsed,
280
+ collateralCap,
281
+ borrowCap,
282
+ collateralFactor,
283
+ borrowFactor,
284
+ liquidationBonus,
285
+ liquidationFee,
286
+ isDeprecated,
287
+ reward,
288
+ },
289
+ ] of loanPools.entries()) {
290
+ const token = tokens[i];
291
+
292
+ const {
293
+ lastUpdateTimestamp,
294
+ minimumAmount,
295
+ collateralSpeed,
296
+ borrowSpeed,
297
+ collateralRewardIndex: oldCollateralRewardIndex,
298
+ borrowRewardIndex: oldBorrowRewardIndex,
299
+ } = reward;
300
+
301
+ pools[token.TsTokenId] = {
302
+ tsTokenId: token.TsTokenId,
303
+ poolId: token.poolId,
304
+ collateralUsed,
305
+ borrowUsed,
306
+ collateralCap,
307
+ borrowCap,
308
+ collateralFactor: [BigInt(collateralFactor), 4],
309
+ borrowFactor: [BigInt(borrowFactor), 4],
310
+ liquidationBonus: [BigInt(liquidationBonus), 4],
311
+ liquidationFee: [BigInt(liquidationFee), 4],
312
+ isDeprecated,
313
+ reward: {
314
+ minimumAmount,
315
+ collateralSpeed: [BigInt(collateralSpeed), 18],
316
+ borrowSpeed: [BigInt(borrowSpeed), 18],
317
+ collateralRewardIndex: calcRewardIndex(
318
+ collateralUsed,
319
+ minimumAmount,
320
+ [BigInt(oldCollateralRewardIndex), 18],
321
+ [BigInt(collateralSpeed), 18],
322
+ lastUpdateTimestamp
323
+ ),
324
+ borrowRewardIndex: calcRewardIndex(
325
+ borrowUsed,
326
+ minimumAmount,
327
+ [BigInt(oldBorrowRewardIndex), 18],
328
+ [BigInt(borrowSpeed), 18],
329
+ lastUpdateTimestamp
330
+ ),
331
+ },
332
+ };
333
+ }
334
+
335
+ return {
336
+ loanTypeId,
337
+ deprecated,
338
+ loanTargetHealth: [BigInt(loanTargetHealth), 4],
339
+ pools,
340
+ };
341
+ }
342
+
343
+ export async function getUserLoanIds(
344
+ provider: Client,
345
+ network: NetworkType,
346
+ accountId: AccountId,
347
+ loanTypeIdsFilter?: Array<LoanTypeId>
348
+ ): Promise<Map<LoanTypeId, Array<LoanId>>> {
349
+ const hubChain = getHubChain(network);
350
+ const loanController = getLoanControllerContract(
351
+ provider,
352
+ hubChain.loanControllerAddress
353
+ );
354
+
355
+ return fetchUserLoanIds({
356
+ loanController,
357
+ accountId,
358
+ loanTypeIds: loanTypeIdsFilter,
359
+ eventParams: defaultEventParams,
360
+ });
361
+ }
362
+
363
+ export async function getUserLoans(
364
+ provider: Client,
365
+ network: NetworkType,
366
+ loanIds: Array<LoanId>,
367
+ throwErrorOnInactiveLoan: boolean
368
+ ): Promise<Map<LoanId, LoanControllerUserLoan>> {
369
+ const hubChain = getHubChain(network);
370
+ const loanController = getLoanControllerContract(
371
+ provider,
372
+ hubChain.loanControllerAddress
373
+ );
374
+
375
+ const getUserLoansCall: Array<ContractFunctionParameters> = loanIds.map(
376
+ (loanId) => ({
377
+ address: loanController.address,
378
+ abi: loanController.abi,
379
+ functionName: 'retrieveUserLoan',
380
+ args: [loanId],
381
+ })
382
+ );
383
+
384
+ const userLoans = await multicall(provider, {
385
+ contracts: getUserLoansCall,
386
+ allowFailure: true,
387
+ });
388
+
389
+ const userLoansMap = new Map<LoanId, LoanControllerUserLoan>();
390
+ for (const [i, loanId] of loanIds.entries()) {
391
+ const { status, error, result } = userLoans[i];
392
+ if (status === 'failure') {
393
+ // if the error is not on inactive loan then throw error regardless
394
+ const errorName = extractRevertErrorName(error);
395
+ if (errorName !== 'UserLoanInactive' || throwErrorOnInactiveLoan)
396
+ throw error;
397
+ } else {
398
+ const userLoan = result as LoanControllerUserLoanAbi;
399
+ userLoansMap.set(loanId, {
400
+ accountId: userLoan[0] as AccountId,
401
+ loanTypeId: userLoan[1] as LoanTypeId,
402
+ colPools: Array.from(userLoan[2]),
403
+ borPools: Array.from(userLoan[3]),
404
+ userLoanCollateral: Array.from(userLoan[4]),
405
+ userLoanBorrow: Array.from(userLoan[5]),
406
+ });
407
+ }
408
+ }
409
+ return userLoansMap;
410
+ }
411
+
412
+ export function getUserLoansInfo(
413
+ userLoansMap: Map<LoanId, LoanControllerUserLoan>,
414
+ poolsInfo: Partial<Record<TSTokenId, PoolInfo>>,
415
+ loanTypesInfo: Partial<Record<LoanTypeId, LoanTypeInfo>>,
416
+ oraclePrices: OraclePrices,
417
+ additionalInterests?: AssetsAdditionalInterest
418
+ ): Record<LoanId, UserLoanInfo> {
419
+ const poolIdToTsTokenId = new Map(
420
+ Object.values(poolsInfo).map(({ tsTokenId, poolId }) => [poolId, tsTokenId])
421
+ );
422
+
423
+ const userLoansInfo: Record<LoanId, UserLoanInfo> = {};
424
+
425
+ for (const [loanId, userLoan] of userLoansMap.entries()) {
426
+ userLoan.borPools.filter((poolId) => poolIdToTsTokenId.has(poolId));
427
+ userLoan.colPools.filter((poolId) => poolIdToTsTokenId.has(poolId));
428
+
429
+ const {
430
+ accountId,
431
+ loanTypeId,
432
+ colPools,
433
+ borPools,
434
+ userLoanCollateral,
435
+ userLoanBorrow,
436
+ } = userLoan;
437
+
438
+ const loanTypeInfo = loanTypesInfo[loanTypeId];
439
+ if (!loanTypeInfo) throw new Error(`Unknown loan type id ${loanTypeId}`);
440
+
441
+ // common to collaterals and borrows
442
+ let netRate = dn.from(0, 18);
443
+ let netYield = dn.from(0, 18);
444
+
445
+ // collaterals
446
+ const collaterals: Partial<Record<TSTokenId, UserLoanInfoCollateral>> = {};
447
+ let totalCollateralBalanceValue: Dnum = dn.from(0, 8);
448
+ let totalEffectiveCollateralBalanceValue: Dnum = dn.from(0, 8);
449
+ for (const [
450
+ j,
451
+ { balance: fTokenBalance },
452
+ ] of userLoanCollateral.entries()) {
453
+ const poolId = colPools[j];
454
+
455
+ const tsTokenId = poolIdToTsTokenId.get(poolId);
456
+ if (!tsTokenId) throw new Error(`Unknown pool id ${poolId}`);
457
+
458
+ const rewardsApr = dn.from(0, 18);
459
+
460
+ const poolInfo = poolsInfo[tsTokenId];
461
+ const loanPoolInfo = loanTypeInfo.pools[tsTokenId];
462
+ const oraclePrice = oraclePrices[tsTokenId];
463
+ if (!poolInfo || !loanPoolInfo || !oraclePrice)
464
+ throw new Error(`Unknown token id ${tsTokenId}`);
465
+ const { price: tokenPrice, decimals: tokenPriceDecimals } = oraclePrice;
466
+
467
+ const { tokenDecimals, depositData } = poolInfo;
468
+ const { interestRate, interestIndex, interestYield } = depositData;
469
+ const { collateralFactor } = loanPoolInfo;
470
+
471
+ const tokenBalance = toUnderlyingAmount(fTokenBalance, interestIndex);
472
+ const balanceValue = calcCollateralAssetLoanValue(
473
+ tokenBalance,
474
+ tokenPrice,
475
+ tokenPriceDecimals,
476
+ dn.from(1, 4)
477
+ );
478
+ const effectiveBalanceValue = calcCollateralAssetLoanValue(
479
+ tokenBalance,
480
+ tokenPrice,
481
+ tokenPriceDecimals,
482
+ collateralFactor
483
+ );
484
+
485
+ totalCollateralBalanceValue = dn.add(
486
+ totalCollateralBalanceValue,
487
+ balanceValue
488
+ );
489
+ totalEffectiveCollateralBalanceValue = dn.add(
490
+ totalEffectiveCollateralBalanceValue,
491
+ effectiveBalanceValue
492
+ );
493
+ netRate = dn.add(
494
+ netRate,
495
+ dn.mul(balanceValue, dn.add(interestRate, rewardsApr))
496
+ );
497
+ netYield = dn.add(
498
+ netYield,
499
+ dn.mul(balanceValue, dn.add(interestYield, rewardsApr))
500
+ );
501
+
502
+ // add additional interests if specified
503
+ const additionalInterest = additionalInterests?.[tsTokenId];
504
+ if (additionalInterest) {
505
+ const { additionalRate, additionalYield } = additionalInterest;
506
+ netRate = dn.add(netRate, dn.mul(balanceValue, additionalRate));
507
+ netYield = dn.add(netYield, dn.mul(balanceValue, additionalYield));
508
+ }
509
+
510
+ collaterals[tsTokenId] = {
511
+ tsTokenId,
512
+ poolId,
513
+ tokenDecimals,
514
+ oraclePrice,
515
+ collateralFactor,
516
+ fTokenBalance,
517
+ tokenBalance,
518
+ balanceValue,
519
+ effectiveBalanceValue,
520
+ interestRate,
521
+ interestYield,
522
+ };
523
+ }
524
+
525
+ // borrows
526
+ const borrows: Partial<Record<TSTokenId, UserLoanInfoBorrow>> = {};
527
+ let totalBorrowedAmountValue: Dnum = dn.from(0, 8);
528
+ let totalBorrowBalanceValue: Dnum = dn.from(0, 8);
529
+ let totalEffectiveBorrowBalanceValue: Dnum = dn.from(0, 8);
530
+ for (const [
531
+ j,
532
+ {
533
+ amount: borrowedAmount,
534
+ balance: oldBorrowBalance,
535
+ lastInterestIndex: lii,
536
+ stableInterestRate: sbir,
537
+ lastStableUpdateTimestamp,
538
+ },
539
+ ] of userLoanBorrow.entries()) {
540
+ const poolId = borPools[j];
541
+
542
+ const lastBorrowInterestIndex: Dnum = [lii, 18];
543
+ const stableBorrowInterestRate: Dnum = [sbir, 18];
544
+
545
+ const tsTokenId = poolIdToTsTokenId.get(poolId);
546
+ if (!tsTokenId) throw new Error(`Unknown pool id ${poolId}`);
547
+
548
+ const poolInfo = poolsInfo[tsTokenId];
549
+ const loanPoolInfo = loanTypeInfo.pools[tsTokenId];
550
+ const oraclePrice = oraclePrices[tsTokenId];
551
+ if (!poolInfo || !loanPoolInfo || !oraclePrice)
552
+ throw new Error(`Unknown townsq token id ${tsTokenId}`);
553
+ const { price: tokenPrice, decimals: tokenPriceDecimals } = oraclePrice;
554
+
555
+ const { tokenDecimals, variableBorrowData } = poolInfo;
556
+ const {
557
+ interestRate: variableBorrowInterestRate,
558
+ interestIndex: variableBorrowInterestIndex,
559
+ } = variableBorrowData;
560
+ const { borrowFactor } = loanPoolInfo;
561
+
562
+ const isStable = lastStableUpdateTimestamp > 0n;
563
+ const bororwInterestIndex = isStable
564
+ ? calcBorrowInterestIndex(
565
+ stableBorrowInterestRate,
566
+ lastBorrowInterestIndex,
567
+ lastStableUpdateTimestamp
568
+ )
569
+ : variableBorrowInterestIndex;
570
+ const borrowedAmountValue = calcBorrowAssetLoanValue(
571
+ borrowedAmount,
572
+ tokenPrice,
573
+ tokenPriceDecimals,
574
+ dn.from(1, 4)
575
+ );
576
+ const borrowBalance = calcBorrowBalance(
577
+ oldBorrowBalance,
578
+ bororwInterestIndex,
579
+ lastBorrowInterestIndex
580
+ );
581
+ const borrowBalanceValue = calcBorrowAssetLoanValue(
582
+ borrowBalance,
583
+ tokenPrice,
584
+ tokenPriceDecimals,
585
+ dn.from(1, 4)
586
+ );
587
+ const effectiveBorrowBalanceValue = calcBorrowAssetLoanValue(
588
+ borrowBalance,
589
+ tokenPrice,
590
+ tokenPriceDecimals,
591
+ borrowFactor
592
+ );
593
+ const accruedInterest = borrowBalance - borrowedAmount;
594
+ const accruedInterestValue = dn.sub(
595
+ borrowBalanceValue,
596
+ borrowedAmountValue
597
+ );
598
+ const interestRate = isStable
599
+ ? stableBorrowInterestRate
600
+ : variableBorrowInterestRate;
601
+ const interestYield = compoundEverySecond(interestRate);
602
+
603
+ totalBorrowedAmountValue = dn.add(
604
+ totalBorrowedAmountValue,
605
+ borrowedAmountValue
606
+ );
607
+ totalBorrowBalanceValue = dn.add(
608
+ totalBorrowBalanceValue,
609
+ borrowBalanceValue
610
+ );
611
+ totalEffectiveBorrowBalanceValue = dn.add(
612
+ totalEffectiveBorrowBalanceValue,
613
+ effectiveBorrowBalanceValue
614
+ );
615
+ netRate = dn.sub(netRate, dn.mul(borrowBalanceValue, interestRate));
616
+ netYield = dn.sub(netYield, dn.mul(borrowBalanceValue, interestYield));
617
+
618
+ // subtract additional interests if specified
619
+ const additionalInterest = additionalInterests?.[tsTokenId];
620
+ if (additionalInterest) {
621
+ const { additionalRate, additionalYield } = additionalInterest;
622
+ netRate = dn.sub(netRate, dn.mul(borrowBalanceValue, additionalRate));
623
+ netYield = dn.sub(
624
+ netYield,
625
+ dn.mul(borrowBalanceValue, additionalYield)
626
+ );
627
+ }
628
+
629
+ borrows[tsTokenId] = {
630
+ tsTokenId,
631
+ poolId,
632
+ tokenDecimals,
633
+ oraclePrice,
634
+ isStable,
635
+ borrowFactor,
636
+ borrowedAmount,
637
+ borrowedAmountValue,
638
+ borrowBalance,
639
+ borrowBalanceValue,
640
+ effectiveBorrowBalanceValue,
641
+ accruedInterest,
642
+ accruedInterestValue,
643
+ interestRate,
644
+ interestYield,
645
+ };
646
+ }
647
+
648
+ if (dn.greaterThan(totalCollateralBalanceValue, 0)) {
649
+ netRate = dn.div(netRate, totalCollateralBalanceValue);
650
+ netYield = dn.div(netYield, totalCollateralBalanceValue);
651
+ }
652
+
653
+ const loanToValueRatio = calcLtvRatio(
654
+ totalBorrowBalanceValue,
655
+ totalCollateralBalanceValue
656
+ );
657
+ const borrowUtilisationRatio = calcBorrowUtilisationRatio(
658
+ totalEffectiveBorrowBalanceValue,
659
+ totalEffectiveCollateralBalanceValue
660
+ );
661
+ const liquidationMargin = calcLiquidationMargin(
662
+ totalEffectiveBorrowBalanceValue,
663
+ totalEffectiveCollateralBalanceValue
664
+ );
665
+
666
+ userLoansInfo[loanId] = {
667
+ loanId,
668
+ loanTypeId,
669
+ accountId,
670
+ collaterals,
671
+ borrows,
672
+ netRate,
673
+ netYield,
674
+ totalCollateralBalanceValue,
675
+ totalBorrowedAmountValue,
676
+ totalBorrowBalanceValue,
677
+ totalEffectiveCollateralBalanceValue,
678
+ totalEffectiveBorrowBalanceValue,
679
+ loanToValueRatio,
680
+ borrowUtilisationRatio,
681
+ liquidationMargin,
682
+ };
683
+ }
684
+
685
+ return userLoansInfo;
686
+ }
687
+
688
+ export function simulateLoanChanges(
689
+ loan: LoanControllerUserLoan,
690
+ changes: Array<LoanChange>
691
+ ): LoanControllerUserLoan {
692
+ const {
693
+ accountId,
694
+ loanTypeId,
695
+ colPools,
696
+ borPools,
697
+ userLoanCollateral,
698
+ userLoanBorrow,
699
+ } = structuredClone(loan);
700
+
701
+ // simulate changes
702
+ for (const change of changes) {
703
+ const { type: changeType, poolInfo } = change;
704
+ switch (changeType) {
705
+ case LoanChangeType.AddCollateral: {
706
+ const colIndex = colPools.findIndex(
707
+ (poolId) => poolId === poolInfo.poolId
708
+ );
709
+ const { tsTokenAmount } = change;
710
+
711
+ if (colIndex === -1) {
712
+ // new collateral
713
+ colPools.push(poolInfo.poolId);
714
+ userLoanCollateral.push({ balance: tsTokenAmount, rewardIndex: 0n });
715
+ } else {
716
+ // existing collateral
717
+ userLoanCollateral[colIndex].balance += tsTokenAmount;
718
+ }
719
+ break;
720
+ }
721
+ case LoanChangeType.ReduceCollateral: {
722
+ const colIndex = colPools.findIndex(
723
+ (poolId) => poolId === poolInfo.poolId
724
+ );
725
+ if (colIndex === -1)
726
+ throw Error(`Cannot find collateral for pool ${poolInfo.poolId}`);
727
+ const { tsTokenAmount } = change;
728
+
729
+ const collateral = userLoanCollateral[colIndex];
730
+ collateral.balance -= tsTokenAmount;
731
+ if (collateral.balance < 0)
732
+ throw Error(`Insufficient collateral for pool ${poolInfo.poolId}`);
733
+ if (collateral.balance === 0n) {
734
+ colPools.splice(colIndex, 1);
735
+ userLoanCollateral.splice(colIndex, 1);
736
+ }
737
+ break;
738
+ }
739
+
740
+ case LoanChangeType.Borrow: {
741
+ const borIndex = borPools.findIndex(
742
+ (poolId) => poolId === poolInfo.poolId
743
+ );
744
+ const { tokenAmount, isStable } = change;
745
+
746
+ if (borIndex === -1) {
747
+ // new borrow
748
+ borPools.push(poolInfo.poolId);
749
+ const borrow = initLoanBorrowInterests(isStable, poolInfo);
750
+ borrow.amount = tokenAmount;
751
+ borrow.balance = tokenAmount;
752
+ userLoanBorrow.push(borrow);
753
+ } else {
754
+ // existing borrow
755
+ const borrow = userLoanBorrow[borIndex];
756
+ if (isStable !== borrow.stableInterestRate > 0)
757
+ throw Error(`Borrow type mismatch for pool ${poolInfo.poolId}`);
758
+
759
+ updateLoanBorrowInterests(borrow, tokenAmount, poolInfo, true);
760
+ borrow.amount += tokenAmount;
761
+ borrow.balance += tokenAmount;
762
+ }
763
+ break;
764
+ }
765
+ case LoanChangeType.Repay: {
766
+ const borIndex = borPools.findIndex(
767
+ (poolId) => poolId === poolInfo.poolId
768
+ );
769
+ if (borIndex === -1)
770
+ throw Error(`Cannot find borrow for pool ${poolInfo.poolId}`);
771
+ const { tokenAmount } = change;
772
+
773
+ const borrow = userLoanBorrow[borIndex];
774
+ updateLoanBorrowInterests(borrow, tokenAmount, poolInfo, false);
775
+ const balance = borrow.balance;
776
+ const interest = balance - borrow.amount;
777
+ const excessPaid = tokenAmount > balance ? tokenAmount - balance : 0n;
778
+ const interestPaid = bigIntMin(tokenAmount, interest);
779
+ const principalPaid = tokenAmount - interestPaid - excessPaid;
780
+ borrow.amount -= principalPaid;
781
+ borrow.balance -= principalPaid + interestPaid;
782
+ if (borrow.balance === 0n) {
783
+ borPools.splice(borIndex, 1);
784
+ userLoanBorrow.splice(borIndex, 1);
785
+ }
786
+ break;
787
+ }
788
+ case LoanChangeType.SwitchBorrowType: {
789
+ const borIndex = borPools.findIndex(
790
+ (poolId) => poolId === poolInfo.poolId
791
+ );
792
+ if (borIndex === -1)
793
+ throw Error(`Cannot find borrow for pool ${poolInfo.poolId}`);
794
+ const { isSwitchingToStable } = change;
795
+ if (
796
+ isSwitchingToStable ===
797
+ userLoanBorrow[borIndex].stableInterestRate > 0
798
+ )
799
+ throw Error(`Borrow type mismatch for pool ${poolInfo.poolId}`);
800
+
801
+ const { amount, balance } = updateLoanBorrowInterests(
802
+ userLoanBorrow[borIndex],
803
+ 0n,
804
+ poolInfo,
805
+ false
806
+ );
807
+ const borrow = initLoanBorrowInterests(isSwitchingToStable, poolInfo);
808
+ borrow.amount = amount;
809
+ borrow.balance = balance;
810
+ userLoanBorrow[borIndex] = borrow;
811
+ break;
812
+ }
813
+ default:
814
+ exhaustiveCheck(changeType);
815
+ break;
816
+ }
817
+ }
818
+
819
+ return {
820
+ accountId,
821
+ loanTypeId,
822
+ colPools,
823
+ borPools,
824
+ userLoanCollateral,
825
+ userLoanBorrow,
826
+ };
827
+ }
828
+
829
+ export function maxReduceBorrowForBorrowUtilisationRatio(
830
+ loan: UserLoanInfo,
831
+ reduceTsTokenId: TSTokenId,
832
+ depositInterestIndex: Dnum,
833
+ targetBorrowUtilisationRatio: Dnum
834
+ ): bigint {
835
+ const collateral = loan.collaterals[reduceTsTokenId];
836
+
837
+ // if could not find collateral or target is below actual, return 0
838
+ if (
839
+ !collateral ||
840
+ dn.lessThan(targetBorrowUtilisationRatio, loan.borrowUtilisationRatio)
841
+ )
842
+ return 0n;
843
+
844
+ const { price: tokenPrice, decimals: tokenPriceDecimals } =
845
+ collateral.oraclePrice;
846
+
847
+ // check if can reduce all collateral (special case as lack required precision otherwise)
848
+ const newEffectiveBalanceValue = dn.sub(
849
+ loan.totalEffectiveCollateralBalanceValue,
850
+ collateral.effectiveBalanceValue
851
+ );
852
+ const newBorrowUtilisationRatio = calcBorrowUtilisationRatio(
853
+ loan.totalEffectiveBorrowBalanceValue,
854
+ newEffectiveBalanceValue
855
+ );
856
+ if (
857
+ !(
858
+ dn.eq(newEffectiveBalanceValue, dn.from(0)) &&
859
+ dn.greaterThan(loan.totalEffectiveBorrowBalanceValue, dn.from(0))
860
+ ) &&
861
+ (dn.lessThan(newBorrowUtilisationRatio, targetBorrowUtilisationRatio) ||
862
+ dn.eq(newBorrowUtilisationRatio, targetBorrowUtilisationRatio))
863
+ )
864
+ return collateral.fTokenBalance;
865
+
866
+ // calculate max
867
+ const targetEffectiveCollateralBalanceValue = dn.div(
868
+ loan.totalEffectiveBorrowBalanceValue,
869
+ targetBorrowUtilisationRatio
870
+ );
871
+ const deltaEffectiveBalanceValue = dn.sub(
872
+ loan.totalEffectiveCollateralBalanceValue,
873
+ targetEffectiveCollateralBalanceValue
874
+ );
875
+ const deltaBalanceValue = dn.div(
876
+ deltaEffectiveBalanceValue,
877
+ collateral.collateralFactor
878
+ );
879
+ const deltaAssetBalance = dn.div(deltaBalanceValue, tokenPrice, {
880
+ decimals: tokenPriceDecimals,
881
+ });
882
+ const deltafAssetBalance = toFAmount(
883
+ deltaAssetBalance[0],
884
+ depositInterestIndex
885
+ );
886
+ return bigIntMin(deltafAssetBalance, collateral.fTokenBalance);
887
+ }
888
+
889
+ export function maxBorrowForBorrowUtilisationRatio(
890
+ loan: UserLoanInfo,
891
+ borrowFactor: Dnum,
892
+ oraclePrice: OraclePrice,
893
+ targetBorrowUtilisationRatio: Dnum
894
+ ): bigint {
895
+ const { price: tokenPrice, decimals: tokenPriceDecimals } = oraclePrice;
896
+
897
+ // if target is below actual, return 0
898
+ if (dn.lessThan(targetBorrowUtilisationRatio, loan.borrowUtilisationRatio))
899
+ return 0n;
900
+
901
+ // calculate max
902
+ const targetEffectiveBorrowBalanceValue = dn.mul(
903
+ loan.totalEffectiveCollateralBalanceValue,
904
+ targetBorrowUtilisationRatio
905
+ );
906
+ const deltaEffectiveBalanceValue = dn.sub(
907
+ targetEffectiveBorrowBalanceValue,
908
+ loan.totalEffectiveBorrowBalanceValue
909
+ );
910
+ const deltaBalanceValue = dn.div(deltaEffectiveBalanceValue, borrowFactor);
911
+ const deltaAssetBalance = dn.div(deltaBalanceValue, tokenPrice, {
912
+ decimals: tokenPriceDecimals,
913
+ });
914
+ return deltaAssetBalance[0];
915
+ }