@@ -15,6 +15,12 @@ import {IERC7786Receiver} from "../../interfaces/IERC7786.sol";
15
15
*
16
16
* The contract implements AxelarExecutable's {_execute} function to execute the message, converting Axelar's native
17
17
* workflow into the standard ERC-7786.
18
+ *
19
+ * NOTE: While both ERC-7786 and Axelar do support non-evm chains, this adaptor does not. This limitation comes from
20
+ * the translation of the ERC-7930 interoperable address (binary objects -- bytes) to strings. This is necessary
21
+ * because Axelar uses string to represend addresses. For EVM network, this adapter uses a checksum hex string
22
+ * representation. Other networks would require a different encoding. Ideally we would have a single encoding for all
23
+ * networks (could be base58, base64, ...) but Axelar doesn't support that.
18
24
*/
19
25
// slither-disable-next-line locked-ether
20
26
contract AxelarGatewayAdapter is IERC7786GatewaySource , Ownable , AxelarExecutable {
@@ -38,6 +44,7 @@ contract AxelarGatewayAdapter is IERC7786GatewaySource, Ownable, AxelarExecutabl
38
44
error UnsupportedNativeTransfer ();
39
45
error InvalidOriginGateway (string axelarSourceChain , string axelarSourceAddress );
40
46
error ReceiverExecutionFailed ();
47
+ error UnsupportedChainType (bytes2 chainType );
41
48
error UnsupportedERC7930Chain (bytes erc7930binary );
42
49
error UnsupportedAxelarChain (string axelar );
43
50
error InvalidChainIdentifier (bytes erc7930binary );
@@ -132,7 +139,7 @@ contract AxelarGatewayAdapter is IERC7786GatewaySource, Ownable, AxelarExecutabl
132
139
(bytes2 chainType , bytes calldata chainReference , ) = recipient.parseV1Calldata ();
133
140
bytes memory remoteGateway = getRemoteGateway (chainType, chainReference);
134
141
string memory axelarDestination = getAxelarChain (InteroperableAddress.formatV1 (chainType, chainReference, "" ));
135
- string memory axelarTarget = address ( bytes20 ( remoteGateway)). toChecksumHexString (); // TODO non-evm chains?
142
+ string memory axelarTarget = _stringifyAddress (chainType, remoteGateway);
136
143
137
144
gateway ().callContract (axelarDestination, axelarTarget, adapterPayload);
138
145
@@ -162,18 +169,31 @@ contract AxelarGatewayAdapter is IERC7786GatewaySource, Ownable, AxelarExecutabl
162
169
(bytes , bytes , bytes )
163
170
);
164
171
165
- // Axelar to ERC-7930 translation
166
- bytes memory addr = getRemoteGateway (getErc7930Chain (axelarSourceChain));
172
+ // variable lifecycle: avoid stack-too-deep
173
+ {
174
+ // Axelar to ERC-7930 translation
175
+ (bytes2 chainType , bytes memory chainReference , ) = getErc7930Chain (axelarSourceChain).parseV1 ();
176
+ bytes memory addr = getRemoteGateway (chainType, chainReference);
167
177
168
- // check message validity
169
- // - `axelarSourceAddress` is the remote gateway on the origin chain.
170
- require (
171
- address (bytes20 (addr)).toChecksumHexString ().equal (axelarSourceAddress), // TODO non-evm chains?
172
- InvalidOriginGateway (axelarSourceChain, axelarSourceAddress)
173
- );
178
+ // check message validity
179
+ // - `axelarSourceAddress` is the remote gateway on the origin chain.
180
+ require (
181
+ _stringifyAddress (chainType, addr).equal (axelarSourceAddress),
182
+ InvalidOriginGateway (axelarSourceChain, axelarSourceAddress)
183
+ );
184
+ }
174
185
175
186
(, address target ) = recipient.parseEvmV1 ();
176
187
bytes4 result = IERC7786Receiver (target).receiveMessage (commandId, sender, payload);
177
188
require (result == IERC7786Receiver .receiveMessage.selector , ReceiverExecutionFailed ());
178
189
}
190
+
191
+ /// @dev ERC-7930 to Axelar address translation. Currently only supports EVM chains.
192
+ function _stringifyAddress (bytes2 chainType , bytes memory addr ) internal virtual returns (string memory ) {
193
+ if (chainType == 0 ) {
194
+ return address (bytes20 (addr)).toChecksumHexString ();
195
+ } else {
196
+ revert UnsupportedChainType (chainType);
197
+ }
198
+ }
179
199
}
0 commit comments