@layerzerolabs/oft-adapter-starknet 0.2.9
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/Scarb.lock +190 -0
- package/Scarb.toml +4 -0
- package/contracts/oft_adapter/Scarb.toml +30 -0
- package/contracts/oft_adapter/src/lib.cairo +1 -0
- package/contracts/oft_adapter/src/oft_adapter.cairo +150 -0
- package/contracts/oft_adapter/tests/constants.cairo +3 -0
- package/contracts/oft_adapter/tests/lib.cairo +11 -0
- package/contracts/oft_adapter/tests/mocks/erc20/erc20.cairo +49 -0
- package/contracts/oft_adapter/tests/mocks/erc20/interface.cairo +8 -0
- package/contracts/oft_adapter/tests/mocks/message_inspector/message_inspector.cairo +17 -0
- package/contracts/oft_adapter/tests/test_oft_adapter.cairo +579 -0
- package/dist/3UUTAAI4.js +9 -0
- package/dist/3UUTAAI4.js.map +1 -0
- package/dist/4VIL37TM.cjs +14 -0
- package/dist/4VIL37TM.cjs.map +1 -0
- package/dist/5AQVVHK2.cjs +17 -0
- package/dist/5AQVVHK2.cjs.map +1 -0
- package/dist/6JUHMRLN.js +14 -0
- package/dist/6JUHMRLN.js.map +1 -0
- package/dist/B3SWU5G3.cjs +990 -0
- package/dist/B3SWU5G3.cjs.map +1 -0
- package/dist/E63KEOR5.cjs +11 -0
- package/dist/E63KEOR5.cjs.map +1 -0
- package/dist/HRRTIIZM.cjs +1282 -0
- package/dist/HRRTIIZM.cjs.map +1 -0
- package/dist/HTWTY64L.js +14 -0
- package/dist/HTWTY64L.js.map +1 -0
- package/dist/IH3YG4QY.js +12 -0
- package/dist/IH3YG4QY.js.map +1 -0
- package/dist/JFLNUTE2.js +988 -0
- package/dist/JFLNUTE2.js.map +1 -0
- package/dist/JNHB3COG.cjs +14 -0
- package/dist/JNHB3COG.cjs.map +1 -0
- package/dist/KGI5KEFS.js +1280 -0
- package/dist/KGI5KEFS.js.map +1 -0
- package/dist/KRS32YQY.cjs +17 -0
- package/dist/KRS32YQY.cjs.map +1 -0
- package/dist/RU2XCZGW.js +12 -0
- package/dist/RU2XCZGW.js.map +1 -0
- package/dist/generated/abi/o-f-t-adapter.cjs +13 -0
- package/dist/generated/abi/o-f-t-adapter.cjs.map +1 -0
- package/dist/generated/abi/o-f-t-adapter.d.ts +722 -0
- package/dist/generated/abi/o-f-t-adapter.d.ts.map +1 -0
- package/dist/generated/abi/o-f-t-adapter.js +4 -0
- package/dist/generated/abi/o-f-t-adapter.js.map +1 -0
- package/dist/generated/abi.cjs +14 -0
- package/dist/generated/abi.cjs.map +1 -0
- package/dist/generated/abi.d.ts +2 -0
- package/dist/generated/abi.d.ts.map +1 -0
- package/dist/generated/abi.js +5 -0
- package/dist/generated/abi.js.map +1 -0
- package/dist/generated/casm.cjs +13 -0
- package/dist/generated/casm.cjs.map +1 -0
- package/dist/generated/casm.d.ts +2 -0
- package/dist/generated/casm.d.ts.map +1 -0
- package/dist/generated/casm.js +4 -0
- package/dist/generated/casm.js.map +1 -0
- package/dist/generated/sierra.cjs +13 -0
- package/dist/generated/sierra.cjs.map +1 -0
- package/dist/generated/sierra.d.ts +2 -0
- package/dist/generated/sierra.d.ts.map +1 -0
- package/dist/generated/sierra.js +4 -0
- package/dist/generated/sierra.js.map +1 -0
- package/dist/generated/verification/index.cjs +14 -0
- package/dist/generated/verification/index.cjs.map +1 -0
- package/dist/generated/verification/index.d.ts +2 -0
- package/dist/generated/verification/index.d.ts.map +1 -0
- package/dist/generated/verification/index.js +5 -0
- package/dist/generated/verification/index.js.map +1 -0
- package/dist/generated/verification/oft_adapter.cjs +10 -0
- package/dist/generated/verification/oft_adapter.cjs.map +1 -0
- package/dist/generated/verification/oft_adapter.d.ts +4 -0
- package/dist/generated/verification/oft_adapter.d.ts.map +1 -0
- package/dist/generated/verification/oft_adapter.js +4 -0
- package/dist/generated/verification/oft_adapter.js.map +1 -0
- package/dist/index.cjs +30 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
package/Scarb.lock
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Code generated by scarb DO NOT EDIT.
|
|
2
|
+
version = 1
|
|
3
|
+
|
|
4
|
+
[[package]]
|
|
5
|
+
name = "enumerable_set"
|
|
6
|
+
version = "0.1.0"
|
|
7
|
+
|
|
8
|
+
[[package]]
|
|
9
|
+
name = "layerzero"
|
|
10
|
+
version = "0.1.0"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"enumerable_set",
|
|
13
|
+
"lz_utils",
|
|
14
|
+
"multisig",
|
|
15
|
+
"openzeppelin",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[[package]]
|
|
19
|
+
name = "lz_utils"
|
|
20
|
+
version = "0.1.0"
|
|
21
|
+
|
|
22
|
+
[[package]]
|
|
23
|
+
name = "multisig"
|
|
24
|
+
version = "0.1.0"
|
|
25
|
+
dependencies = [
|
|
26
|
+
"enumerable_set",
|
|
27
|
+
"lz_utils",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[[package]]
|
|
31
|
+
name = "oft_adapter"
|
|
32
|
+
version = "0.1.0"
|
|
33
|
+
dependencies = [
|
|
34
|
+
"layerzero",
|
|
35
|
+
"lz_utils",
|
|
36
|
+
"openzeppelin",
|
|
37
|
+
"snforge_std",
|
|
38
|
+
"starkware_utils_testing",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[[package]]
|
|
42
|
+
name = "openzeppelin"
|
|
43
|
+
version = "2.0.0"
|
|
44
|
+
source = "registry+https://scarbs.xyz/"
|
|
45
|
+
checksum = "sha256:5e4fdecc957cfca7854d95912dc72d9f725517c063b116512900900add29fd77"
|
|
46
|
+
dependencies = [
|
|
47
|
+
"openzeppelin_access",
|
|
48
|
+
"openzeppelin_account",
|
|
49
|
+
"openzeppelin_finance",
|
|
50
|
+
"openzeppelin_governance",
|
|
51
|
+
"openzeppelin_introspection",
|
|
52
|
+
"openzeppelin_merkle_tree",
|
|
53
|
+
"openzeppelin_presets",
|
|
54
|
+
"openzeppelin_security",
|
|
55
|
+
"openzeppelin_token",
|
|
56
|
+
"openzeppelin_upgrades",
|
|
57
|
+
"openzeppelin_utils",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[[package]]
|
|
61
|
+
name = "openzeppelin_access"
|
|
62
|
+
version = "2.0.0"
|
|
63
|
+
source = "registry+https://scarbs.xyz/"
|
|
64
|
+
checksum = "sha256:511681dd26d814ee2bc996d44ff8cb4aaa5ae9d14272130def7eb901cf004850"
|
|
65
|
+
dependencies = [
|
|
66
|
+
"openzeppelin_introspection",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[[package]]
|
|
70
|
+
name = "openzeppelin_account"
|
|
71
|
+
version = "2.0.0"
|
|
72
|
+
source = "registry+https://scarbs.xyz/"
|
|
73
|
+
checksum = "sha256:fb3381c50d68b028d3801feb43df378e2bd62137b6884844f8f60aefe796188b"
|
|
74
|
+
dependencies = [
|
|
75
|
+
"openzeppelin_introspection",
|
|
76
|
+
"openzeppelin_utils",
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
[[package]]
|
|
80
|
+
name = "openzeppelin_finance"
|
|
81
|
+
version = "2.0.0"
|
|
82
|
+
source = "registry+https://scarbs.xyz/"
|
|
83
|
+
checksum = "sha256:e9456ef69502a87c4c99bf50145351b50950f8b11244847d92935c466c4ba787"
|
|
84
|
+
dependencies = [
|
|
85
|
+
"openzeppelin_access",
|
|
86
|
+
"openzeppelin_token",
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
[[package]]
|
|
90
|
+
name = "openzeppelin_governance"
|
|
91
|
+
version = "2.0.0"
|
|
92
|
+
source = "registry+https://scarbs.xyz/"
|
|
93
|
+
checksum = "sha256:056e6d6f3d48193b53f06283884f8a9675f986fc85425f6a40e8c1aeb3b3ecfa"
|
|
94
|
+
dependencies = [
|
|
95
|
+
"openzeppelin_access",
|
|
96
|
+
"openzeppelin_account",
|
|
97
|
+
"openzeppelin_introspection",
|
|
98
|
+
"openzeppelin_token",
|
|
99
|
+
"openzeppelin_utils",
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
[[package]]
|
|
103
|
+
name = "openzeppelin_introspection"
|
|
104
|
+
version = "2.0.0"
|
|
105
|
+
source = "registry+https://scarbs.xyz/"
|
|
106
|
+
checksum = "sha256:87773ed6cd2318f169283ecbbb161890d1996260a80302d81ec45b70ee5e54c1"
|
|
107
|
+
|
|
108
|
+
[[package]]
|
|
109
|
+
name = "openzeppelin_merkle_tree"
|
|
110
|
+
version = "2.0.0"
|
|
111
|
+
source = "registry+https://scarbs.xyz/"
|
|
112
|
+
checksum = "sha256:47f80c9ce59557774243214f8e75c5e866f30f3d8daa755855f6ffd01c89ca89"
|
|
113
|
+
|
|
114
|
+
[[package]]
|
|
115
|
+
name = "openzeppelin_presets"
|
|
116
|
+
version = "2.0.0"
|
|
117
|
+
source = "registry+https://scarbs.xyz/"
|
|
118
|
+
checksum = "sha256:36c761ee923f1dc0887c0eab8c224b49ac242dbfe9163fbb0b08562042ab3d98"
|
|
119
|
+
dependencies = [
|
|
120
|
+
"openzeppelin_access",
|
|
121
|
+
"openzeppelin_account",
|
|
122
|
+
"openzeppelin_finance",
|
|
123
|
+
"openzeppelin_introspection",
|
|
124
|
+
"openzeppelin_token",
|
|
125
|
+
"openzeppelin_upgrades",
|
|
126
|
+
"openzeppelin_utils",
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
[[package]]
|
|
130
|
+
name = "openzeppelin_security"
|
|
131
|
+
version = "2.0.0"
|
|
132
|
+
source = "registry+https://scarbs.xyz/"
|
|
133
|
+
checksum = "sha256:902932ec296c2f400e0ac7c579edeaafd6067b6ce6d9854c1191de28e396ffe3"
|
|
134
|
+
|
|
135
|
+
[[package]]
|
|
136
|
+
name = "openzeppelin_token"
|
|
137
|
+
version = "2.0.0"
|
|
138
|
+
source = "registry+https://scarbs.xyz/"
|
|
139
|
+
checksum = "sha256:6fe61f63b5a6706018265fb7373b6e5bd3ff829bdc760b2b90296b1e708d180c"
|
|
140
|
+
dependencies = [
|
|
141
|
+
"openzeppelin_access",
|
|
142
|
+
"openzeppelin_account",
|
|
143
|
+
"openzeppelin_introspection",
|
|
144
|
+
"openzeppelin_utils",
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
[[package]]
|
|
148
|
+
name = "openzeppelin_upgrades"
|
|
149
|
+
version = "2.0.0"
|
|
150
|
+
source = "registry+https://scarbs.xyz/"
|
|
151
|
+
checksum = "sha256:560d57a9c3f3ec5a476e82fec8963c93c8df63a4ff9ff134f64ab8383bde3c61"
|
|
152
|
+
|
|
153
|
+
[[package]]
|
|
154
|
+
name = "openzeppelin_utils"
|
|
155
|
+
version = "2.0.0"
|
|
156
|
+
source = "registry+https://scarbs.xyz/"
|
|
157
|
+
checksum = "sha256:bf799c794139837f397975ffdf6a7ed5032d198bbf70e87a8f44f144a9dfc505"
|
|
158
|
+
|
|
159
|
+
[[package]]
|
|
160
|
+
name = "snforge_scarb_plugin"
|
|
161
|
+
version = "0.49.0"
|
|
162
|
+
source = "registry+https://scarbs.xyz/"
|
|
163
|
+
checksum = "sha256:903150f0e9542e4277d417029eea4c03af0db398b581f9f7ae3ebbdac9afc657"
|
|
164
|
+
|
|
165
|
+
[[package]]
|
|
166
|
+
name = "snforge_std"
|
|
167
|
+
version = "0.49.0"
|
|
168
|
+
source = "registry+https://scarbs.xyz/"
|
|
169
|
+
checksum = "sha256:73d73653cc4356ec51b92a6bec9d8385b20318170c2f2ade7891e5185a0e7e64"
|
|
170
|
+
dependencies = [
|
|
171
|
+
"snforge_scarb_plugin",
|
|
172
|
+
]
|
|
173
|
+
|
|
174
|
+
[[package]]
|
|
175
|
+
name = "starkware_utils"
|
|
176
|
+
version = "1.0.0"
|
|
177
|
+
source = "git+https://github.com/starkware-libs/starkware-starknet-utils?rev=e1955423808045de868987b8fb0b43f5cbdf5699#e1955423808045de868987b8fb0b43f5cbdf5699"
|
|
178
|
+
dependencies = [
|
|
179
|
+
"openzeppelin",
|
|
180
|
+
]
|
|
181
|
+
|
|
182
|
+
[[package]]
|
|
183
|
+
name = "starkware_utils_testing"
|
|
184
|
+
version = "1.0.0"
|
|
185
|
+
source = "git+https://github.com/starkware-libs/starkware-starknet-utils?rev=e1955423808045de868987b8fb0b43f5cbdf5699#e1955423808045de868987b8fb0b43f5cbdf5699"
|
|
186
|
+
dependencies = [
|
|
187
|
+
"openzeppelin",
|
|
188
|
+
"snforge_std",
|
|
189
|
+
"starkware_utils",
|
|
190
|
+
]
|
package/Scarb.toml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "oft_adapter"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2024_07"
|
|
5
|
+
|
|
6
|
+
# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html
|
|
7
|
+
|
|
8
|
+
[dependencies]
|
|
9
|
+
starknet = "2.14.0"
|
|
10
|
+
openzeppelin = "2.0.0"
|
|
11
|
+
lz_utils = { path = "../../node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils" }
|
|
12
|
+
layerzero = { path = "../../node_modules/@layerzerolabs/protocol-starknet-v2/layerzero" }
|
|
13
|
+
|
|
14
|
+
[dev-dependencies]
|
|
15
|
+
snforge_std = "0.49.0"
|
|
16
|
+
assert_macros = "2.12.0"
|
|
17
|
+
starkware_utils_testing = { git = "https://github.com/starkware-libs/starkware-starknet-utils", rev = "e1955423808045de868987b8fb0b43f5cbdf5699" }
|
|
18
|
+
|
|
19
|
+
[[target.starknet-contract]]
|
|
20
|
+
sierra = true
|
|
21
|
+
casm = true
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
[scripts]
|
|
25
|
+
test = "snforge test"
|
|
26
|
+
|
|
27
|
+
[tool.scarb]
|
|
28
|
+
allow-prebuilt-plugins = ["snforge_scarb_plugin", "snforge_std"]
|
|
29
|
+
|
|
30
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pub mod oft_adapter;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/// OFT Adapter Contract
|
|
2
|
+
/// Wraps an existing ERC20 token for cross-chain transfers using lock/unlock mechanism
|
|
3
|
+
#[starknet::contract]
|
|
4
|
+
pub mod OFTAdapter {
|
|
5
|
+
use layerzero::oapps::common::oapp_options_type_3::oapp_options_type_3::OAppOptionsType3Component;
|
|
6
|
+
use layerzero::oapps::oapp::oapp_core::OAppCoreComponent;
|
|
7
|
+
use layerzero::oapps::oft::errors::err_oft_transfer_failed;
|
|
8
|
+
use layerzero::oapps::oft::oft_core::default_oapp_hooks::OFTCoreOAppHooksDefaultImpl;
|
|
9
|
+
use layerzero::oapps::oft::oft_core::oft_core::OFTCoreComponent;
|
|
10
|
+
use layerzero::oapps::oft::structs::OFTDebit;
|
|
11
|
+
use lz_utils::error::assert_with_byte_array;
|
|
12
|
+
use openzeppelin::access::ownable::OwnableComponent;
|
|
13
|
+
use openzeppelin::token::erc20::interface::{
|
|
14
|
+
IERC20Dispatcher, IERC20DispatcherTrait, IERC20MetadataDispatcher,
|
|
15
|
+
IERC20MetadataDispatcherTrait,
|
|
16
|
+
};
|
|
17
|
+
use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};
|
|
18
|
+
use starknet::{ContractAddress, get_contract_address};
|
|
19
|
+
|
|
20
|
+
// Component declarations
|
|
21
|
+
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
|
|
22
|
+
component!(path: OAppCoreComponent, storage: oapp_core, event: OAppCoreEvent);
|
|
23
|
+
component!(path: OFTCoreComponent, storage: oft_core, event: OFTCoreEvent);
|
|
24
|
+
component!(
|
|
25
|
+
path: OAppOptionsType3Component, storage: oapp_options_type_3, event: OAppOptionsType3Event,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Ownable Mixin
|
|
29
|
+
#[abi(embed_v0)]
|
|
30
|
+
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;
|
|
31
|
+
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;
|
|
32
|
+
|
|
33
|
+
// OApp Core
|
|
34
|
+
#[abi(embed_v0)]
|
|
35
|
+
impl OAppCoreImpl = OAppCoreComponent::OAppCoreImpl<ContractState>;
|
|
36
|
+
impl OAppCoreInternalImpl = OAppCoreComponent::InternalImpl<ContractState>;
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
// OApp Receiver
|
|
40
|
+
#[abi(embed_v0)]
|
|
41
|
+
impl IOAppReceiverImpl = OAppCoreComponent::OAppReceiverImpl<ContractState>;
|
|
42
|
+
#[abi(embed_v0)]
|
|
43
|
+
impl ILayerZeroReceiverImpl =
|
|
44
|
+
OAppCoreComponent::LayerZeroReceiverImpl<ContractState>;
|
|
45
|
+
|
|
46
|
+
// OFT Core - embed the implementation
|
|
47
|
+
#[abi(embed_v0)]
|
|
48
|
+
impl OFTCoreImpl = OFTCoreComponent::OFTCoreImpl<ContractState>;
|
|
49
|
+
impl OFTCoreInternalImpl = OFTCoreComponent::InternalImpl<ContractState>;
|
|
50
|
+
|
|
51
|
+
const SHARED_DECIMALS: u8 = 6;
|
|
52
|
+
|
|
53
|
+
// OApp Options Type 3
|
|
54
|
+
#[abi(embed_v0)]
|
|
55
|
+
impl OAppOptionsType3Impl =
|
|
56
|
+
OAppOptionsType3Component::OAppOptionsType3Impl<ContractState>;
|
|
57
|
+
impl OAppOptionsType3InternalImpl = OAppOptionsType3Component::InternalImpl<ContractState>;
|
|
58
|
+
|
|
59
|
+
#[storage]
|
|
60
|
+
struct Storage {
|
|
61
|
+
#[substorage(v0)]
|
|
62
|
+
ownable: OwnableComponent::Storage,
|
|
63
|
+
#[substorage(v0)]
|
|
64
|
+
oapp_core: OAppCoreComponent::Storage,
|
|
65
|
+
#[substorage(v0)]
|
|
66
|
+
oft_core: OFTCoreComponent::Storage,
|
|
67
|
+
#[substorage(v0)]
|
|
68
|
+
oapp_options_type_3: OAppOptionsType3Component::Storage,
|
|
69
|
+
erc20_token: ContractAddress,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
#[event]
|
|
73
|
+
#[derive(Drop, starknet::Event)]
|
|
74
|
+
enum Event {
|
|
75
|
+
#[flat]
|
|
76
|
+
OwnableEvent: OwnableComponent::Event,
|
|
77
|
+
#[flat]
|
|
78
|
+
OAppCoreEvent: OAppCoreComponent::Event,
|
|
79
|
+
#[flat]
|
|
80
|
+
OFTCoreEvent: OFTCoreComponent::Event,
|
|
81
|
+
#[flat]
|
|
82
|
+
OAppOptionsType3Event: OAppOptionsType3Component::Event,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
#[constructor]
|
|
86
|
+
fn constructor(
|
|
87
|
+
ref self: ContractState,
|
|
88
|
+
erc20_token: ContractAddress,
|
|
89
|
+
lz_endpoint: ContractAddress,
|
|
90
|
+
owner: ContractAddress,
|
|
91
|
+
native_token: ContractAddress,
|
|
92
|
+
) {
|
|
93
|
+
// Initialize Ownable
|
|
94
|
+
self.ownable.initializer(owner);
|
|
95
|
+
|
|
96
|
+
// Initialize OApp Core
|
|
97
|
+
self.oapp_core.initializer(lz_endpoint, owner, native_token);
|
|
98
|
+
|
|
99
|
+
// Initialize token address
|
|
100
|
+
self.erc20_token.write(erc20_token);
|
|
101
|
+
|
|
102
|
+
// OFT Core needs to read local decimals from already deployed ERC20 token
|
|
103
|
+
let token_dispatcher = IERC20MetadataDispatcher { contract_address: erc20_token };
|
|
104
|
+
|
|
105
|
+
// Initialize OFT Core with local decimals
|
|
106
|
+
self.oft_core.initializer(token_dispatcher.decimals(), SHARED_DECIMALS);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Implement OFTHooks to provide the specific token operations
|
|
110
|
+
impl OFTHooks of OFTCoreComponent::OFTHooks<ContractState> {
|
|
111
|
+
fn _debit(
|
|
112
|
+
ref self: OFTCoreComponent::ComponentState<ContractState>,
|
|
113
|
+
from: ContractAddress,
|
|
114
|
+
amount: u256,
|
|
115
|
+
min_amount: u256,
|
|
116
|
+
dst_eid: u32,
|
|
117
|
+
) -> OFTDebit {
|
|
118
|
+
let oft_debit = self._debit_view(amount, min_amount, dst_eid);
|
|
119
|
+
|
|
120
|
+
// Lock tokens by transferring them from the caller to this contract
|
|
121
|
+
let success = IERC20Dispatcher { contract_address: self._token() }
|
|
122
|
+
.transfer_from(from, get_contract_address(), oft_debit.amount_sent_ld);
|
|
123
|
+
assert_with_byte_array(success, err_oft_transfer_failed());
|
|
124
|
+
|
|
125
|
+
oft_debit
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
fn _credit(
|
|
129
|
+
ref self: OFTCoreComponent::ComponentState<ContractState>,
|
|
130
|
+
to: ContractAddress,
|
|
131
|
+
amount: u256,
|
|
132
|
+
src_eid: u32,
|
|
133
|
+
) -> u256 {
|
|
134
|
+
// Unlock tokens by transferring them from this contract to the recipient
|
|
135
|
+
let success = IERC20Dispatcher { contract_address: self._token() }.transfer(to, amount);
|
|
136
|
+
assert_with_byte_array(success, err_oft_transfer_failed());
|
|
137
|
+
|
|
138
|
+
// Return the actual amount received (same as input in default implementation)
|
|
139
|
+
amount
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
fn _token(self: @OFTCoreComponent::ComponentState<ContractState>) -> ContractAddress {
|
|
143
|
+
self.get_contract().erc20_token.read()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
fn _approval_required(self: @OFTCoreComponent::ComponentState<ContractState>) -> bool {
|
|
147
|
+
true
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//! Mock ERC20 component for testing
|
|
2
|
+
|
|
3
|
+
#[starknet::contract]
|
|
4
|
+
pub mod MockERC20 {
|
|
5
|
+
use openzeppelin::token::erc20::{ERC20Component, ERC20HooksEmptyImpl};
|
|
6
|
+
use starknet::ContractAddress;
|
|
7
|
+
use crate::mocks::erc20::interface::IMockERC20;
|
|
8
|
+
|
|
9
|
+
component!(path: ERC20Component, storage: erc20, event: ERC20Event);
|
|
10
|
+
|
|
11
|
+
impl ERC20ImmutableConfig of ERC20Component::ImmutableConfig {
|
|
12
|
+
const DECIMALS: u8 = 18;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#[abi(embed_v0)]
|
|
16
|
+
impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl<ContractState>;
|
|
17
|
+
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;
|
|
18
|
+
|
|
19
|
+
#[storage]
|
|
20
|
+
struct Storage {
|
|
21
|
+
#[substorage(v0)]
|
|
22
|
+
erc20: ERC20Component::Storage,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#[event]
|
|
26
|
+
#[derive(Drop, starknet::Event)]
|
|
27
|
+
enum Event {
|
|
28
|
+
#[flat]
|
|
29
|
+
ERC20Event: ERC20Component::Event,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
#[constructor]
|
|
33
|
+
fn constructor(ref self: ContractState, initial_supply: u256, recipient: ContractAddress) {
|
|
34
|
+
let name = "MyToken";
|
|
35
|
+
let symbol = "MTK";
|
|
36
|
+
|
|
37
|
+
self.erc20.initializer(name, symbol);
|
|
38
|
+
self.erc20.mint(recipient, initial_supply);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#[abi(embed_v0)]
|
|
42
|
+
impl MockERC20Impl of IMockERC20<ContractState> {
|
|
43
|
+
fn mint(ref self: ContractState, recipient: ContractAddress, amount: u256) {
|
|
44
|
+
// This function is NOT protected which means
|
|
45
|
+
// ANYONE can mint tokens
|
|
46
|
+
self.erc20.mint(recipient, amount);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//! Mock Message Inspector component for testing
|
|
2
|
+
|
|
3
|
+
#[starknet::contract]
|
|
4
|
+
pub mod MockMessageInspector {
|
|
5
|
+
use core::panics::panic_with_byte_array;
|
|
6
|
+
use layerzero::oapps::message_inspector::interface::IMessageInspector;
|
|
7
|
+
|
|
8
|
+
#[storage]
|
|
9
|
+
struct Storage {}
|
|
10
|
+
|
|
11
|
+
#[abi(embed_v0)]
|
|
12
|
+
impl MockMessageInspectorImpl of IMessageInspector<ContractState> {
|
|
13
|
+
fn inspect_msg(self: @ContractState, message: ByteArray, options: ByteArray) -> bool {
|
|
14
|
+
panic_with_byte_array(@"Invalid message or options")
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|