Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use Address.functionDelegateCall to call delegatecall #209

Merged
merged 1 commit into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
IBCTest:testBenchmarkCreateMockClient() (gas: 213968)
IBCTest:testBenchmarkRecvPacket() (gas: 156580)
IBCTest:testBenchmarkSendPacket() (gas: 85117)
IBCTest:testBenchmarkUpdateMockClient() (gas: 129390)
IBCTest:testConnectionOpenInit() (gas: 495976)
IBCTest:testBenchmarkCreateMockClient() (gas: 214256)
IBCTest:testBenchmarkRecvPacket() (gas: 157427)
IBCTest:testBenchmarkSendPacket() (gas: 85405)
IBCTest:testBenchmarkUpdateMockClient() (gas: 129811)
IBCTest:testConnectionOpenInit() (gas: 496552)
IBCTest:testToUint128((uint64,uint64)) (runs: 256, μ: 1051, ~: 1051)
31 changes: 12 additions & 19 deletions contracts/core/25-handler/IBCChannelHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,21 @@ import "../05-port/ModuleManager.sol";
* @dev IBCChannelHandler is a contract that calls a contract that implements `IIBCChannelHandshake` with delegatecall.
*/
abstract contract IBCChannelHandler is ModuleManager {
using Address for address;

// IBC Channel contract address
address immutable ibcChannel;

event GeneratedChannelIdentifier(string);

constructor(address _ibcChannel) {
require(Address.isContract(_ibcChannel), "address must be contract");
require(Address.isContract(_ibcChannel));
ibcChannel = _ibcChannel;
}

function channelOpenInit(IBCMsgs.MsgChannelOpenInit calldata msg_) external returns (string memory channelId) {
(bool success, bytes memory res) =
ibcChannel.delegatecall(abi.encodeWithSelector(IIBCChannelHandshake.channelOpenInit.selector, msg_));
require(success);
bytes memory res =
ibcChannel.functionDelegateCall(abi.encodeWithSelector(IIBCChannelHandshake.channelOpenInit.selector, msg_));
channelId = abi.decode(res, (string));

IIBCModule module = lookupModuleByPort(msg_.portId);
Expand All @@ -45,9 +46,9 @@ abstract contract IBCChannelHandler is ModuleManager {
function channelOpenTry(IBCMsgs.MsgChannelOpenTry calldata msg_) external returns (string memory channelId) {
{
// avoid "Stack too deep" error
(bool success, bytes memory res) =
ibcChannel.delegatecall(abi.encodeWithSelector(IIBCChannelHandshake.channelOpenTry.selector, msg_));
require(success);
bytes memory res = ibcChannel.functionDelegateCall(
abi.encodeWithSelector(IIBCChannelHandshake.channelOpenTry.selector, msg_)
);
channelId = abi.decode(res, (string));
}
IIBCModule module = lookupModuleByPort(msg_.portId);
Expand All @@ -66,30 +67,22 @@ abstract contract IBCChannelHandler is ModuleManager {
}

function channelOpenAck(IBCMsgs.MsgChannelOpenAck calldata msg_) external {
(bool success,) =
ibcChannel.delegatecall(abi.encodeWithSelector(IIBCChannelHandshake.channelOpenAck.selector, msg_));
require(success);
ibcChannel.functionDelegateCall(abi.encodeWithSelector(IIBCChannelHandshake.channelOpenAck.selector, msg_));
lookupModuleByPort(msg_.portId).onChanOpenAck(msg_.portId, msg_.channelId, msg_.counterpartyVersion);
}

function channelOpenConfirm(IBCMsgs.MsgChannelOpenConfirm calldata msg_) external {
(bool success,) =
ibcChannel.delegatecall(abi.encodeWithSelector(IIBCChannelHandshake.channelOpenConfirm.selector, msg_));
require(success);
ibcChannel.functionDelegateCall(abi.encodeWithSelector(IIBCChannelHandshake.channelOpenConfirm.selector, msg_));
lookupModuleByPort(msg_.portId).onChanOpenConfirm(msg_.portId, msg_.channelId);
}

function channelCloseInit(IBCMsgs.MsgChannelCloseInit calldata msg_) external {
(bool success,) =
ibcChannel.delegatecall(abi.encodeWithSelector(IIBCChannelHandshake.channelCloseInit.selector, msg_));
require(success);
ibcChannel.functionDelegateCall(abi.encodeWithSelector(IIBCChannelHandshake.channelCloseInit.selector, msg_));
lookupModuleByPort(msg_.portId).onChanCloseInit(msg_.portId, msg_.channelId);
}

function channelCloseConfirm(IBCMsgs.MsgChannelCloseConfirm calldata msg_) external {
(bool success,) =
ibcChannel.delegatecall(abi.encodeWithSelector(IIBCChannelHandshake.channelCloseConfirm.selector, msg_));
require(success);
ibcChannel.functionDelegateCall(abi.encodeWithSelector(IIBCChannelHandshake.channelCloseConfirm.selector, msg_));
lookupModuleByPort(msg_.portId).onChanCloseConfirm(msg_.portId, msg_.channelId);
}
}
16 changes: 7 additions & 9 deletions contracts/core/25-handler/IBCClientHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,31 @@ import "../02-client/IIBCClient.sol";
* @dev IBCClientHandler is a contract that calls a contract that implements `IIBCClient` with delegatecall.
*/
abstract contract IBCClientHandler {
using Address for address;

// IBC Client contract address
address immutable ibcClient;

event GeneratedClientIdentifier(string);

constructor(address _ibcClient) {
require(Address.isContract(_ibcClient), "address must be contract");
require(Address.isContract(_ibcClient));
ibcClient = _ibcClient;
}

/**
* @dev registerClient registers a new client type into the client registry
*/
function registerClient(string calldata clientType, ILightClient client) public virtual {
(bool success,) =
ibcClient.delegatecall(abi.encodeWithSelector(IIBCClient.registerClient.selector, clientType, client));
require(success);
ibcClient.functionDelegateCall(abi.encodeWithSelector(IIBCClient.registerClient.selector, clientType, client));
}

/**
* @dev createClient creates a new client state and populates it with a given consensus state
*/
function createClient(IBCMsgs.MsgCreateClient calldata msg_) external returns (string memory clientId) {
(bool success, bytes memory res) =
ibcClient.delegatecall(abi.encodeWithSelector(IIBCClient.createClient.selector, msg_));
require(success);
bytes memory res =
ibcClient.functionDelegateCall(abi.encodeWithSelector(IIBCClient.createClient.selector, msg_));
clientId = abi.decode(res, (string));
emit GeneratedClientIdentifier(clientId);
return clientId;
Expand All @@ -44,7 +43,6 @@ abstract contract IBCClientHandler {
* @dev updateClient updates the consensus state and the state root from a provided header
*/
function updateClient(IBCMsgs.MsgUpdateClient calldata msg_) external {
(bool success,) = ibcClient.delegatecall(abi.encodeWithSelector(IIBCClient.updateClient.selector, msg_));
require(success);
ibcClient.functionDelegateCall(abi.encodeWithSelector(IIBCClient.updateClient.selector, msg_));
}
}
22 changes: 11 additions & 11 deletions contracts/core/25-handler/IBCConnectionHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,25 @@ import "../03-connection/IIBCConnection.sol";
* @dev IBCConnectionHandler is a contract that calls a contract that implements `IIBCConnectionHandshake` with delegatecall.
*/
abstract contract IBCConnectionHandler {
using Address for address;

// IBC Connection contract address
address immutable ibcConnection;

event GeneratedConnectionIdentifier(string);

constructor(address _ibcConnection) {
require(Address.isContract(_ibcConnection), "address must be contract");
require(Address.isContract(_ibcConnection));
ibcConnection = _ibcConnection;
}

function connectionOpenInit(IBCMsgs.MsgConnectionOpenInit calldata msg_)
external
returns (string memory connectionId)
{
(bool success, bytes memory res) = ibcConnection.delegatecall(
bytes memory res = ibcConnection.functionDelegateCall(
abi.encodeWithSelector(IIBCConnectionHandshake.connectionOpenInit.selector, msg_)
);
require(success);
connectionId = abi.decode(res, (string));
emit GeneratedConnectionIdentifier(connectionId);
return connectionId;
Expand All @@ -37,24 +38,23 @@ abstract contract IBCConnectionHandler {
external
returns (string memory connectionId)
{
(bool success, bytes memory res) =
ibcConnection.delegatecall(abi.encodeWithSelector(IIBCConnectionHandshake.connectionOpenTry.selector, msg_));
require(success);
bytes memory res = ibcConnection.functionDelegateCall(
abi.encodeWithSelector(IIBCConnectionHandshake.connectionOpenTry.selector, msg_)
);
connectionId = abi.decode(res, (string));
emit GeneratedConnectionIdentifier(connectionId);
return connectionId;
}

function connectionOpenAck(IBCMsgs.MsgConnectionOpenAck calldata msg_) external {
(bool success,) =
ibcConnection.delegatecall(abi.encodeWithSelector(IIBCConnectionHandshake.connectionOpenAck.selector, msg_));
require(success);
ibcConnection.functionDelegateCall(
abi.encodeWithSelector(IIBCConnectionHandshake.connectionOpenAck.selector, msg_)
);
}

function connectionOpenConfirm(IBCMsgs.MsgConnectionOpenConfirm calldata msg_) external {
(bool success,) = ibcConnection.delegatecall(
ibcConnection.functionDelegateCall(
abi.encodeWithSelector(IIBCConnectionHandshake.connectionOpenConfirm.selector, msg_)
);
require(success);
}
}
25 changes: 10 additions & 15 deletions contracts/core/25-handler/IBCPacketHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import "../05-port/IIBCModule.sol";
* @dev IBCPacketHandler is a contract that calls a contract that implements `IIBCPacket` with delegatecall.
*/
abstract contract IBCPacketHandler is Context, ModuleManager {
using Address for address;

// IBC Packet contract address
address immutable ibcPacket;

Expand All @@ -33,7 +35,7 @@ abstract contract IBCPacketHandler is Context, ModuleManager {
event TimeoutPacket(Packet.Data packet);

constructor(address _ibcPacket) {
require(Address.isContract(_ibcPacket), "address must be contract");
require(Address.isContract(_ibcPacket));
ibcPacket = _ibcPacket;
}

Expand All @@ -45,22 +47,20 @@ abstract contract IBCPacketHandler is Context, ModuleManager {
bytes calldata data
) external {
require(authenticateCapability(channelCapabilityPath(sourcePort, sourceChannel)));
(bool success, bytes memory res) = ibcPacket.delegatecall(
bytes memory res = ibcPacket.functionDelegateCall(
abi.encodeWithSelector(
IIBCPacket.sendPacket.selector, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data
)
);
require(success);
emit SendPacket(abi.decode(res, (uint64)), sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data);
}

function recvPacket(IBCMsgs.MsgPacketRecv calldata msg_) external {
IIBCModule module = lookupModuleByChannel(msg_.packet.destination_port, msg_.packet.destination_channel);
ibcPacket.functionDelegateCall(abi.encodeWithSelector(IIBCPacket.recvPacket.selector, msg_));
bytes memory acknowledgement = module.onRecvPacket(msg_.packet, _msgSender());
(bool success,) = ibcPacket.delegatecall(abi.encodeWithSelector(IIBCPacket.recvPacket.selector, msg_));
require(success);
if (acknowledgement.length > 0) {
(success,) = ibcPacket.delegatecall(
ibcPacket.functionDelegateCall(
abi.encodeWithSelector(
IIBCPacket.writeAcknowledgement.selector,
msg_.packet.destination_port,
Expand All @@ -69,7 +69,6 @@ abstract contract IBCPacketHandler is Context, ModuleManager {
acknowledgement
)
);
require(success);
emit WriteAcknowledgement(
msg_.packet.destination_port, msg_.packet.destination_channel, msg_.packet.sequence, acknowledgement
);
Expand All @@ -84,7 +83,7 @@ abstract contract IBCPacketHandler is Context, ModuleManager {
bytes calldata acknowledgement
) external {
require(authenticateCapability(channelCapabilityPath(destinationPortId, destinationChannel)));
(bool success,) = ibcPacket.delegatecall(
ibcPacket.functionDelegateCall(
abi.encodeWithSelector(
IIBCPacket.writeAcknowledgement.selector,
destinationPortId,
Expand All @@ -93,30 +92,26 @@ abstract contract IBCPacketHandler is Context, ModuleManager {
acknowledgement
)
);
require(success);
emit WriteAcknowledgement(destinationPortId, destinationChannel, sequence, acknowledgement);
}

function acknowledgePacket(IBCMsgs.MsgPacketAcknowledgement calldata msg_) external {
IIBCModule module = lookupModuleByChannel(msg_.packet.source_port, msg_.packet.source_channel);
ibcPacket.functionDelegateCall(abi.encodeWithSelector(IIBCPacket.acknowledgePacket.selector, msg_));
module.onAcknowledgementPacket(msg_.packet, msg_.acknowledgement, _msgSender());
(bool success,) = ibcPacket.delegatecall(abi.encodeWithSelector(IIBCPacket.acknowledgePacket.selector, msg_));
require(success);
emit AcknowledgePacket(msg_.packet, msg_.acknowledgement);
}

function timeoutPacket(IBCMsgs.MsgTimeoutPacket calldata msg_) external {
IIBCModule module = lookupModuleByChannel(msg_.packet.source_port, msg_.packet.source_channel);
(bool success,) = ibcPacket.delegatecall(abi.encodeWithSelector(IIBCPacket.timeoutPacket.selector, msg_));
require(success);
ibcPacket.functionDelegateCall(abi.encodeWithSelector(IIBCPacket.timeoutPacket.selector, msg_));
module.onTimeoutPacket(msg_.packet, _msgSender());
emit TimeoutPacket(msg_.packet);
}

function timeoutOnClose(IBCMsgs.MsgTimeoutOnClose calldata msg_) external {
IIBCModule module = lookupModuleByChannel(msg_.packet.source_port, msg_.packet.source_channel);
(bool success,) = ibcPacket.delegatecall(abi.encodeWithSelector(IIBCPacket.timeoutOnClose.selector, msg_));
require(success);
ibcPacket.functionDelegateCall(abi.encodeWithSelector(IIBCPacket.timeoutOnClose.selector, msg_));
module.onTimeoutPacket(msg_.packet, _msgSender());
emit TimeoutPacket(msg_.packet);
}
Expand Down