Skip to content

Commit 665c4df

Browse files
authored
feat: off-chain quoting (#1)
* feat: off-chain quoting * rm: wsteth
1 parent 2139d1b commit 665c4df

File tree

8 files changed

+59
-469
lines changed

8 files changed

+59
-469
lines changed

src/axelar/AxelarTransceiver.sol

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
pragma solidity >=0.8.0 <0.9.0;
33

44
import "wormhole-solidity-sdk/Utils.sol";
5+
import "wormhole-solidity-sdk/libraries/BytesParsing.sol";
56

67
import {TransceiverStructs} from
78
"@wormhole-foundation/native_token_transfer/libraries/TransceiverStructs.sol";
@@ -21,9 +22,11 @@ import {ITransceiver} from "@wormhole-foundation/native_token_transfer/interface
2122
import {IAxelarTransceiver} from "./interfaces/IAxelarTransceiver.sol";
2223

2324
contract AxelarTransceiver is IAxelarTransceiver, AxelarGMPExecutable, Transceiver {
25+
using BytesParsing for bytes;
26+
2427
IAxelarGasService public immutable gasService;
2528

26-
string public constant AXELAR_TRANSCEIVER_VERSION = "1.1.0";
29+
string public constant AXELAR_TRANSCEIVER_VERSION = "2.0.0";
2730

2831
// These mappings are used to convert chainId and chainName between Wormhole and Axelar formats.
2932
struct AxelarTransceiverStorage {
@@ -37,9 +40,6 @@ contract AxelarTransceiver is IAxelarTransceiver, AxelarGMPExecutable, Transceiv
3740
bytes32 internal constant AXELAR_TRANSCEIVER_STORAGE_SLOT =
3841
0x6d72a7741b755e11bdb1cef6ed3f290bbe196e69da228a3ae322e5bc37ea7600;
3942

40-
// TODO: update this based on tests
41-
uint256 internal constant DESTINATION_EXECUTION_GAS_LIMIT = 200000;
42-
4343
constructor(
4444
address _gateway,
4545
address _gasService,
@@ -97,25 +97,35 @@ contract AxelarTransceiver is IAxelarTransceiver, AxelarGMPExecutable, Transceiv
9797
emit AxelarChainIdSet(chainId, chainName, transceiverAddress);
9898
}
9999

100+
/// @inheritdoc IAxelarTransceiver
101+
function parseAxelarTransceiverInstruction(
102+
bytes memory encoded
103+
) public pure returns (AxelarTransceiverInstruction memory instruction) {
104+
uint256 offset = 0;
105+
(instruction.estimatedMsgValue, offset) = encoded.asUint256Unchecked(offset);
106+
encoded.checkLength(offset);
107+
}
108+
109+
/// @inheritdoc IAxelarTransceiver
110+
function encodeAxelarTransceiverInstruction(
111+
AxelarTransceiverInstruction memory instruction
112+
) public pure returns (bytes memory) {
113+
return abi.encodePacked(instruction.estimatedMsgValue);
114+
}
115+
100116
/// @notice Fetch the delivery price for a given recipient chain transfer.
101-
/// @param recipientChainId The Wormhole chain ID of the target chain.
102-
/// param instruction An additional Instruction provided by the Transceiver to be
117+
/// param recipientChainId The Wormhole chain ID of the target chain.
118+
/// @param instruction An additional Instruction provided by the Transceiver to be
103119
/// executed on the recipient chain.
104120
/// @return deliveryPrice The cost of delivering a message to the recipient chain,
105121
/// in this chain's native token.
106122
function _quoteDeliveryPrice(
107-
uint16 recipientChainId,
108-
TransceiverStructs.TransceiverInstruction memory /*instruction*/
123+
uint16, /*recipientChainId*/
124+
TransceiverStructs.TransceiverInstruction memory instruction
109125
) internal view virtual override returns (uint256) {
110-
// Use the gas estimation from gas service
111-
AxelarTransceiverStorage storage slot = _storage();
112-
return gasService.estimateGasFee(
113-
slot.idToAxelarChainId[recipientChainId],
114-
slot.idToTransceiverAddress[recipientChainId],
115-
bytes(""),
116-
DESTINATION_EXECUTION_GAS_LIMIT,
117-
bytes("")
118-
);
126+
AxelarTransceiverInstruction memory axIns =
127+
parseAxelarTransceiverInstruction(instruction.payload);
128+
return axIns.estimatedMsgValue;
119129
}
120130

121131
/// @dev Send a message to another chain.

src/axelar/interfaces/IAxelarTransceiver.sol

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ pragma solidity >=0.8.0 <0.9.0;
44
import {ITransceiver} from "@wormhole-foundation/native_token_transfer/interfaces/ITransceiver.sol";
55

66
interface IAxelarTransceiver is ITransceiver {
7+
/// @notice The instruction for the WormholeTransceiver contract
8+
/// to skip delivery via the relayer.
9+
struct AxelarTransceiverInstruction {
10+
uint256 estimatedMsgValue;
11+
}
12+
713
/// @notice Chain is not supported.
814
/// @param chainId The wormhole chainId.
915
/// @param sourceChain The source chain axelar name.
@@ -54,4 +60,19 @@ interface IAxelarTransceiver is ITransceiver {
5460
string calldata chainName,
5561
string calldata transceiverAddress
5662
) external;
63+
64+
/// @notice Parses the encoded instruction and returns the instruction struct.
65+
/// This instruction is specific to the AxelarTransceiver contract.
66+
/// @param encoded The encoded instruction.
67+
/// @return instruction The parsed `AxelarTransceiverInstruction`.
68+
function parseAxelarTransceiverInstruction(
69+
bytes memory encoded
70+
) external pure returns (AxelarTransceiverInstruction memory instruction);
71+
72+
/// @notice Encodes the `AxelarTransceiverInstruction` into a byte array.
73+
/// @param instruction The `AxelarTransceiverInstruction` to encode.
74+
/// @return encoded The encoded instruction.
75+
function encodeAxelarTransceiverInstruction(
76+
AxelarTransceiverInstruction memory instruction
77+
) external pure returns (bytes memory);
5778
}

src/token/WstEthL2Token.sol

Lines changed: 0 additions & 118 deletions
This file was deleted.

test/axelar/AxelarTransceiver.t.sol

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import {TransceiverStructs} from
99
import {NttManager} from "@wormhole-foundation/native_token_transfer/NttManager/NttManager.sol";
1010
import {INttManager} from "@wormhole-foundation/native_token_transfer/interfaces/INttManager.sol";
1111
import {IManagerBase} from "@wormhole-foundation/native_token_transfer/interfaces/IManagerBase.sol";
12+
import {DummyTokenMintAndBurn} from
13+
"@wormhole-foundation/native_token_transfer/mocks/DummyToken.sol";
1214
import {ERC1967Proxy} from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol";
13-
import {WstEthL2Token} from "src/token/WstEthL2Token.sol";
14-
import {WstEthL2TokenHarness} from "test/token/WstEthL2TokenHarness.sol";
1515
import {Upgrades} from "script/lib/Upgrades.sol";
1616

1717
import "forge-std/console.sol";
@@ -41,21 +41,14 @@ contract AxelarTransceiverTest is Test {
4141
IAxelarGateway gateway;
4242
IAxelarGasService gasService;
4343
NttManager manager;
44-
WstEthL2TokenHarness token;
44+
DummyTokenMintAndBurn token;
4545

4646
function setUp() public {
4747
gateway = IAxelarGateway(new MockAxelarGateway());
4848
gasService = IAxelarGasService(address(new MockAxelarGasService()));
4949

5050
// Deploy the token
51-
address proxy = Upgrades.deployUUPSProxy(
52-
"out/ERC1967Proxy.sol/ERC1967Proxy.json",
53-
"WstEthL2TokenHarness.sol",
54-
abi.encodeCall(WstEthL2Token.initialize, ("Wrapped Staked Eth", "wstEth", OWNER))
55-
);
56-
vm.label(proxy, "Proxy");
57-
58-
token = WstEthL2TokenHarness(proxy);
51+
token = new DummyTokenMintAndBurn();
5952

6053
address managerImplementation = address(
6154
new NttManager(
@@ -232,8 +225,6 @@ contract AxelarTransceiverTest is Test {
232225
vm.prank(OWNER);
233226
transceiver.setAxelarChainId(chainId, chainName, axelarAddress);
234227
vm.prank(OWNER);
235-
token.setMinter(OWNER);
236-
vm.prank(OWNER);
237228
token.mint(address(manager), amount);
238229
gateway.approveContractCall(messageId, chainName, axelarAddress, keccak256(payload));
239230

test/axelar/AxelarTransceiverEndToEnd.sol

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import {TransceiverStructs} from
99
import {NttManager} from "@wormhole-foundation/native_token_transfer/NttManager/NttManager.sol";
1010
import {INttManager} from "@wormhole-foundation/native_token_transfer/interfaces/INttManager.sol";
1111
import {IManagerBase} from "@wormhole-foundation/native_token_transfer/interfaces/IManagerBase.sol";
12+
13+
import {DummyTokenMintAndBurn} from
14+
"@wormhole-foundation/native_token_transfer/mocks/DummyToken.sol";
1215
import {ERC1967Proxy} from "openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol";
13-
import {WstEthL2Token} from "src/token/WstEthL2Token.sol";
1416

1517
import "forge-std/console.sol";
1618
import "forge-std/Test.sol";
@@ -28,32 +30,20 @@ contract AxelarTransceiverEndToEnd is Test {
2830
IAxelarGateway gateway;
2931
IAxelarGasService gasService;
3032
NttManager sourceNttmanager;
31-
WstEthL2Token sourceToken;
33+
DummyTokenMintAndBurn sourceToken;
3234
uint16 sourceChainId;
3335

3436
AxelarTransceiver recipientTransceiver;
3537
NttManager recipientNttManager;
36-
WstEthL2Token recipientToken;
38+
DummyTokenMintAndBurn recipientToken;
3739
uint16 recipientChainId;
3840

3941
function setUp() public {
4042
gateway = IAxelarGateway(new MockAxelarGateway());
4143
gasService = IAxelarGasService(address(new MockAxelarGasService()));
4244
// Setup Source Infrastructure
4345
sourceChainId = 1;
44-
address tokenImplementaion = address(new WstEthL2Token());
45-
sourceToken = WstEthL2Token(
46-
address(
47-
new ERC1967Proxy(
48-
tokenImplementaion,
49-
abi.encodeWithSelector(
50-
WstEthL2Token.initialize.selector, "Source Token", "ST", OWNER
51-
)
52-
)
53-
)
54-
);
55-
vm.prank(OWNER);
56-
sourceToken.setMinter(OWNER);
46+
sourceToken = new DummyTokenMintAndBurn();
5747
address sourceManagerImplementation = address(
5848
new NttManager(
5949
address(sourceToken),
@@ -77,18 +67,7 @@ contract AxelarTransceiverEndToEnd is Test {
7767

7868
// Setup Recipient Infrastructure
7969
recipientChainId = 2;
80-
recipientToken = WstEthL2Token(
81-
address(
82-
new ERC1967Proxy(
83-
tokenImplementaion,
84-
abi.encodeWithSelector(
85-
WstEthL2Token.initialize.selector, "Source Token", "ST", OWNER
86-
)
87-
)
88-
)
89-
);
90-
vm.prank(OWNER);
91-
recipientToken.setMinter(OWNER);
70+
recipientToken = new DummyTokenMintAndBurn();
9271
address recipientManagerImplementation = address(
9372
new NttManager(
9473
address(recipientToken),

0 commit comments

Comments
 (0)