-
Notifications
You must be signed in to change notification settings - Fork 22
/
IbcReceiver.sol
173 lines (157 loc) · 7.23 KB
/
IbcReceiver.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright 2024, Polymer Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
pragma solidity ^0.8.9;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IbcDispatcher} from "./IbcDispatcher.sol";
import {ChannelOrder, IbcPacket, AckPacket} from "../libs/Ibc.sol";
/**
* @title IbcChannelReceiver
* @dev This interface must be implemented by IBC-enabled contracts that act as channel owners and process channel
* handshake callbacks.
*/
interface IbcChannelReceiver {
/**
* @notice Handles the channel open initialization event (step 1 of the open channel handshake)
* @dev Make sure to validate that the channel version is indeed one supported by the dapp; this callback should
* revert if not.
* @param version The version string provided by the counterparty
* @return selectedVersion The selected version string
*/
function onChanOpenInit(
ChannelOrder order,
string[] calldata connectionHops,
string calldata counterpartyPortIdentifier,
string calldata version
) external returns (string memory selectedVersion);
/**
* @notice Handles the channel open try event (step 2 of the open channel handshake)
* @dev Make sure to validate that the counterparty version is indeed one supported by the dapp; this callback
* should
* revert if not.
* @param counterpartyVersion The version string provided by the counterparty
* @return selectedVersion The selected version string
*/
function onChanOpenTry(
ChannelOrder order,
string[] memory connectionHops,
bytes32 channelId,
string memory counterpartyPortIdentifier,
bytes32 counterpartychannelId,
string memory counterpartyVersion
) external returns (string memory selectedVersion);
/**
* @notice Handles the channel open acknowledgment event (step 3 of the open channel handshake)
* @dev Make sure to validate channelId and counterpartyVersion
* @param channelId The unique identifier of the channel
* @param counterpartyVersion The version string provided by the counterparty
*/
function onChanOpenAck(bytes32 channelId, bytes32 counterpartychannelId, string calldata counterpartyVersion)
external;
/**
* @notice Handles the channel close init event
* @param channelId The unique identifier of the channel
* @dev Make sure to validate channelId and counterpartyVersion
* @param counterpartyPortId The unique identifier of the counterparty's port
* @param counterpartyChannelId The unique identifier of the counterparty's channel
*/
function onChanCloseInit(bytes32 channelId, string calldata counterpartyPortId, bytes32 counterpartyChannelId)
external;
/**
* @notice Handles the channel close confirmation event
* @param channelId The unique identifier of the channel
* @dev Make sure to validate channelId and counterpartyVersion
* @param counterpartyPortId The unique identifier of the counterparty's port
* @param counterpartyChannelId The unique identifier of the counterparty's channel
*/
function onChanCloseConfirm(bytes32 channelId, string calldata counterpartyPortId, bytes32 counterpartyChannelId)
external;
/**
* @notice Handles the channel open confirmation event (step 4 of the open channel handshake)
* @dev Make sure to validate channelId and counterpartyVersion
* @param channelId The unique identifier of the channel
*/
function onChanOpenConfirm(bytes32 channelId) external;
}
/**
* @title IbcPacketReceiver
* @notice Packet handler interface must be implemented by a IBC-enabled contract.
* @dev Packet handling callback methods are invoked by the IBC dispatcher.
*/
interface IbcPacketReceiver {
/**
* @notice Callback for receiving a packet; triggered when a counterparty sends an an IBC packet
* @param packet The IBC packet received
* @return ackPacket The acknowledgement packet generated in response
* @dev Make sure to validate packet's source and destiation channels and ports.
*/
function onRecvPacket(IbcPacket calldata packet) external returns (AckPacket memory ackPacket);
/**
* @notice Callback for acknowledging a packet; triggered on reciept of an IBC packet by the counterparty
* @param packet The IBC packet for which acknowledgement is received
* @param ack The acknowledgement packet received
* @dev Make sure to validate packet's source and destiation channels and ports.
*/
function onAcknowledgementPacket(IbcPacket calldata packet, AckPacket calldata ack) external;
/**
* @notice Callback for handling a packet timeout
* @param packet The IBC packet that has timed out
* @dev Make sure to validate packet's source and destiation channels and ports.
*/
function onTimeoutPacket(IbcPacket calldata packet) external;
}
/**
* @title IbcReceiver
* @author Polymer Labs
* @notice IBC receiver interface must be implemented by a IBC-enabled contract.
* The implementer, aka. dApp devs, should implement channel handshake and packet handling methods.
* @notice : Make sure to integrate carefully. Anyone can open a channel with your dapp. It's important to
* follow best practices and to note:
* - Always validte all given arguments (e.g. channels, ports) in the channel handsakes
* - It's recommended to use the onlyIbcDispatcher modifier to restrict access control to only the Dispatcher
* contract.
* - Dispatcher callbacks inherit from nonReentrant, so multiple calls to the Dispatcher cannot be made within the
* same transaction .
*/
interface IbcReceiver is IbcChannelReceiver, IbcPacketReceiver {}
contract IbcReceiverBase is Ownable {
IbcDispatcher public dispatcher;
error notIbcDispatcher();
error UnsupportedVersion();
error ChannelNotFound();
/**
* @dev Modifier to restrict access to only the IBC dispatcher.
* Only the address with the IBC_ROLE can execute the function.
* Should add this modifier to all IBC-related callback functions.
*/
modifier onlyIbcDispatcher() {
if (msg.sender != address(dispatcher)) {
revert notIbcDispatcher();
}
_;
}
/**
* @dev Constructor function that takes an IbcDispatcher address and grants the IBC_ROLE to the Polymer IBC
* Dispatcher.
* @param _dispatcher The address of the IbcDispatcher contract.
*/
constructor(IbcDispatcher _dispatcher) Ownable() {
dispatcher = _dispatcher;
}
/// This function is called for plain Ether transfers, i.e. for every call with empty calldata.
// An empty function body is sufficient to receive packet fee refunds.
receive() external payable {}
}