From c89791bf9be7c6327d1e3d479288552b5d977638 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Mon, 8 Jan 2024 17:51:15 +0100 Subject: [PATCH 01/14] feat(evm): upgrade to solidity 0.8.23 --- evm/contracts/Glue.sol | 2 +- .../apps/ucs/00-pingpong/PingPong.sol | 2 +- .../apps/ucs/01-relay/ERC20Denom.sol | 2 +- .../apps/ucs/01-relay/IERC20Denom.sol | 2 +- evm/contracts/apps/ucs/01-relay/Relay.sol | 116 ++++++++++++------ evm/contracts/clients/CometblsClient.sol | 2 +- evm/contracts/clients/CometblsClientV2.sol | 2 +- .../clients/ICS23MembershipVerifier.sol | 2 +- evm/contracts/clients/MockClient.sol | 2 +- evm/contracts/clients/TestVerifier.sol | 2 +- evm/contracts/clients/Verifier.sol | 2 +- evm/contracts/core/02-client/IBCClient.sol | 2 +- evm/contracts/core/02-client/IBCHeight.sol | 2 +- evm/contracts/core/02-client/IIBCClient.sol | 2 +- evm/contracts/core/02-client/ILightClient.sol | 2 +- .../core/03-connection/IBCConnection.sol | 2 +- .../core/03-connection/IIBCConnection.sol | 2 +- .../core/04-channel/IBCChannelHandshake.sol | 2 +- evm/contracts/core/04-channel/IBCPacket.sol | 2 +- evm/contracts/core/04-channel/IIBCChannel.sol | 2 +- evm/contracts/core/05-port/IIBCModule.sol | 2 +- evm/contracts/core/05-port/ModuleManager.sol | 2 +- evm/contracts/core/24-host/IBCCommitment.sol | 2 +- .../core/24-host/IBCCommitmentTestHelper.sol | 2 +- evm/contracts/core/24-host/IBCHost.sol | 2 +- evm/contracts/core/24-host/IBCStore.sol | 2 +- .../core/25-handler/IBCChannelHandler.sol | 2 +- .../core/25-handler/IBCClientHandler.sol | 2 +- .../core/25-handler/IBCConnectionHandler.sol | 2 +- evm/contracts/core/25-handler/IBCHandler.sol | 2 +- evm/contracts/core/25-handler/IBCMsgs.sol | 2 +- .../core/25-handler/IBCPacketHandler.sol | 4 +- evm/contracts/core/25-handler/IBCQuerier.sol | 2 +- evm/contracts/core/DevnetIBCHandlerInit.sol | 2 +- .../core/DevnetOwnableIBCHandler.sol | 2 +- evm/contracts/core/IMembershipVerifier.sol | 2 +- evm/contracts/core/IZKVerifier.sol | 2 +- evm/contracts/core/OwnableIBCHandler.sol | 2 +- evm/contracts/lib/CometblsHelp.sol | 2 +- evm/contracts/lib/Encoder.sol | 2 +- evm/contracts/lib/ICS23.sol | 2 +- evm/contracts/lib/MerkleTree.sol | 2 +- evm/contracts/lib/Pairing.sol | 2 +- evm/contracts/proto/GoogleProtobufAny.sol | 2 +- evm/contracts/proto/MockClient.sol | 2 +- evm/contracts/proto/ProtoBufRuntime.sol | 2 +- .../proto/cosmos/auth/v1beta1/auth.sol | 2 +- .../cosmos/base/query/v1beta1/pagination.sol | 2 +- .../proto/cosmos/base/v1beta1/coin.sol | 2 +- .../proto/cosmos/ics23/v1/proofs.sol | 2 +- .../proto/cosmos/upgrade/v1beta1/upgrade.sol | 2 +- evm/contracts/proto/cosmos_proto/cosmos.sol | 2 +- evm/contracts/proto/google/api/http.sol | 2 +- .../proto/ibc/applications/fee/v1/ack.sol | 2 +- .../proto/ibc/applications/fee/v1/fee.sol | 2 +- .../proto/ibc/applications/fee/v1/genesis.sol | 2 +- .../ibc/applications/fee/v1/metadata.sol | 2 +- .../proto/ibc/applications/fee/v1/query.sol | 2 +- .../proto/ibc/applications/fee/v1/tx.sol | 2 +- .../controller/v1/controller.sol | 2 +- .../controller/v1/query.sol | 2 +- .../interchain_accounts/controller/v1/tx.sol | 2 +- .../genesis/v1/genesis.sol | 2 +- .../interchain_accounts/host/v1/host.sol | 2 +- .../interchain_accounts/host/v1/query.sol | 2 +- .../interchain_accounts/v1/account.sol | 2 +- .../interchain_accounts/v1/metadata.sol | 2 +- .../interchain_accounts/v1/packet.sol | 2 +- .../ibc/applications/transfer/v1/authz.sol | 2 +- .../ibc/applications/transfer/v1/genesis.sol | 2 +- .../ibc/applications/transfer/v1/query.sol | 2 +- .../ibc/applications/transfer/v1/transfer.sol | 2 +- .../proto/ibc/applications/transfer/v1/tx.sol | 2 +- .../ibc/applications/transfer/v2/packet.sol | 2 +- .../proto/ibc/core/channel/v1/channel.sol | 2 +- .../proto/ibc/core/channel/v1/genesis.sol | 2 +- .../proto/ibc/core/channel/v1/query.sol | 2 +- .../proto/ibc/core/channel/v1/tx.sol | 2 +- .../proto/ibc/core/client/v1/client.sol | 2 +- .../proto/ibc/core/client/v1/genesis.sol | 2 +- .../proto/ibc/core/client/v1/query.sol | 2 +- evm/contracts/proto/ibc/core/client/v1/tx.sol | 2 +- .../ibc/core/commitment/v1/commitment.sol | 2 +- .../ibc/core/connection/v1/connection.sol | 2 +- .../proto/ibc/core/connection/v1/genesis.sol | 2 +- .../proto/ibc/core/connection/v1/query.sol | 2 +- .../proto/ibc/core/connection/v1/tx.sol | 2 +- .../proto/ibc/core/types/v1/genesis.sol | 2 +- .../solomachine/v2/solomachine.sol | 2 +- .../solomachine/v3/solomachine.sol | 2 +- .../lightclients/tendermint/v1/tendermint.sol | 2 +- .../ibc/lightclients/wasm/v1/genesis.sol | 2 +- .../proto/ibc/lightclients/wasm/v1/query.sol | 2 +- .../proto/ibc/lightclients/wasm/v1/tx.sol | 2 +- .../proto/ibc/lightclients/wasm/v1/wasm.sol | 2 +- .../proto/tendermint/crypto/keys.sol | 2 +- .../proto/tendermint/crypto/proof.sol | 2 +- .../proto/tendermint/types/canonical.sol | 2 +- .../proto/tendermint/types/types.sol | 2 +- .../proto/tendermint/types/validator.sol | 2 +- .../proto/tendermint/version/types.sol | 2 +- .../ibc/lightclients/cometbls/v1/cometbls.sol | 2 +- evm/tests/src/02-client/IBCClient.t.sol | 2 +- .../src/03-connection/IBCConnection.t.sol | 2 +- .../src/04-channel/IBCChannelHandshake.t.sol | 2 +- evm/tests/src/04-channel/IBCPacket.t.sol | 2 +- evm/tests/src/24-host/IBCCommitment.t.sol | 2 +- .../src/25-handler/IBCChannelHandler.t.sol | 2 +- .../src/25-handler/IBCClientHandler.t.sol | 2 +- .../src/25-handler/IBCConnectionHandler.t.sol | 2 +- .../src/25-handler/IBCPacketHandler.t.sol | 2 +- evm/tests/src/ICS23.t.sol | 2 +- evm/tests/src/MockApp.t.sol | 2 +- evm/tests/src/TestPlus.sol | 2 +- evm/tests/src/TestableIBCHandler.t.sol | 2 +- evm/tests/src/apps/ucs/01-relay/Relay.t.sol | 2 +- evm/tests/src/utils/Cometbls.sol | 2 +- evm/tests/src/utils/IBCHandler_Testable.sol | 2 +- .../src/utils/MembershipVerifier_Testable.sol | 2 +- evm/tests/src/utils/MockApp.sol | 2 +- evm/tests/src/utils/MsgMocks.sol | 2 +- evm/tests/src/utils/TestUtils.sol | 2 +- flake.nix | 37 +++++- 123 files changed, 237 insertions(+), 160 deletions(-) diff --git a/evm/contracts/Glue.sol b/evm/contracts/Glue.sol index a37e9fca69..2ece1b546a 100644 --- a/evm/contracts/Glue.sol +++ b/evm/contracts/Glue.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "./core/02-client/ILightClient.sol"; import "./core/02-client/IBCHeight.sol"; diff --git a/evm/contracts/apps/ucs/00-pingpong/PingPong.sol b/evm/contracts/apps/ucs/00-pingpong/PingPong.sol index c54d313110..a3edc51743 100644 --- a/evm/contracts/apps/ucs/00-pingpong/PingPong.sol +++ b/evm/contracts/apps/ucs/00-pingpong/PingPong.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../Base.sol"; import "../../../core/25-handler/IBCHandler.sol"; diff --git a/evm/contracts/apps/ucs/01-relay/ERC20Denom.sol b/evm/contracts/apps/ucs/01-relay/ERC20Denom.sol index ac3d564c7d..c514c998b8 100644 --- a/evm/contracts/apps/ucs/01-relay/ERC20Denom.sol +++ b/evm/contracts/apps/ucs/01-relay/ERC20Denom.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "./IERC20Denom.sol"; diff --git a/evm/contracts/apps/ucs/01-relay/IERC20Denom.sol b/evm/contracts/apps/ucs/01-relay/IERC20Denom.sol index 0f61c75a18..d120be61dd 100644 --- a/evm/contracts/apps/ucs/01-relay/IERC20Denom.sol +++ b/evm/contracts/apps/ucs/01-relay/IERC20Denom.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/evm/contracts/apps/ucs/01-relay/Relay.sol b/evm/contracts/apps/ucs/01-relay/Relay.sol index 05f1eb9d8d..79bc3ddfdf 100644 --- a/evm/contracts/apps/ucs/01-relay/Relay.sol +++ b/evm/contracts/apps/ucs/01-relay/Relay.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -31,6 +31,33 @@ struct RelayPacket { library RelayLib { using LibString for *; + string public constant VERSION = "ucs01-0"; + bytes1 public constant ACK_SUCCESS = 0x01; + bytes1 public constant ACK_FAILURE = 0x00; + uint256 public constant ACK_LENGTH = 1; + + event DenomCreated(string denom, address token); + event Received( + string sender, + address receiver, + string denom, + address token, + uint256 amount + ); + event Sent( + address sender, + string receiver, + string denom, + address token, + uint256 amount + ); + + function isValidVersion( + string memory version + ) internal pure returns (bool) { + return version.eq(VERSION); + } + function isRemote( string memory portId, string memory channelId, @@ -57,10 +84,10 @@ library RelayLib { string(abi.encodePacked(makeDenomPrefix(portId, channelId), denom)); } - // It expect 0x.. prefix function hexToAddress( string memory _a ) internal pure returns (address _parsedAddress) { + require(bytes(_a).length == 42, "ucs01-relay: invalid address"); bytes memory tmp = bytes(_a); uint160 iaddr = 0; uint160 b1; @@ -89,9 +116,7 @@ library RelayLib { } function bytesToAddress(bytes memory b) internal pure returns (address) { - if (b.length != 20) { - revert("Invalid address."); - } + require(b.length == 20, "ucs01-relay: invalid address"); return address(uint160(bytes20(b))); } } @@ -122,10 +147,6 @@ contract UCS01Relay is IBCAppBase { using strings for *; using SafeMath for uint256; - bytes1 constant ACK_SUCCESS = 0x01; - bytes1 constant ACK_FAILURE = 0x00; - uint256 constant ACK_LENGTH = 1; - IBCHandler private immutable ibcHandler; mapping(string => address) public denomToAddress; @@ -135,22 +156,6 @@ contract UCS01Relay is IBCAppBase { mapping(string => mapping(string => mapping(address => uint256))) public outstanding; - event DenomCreated(string denom, address token); - event Received( - string sender, - address receiver, - string denom, - address token, - uint256 amount - ); - event Sent( - address sender, - string receiver, - string denom, - address token, - uint256 amount - ); - constructor(IBCHandler _ibcHandler) { ibcHandler = _ibcHandler; } @@ -159,6 +164,24 @@ contract UCS01Relay is IBCAppBase { return address(ibcHandler); } + function getDenomAddress( + string memory denom + ) public view returns (address) { + return denomToAddress[denom]; + } + + function getAddressDenom(address addr) public view returns (string memory) { + return addressToDenom[addr]; + } + + function getOutstanding( + string memory sourcePort, + string memory sourceChannel, + address token + ) public view returns (uint256) { + return outstanding[sourcePort][sourceChannel][token]; + } + function increaseOutstanding( string memory portId, string memory channelId, @@ -242,7 +265,7 @@ contract UCS01Relay is IBCAppBase { ); normalizedTokens[i].denom = addressDenom; normalizedTokens[i].amount = uint256(localToken.amount); - emit Sent( + emit RelayLib.Sent( msg.sender, receiver.toHexString(), addressDenom, @@ -308,7 +331,10 @@ contract UCS01Relay is IBCAppBase { IbcCoreChannelV1Packet.Data calldata ibcPacket, address relayer ) public { - require(msg.sender == address(this)); + require( + msg.sender == address(this), + "ucs01-relay: sender must be self" + ); RelayPacket memory packet = RelayPacketLib.decode(ibcPacket.data); string memory prefix = RelayLib.makeDenomPrefix( ibcPacket.destination_port, @@ -346,11 +372,11 @@ contract UCS01Relay is IBCAppBase { denomAddress = address(new ERC20Denom(denom)); denomToAddress[denom] = denomAddress; addressToDenom[denomAddress] = denom; - emit DenomCreated(denom, denomAddress); + emit RelayLib.DenomCreated(denom, denomAddress); } IERC20Denom(denomAddress).mint(receiver, token.amount); } - emit Received( + emit RelayLib.Received( packet.sender.toHexString(), receiver, denom, @@ -373,9 +399,9 @@ contract UCS01Relay is IBCAppBase { ) ); if (success) { - return abi.encodePacked(ACK_SUCCESS); + return abi.encodePacked(RelayLib.ACK_SUCCESS); } else { - return abi.encodePacked(ACK_FAILURE); + return abi.encodePacked(RelayLib.ACK_FAILURE); } } @@ -385,11 +411,11 @@ contract UCS01Relay is IBCAppBase { address _relayer ) external virtual override onlyIBC { require( - acknowledgement.length == ACK_LENGTH, + acknowledgement.length == RelayLib.ACK_LENGTH, "ucs01-relay: single byte ack" ); RelayPacket memory packet = RelayPacketLib.decode(ibcPacket.data); - if (acknowledgement[0] == ACK_SUCCESS) { + if (acknowledgement[0] == RelayLib.ACK_SUCCESS) { tokensLanded( ibcPacket.source_port, ibcPacket.source_channel, @@ -421,8 +447,12 @@ contract UCS01Relay is IBCAppBase { string calldata portId, string calldata channelId, IbcCoreChannelV1Counterparty.Data calldata counterpartyEndpoint, - string calldata _version + string calldata version ) external virtual override onlyIBC { + require( + RelayLib.isValidVersion(version), + "ucs01-relay: invalid version" + ); counterpartyEndpoints[portId][channelId] = counterpartyEndpoint; } @@ -432,9 +462,17 @@ contract UCS01Relay is IBCAppBase { string calldata portId, string calldata channelId, IbcCoreChannelV1Counterparty.Data calldata counterpartyEndpoint, - string calldata _version, - string calldata _counterpartyVersion + string calldata version, + string calldata counterpartyVersion ) external virtual override onlyIBC { + require( + RelayLib.isValidVersion(version), + "ucs01-relay: invalid version" + ); + require( + RelayLib.isValidVersion(counterpartyVersion), + "ucs01-relay: invalid counterparty version" + ); counterpartyEndpoints[portId][channelId] = counterpartyEndpoint; } @@ -442,8 +480,12 @@ contract UCS01Relay is IBCAppBase { string calldata portId, string calldata channelId, string calldata counterpartyChannelId, - string calldata _counterpartyVersion + string calldata counterpartyVersion ) external virtual override onlyIBC { + require( + RelayLib.isValidVersion(counterpartyVersion), + "ucs01-relay: invalid counterparty version" + ); // Counterparty channel was empty. counterpartyEndpoints[portId][channelId] .channel_id = counterpartyChannelId; diff --git a/evm/contracts/clients/CometblsClient.sol b/evm/contracts/clients/CometblsClient.sol index 28936dfc0a..4cf8650d1d 100644 --- a/evm/contracts/clients/CometblsClient.sol +++ b/evm/contracts/clients/CometblsClient.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../core/02-client/ILightClient.sol"; import "../core/02-client/IBCHeight.sol"; diff --git a/evm/contracts/clients/CometblsClientV2.sol b/evm/contracts/clients/CometblsClientV2.sol index 78fd53f286..710e375d63 100644 --- a/evm/contracts/clients/CometblsClientV2.sol +++ b/evm/contracts/clients/CometblsClientV2.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../core/02-client/ILightClient.sol"; import "../core/02-client/IBCHeight.sol"; diff --git a/evm/contracts/clients/ICS23MembershipVerifier.sol b/evm/contracts/clients/ICS23MembershipVerifier.sol index 8c054c7bc4..8859667a26 100644 --- a/evm/contracts/clients/ICS23MembershipVerifier.sol +++ b/evm/contracts/clients/ICS23MembershipVerifier.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../core/IMembershipVerifier.sol"; import "../lib/ICS23.sol"; diff --git a/evm/contracts/clients/MockClient.sol b/evm/contracts/clients/MockClient.sol index 65189ae894..4ae95052b7 100644 --- a/evm/contracts/clients/MockClient.sol +++ b/evm/contracts/clients/MockClient.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../core/02-client/ILightClient.sol"; import "../core/02-client/IBCHeight.sol"; diff --git a/evm/contracts/clients/TestVerifier.sol b/evm/contracts/clients/TestVerifier.sol index caaa4866bc..06704fe50f 100644 --- a/evm/contracts/clients/TestVerifier.sol +++ b/evm/contracts/clients/TestVerifier.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../lib/Pairing.sol"; import "../core/IZKVerifier.sol"; diff --git a/evm/contracts/clients/Verifier.sol b/evm/contracts/clients/Verifier.sol index 6467de698f..328f5b30be 100644 --- a/evm/contracts/clients/Verifier.sol +++ b/evm/contracts/clients/Verifier.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../lib/Pairing.sol"; import "../core/IZKVerifierV2.sol"; diff --git a/evm/contracts/core/02-client/IBCClient.sol b/evm/contracts/core/02-client/IBCClient.sol index e530abd025..c084ac7671 100644 --- a/evm/contracts/core/02-client/IBCClient.sol +++ b/evm/contracts/core/02-client/IBCClient.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/utils/Strings.sol"; import "./ILightClient.sol"; diff --git a/evm/contracts/core/02-client/IBCHeight.sol b/evm/contracts/core/02-client/IBCHeight.sol index 9984fb09e0..97b3320fd1 100644 --- a/evm/contracts/core/02-client/IBCHeight.sol +++ b/evm/contracts/core/02-client/IBCHeight.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../proto/ibc/core/client/v1/client.sol"; diff --git a/evm/contracts/core/02-client/IIBCClient.sol b/evm/contracts/core/02-client/IIBCClient.sol index 3e7e36ed74..a9e5e86d46 100644 --- a/evm/contracts/core/02-client/IIBCClient.sol +++ b/evm/contracts/core/02-client/IIBCClient.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "./ILightClient.sol"; import "../25-handler/IBCMsgs.sol"; diff --git a/evm/contracts/core/02-client/ILightClient.sol b/evm/contracts/core/02-client/ILightClient.sol index 9b7af68d85..57a37a8222 100644 --- a/evm/contracts/core/02-client/ILightClient.sol +++ b/evm/contracts/core/02-client/ILightClient.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../proto/ibc/core/client/v1/client.sol"; diff --git a/evm/contracts/core/03-connection/IBCConnection.sol b/evm/contracts/core/03-connection/IBCConnection.sol index 3b5af3a39b..9e01c2cd2d 100644 --- a/evm/contracts/core/03-connection/IBCConnection.sol +++ b/evm/contracts/core/03-connection/IBCConnection.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/utils/Strings.sol"; import "../../proto/ibc/core/client/v1/client.sol"; diff --git a/evm/contracts/core/03-connection/IIBCConnection.sol b/evm/contracts/core/03-connection/IIBCConnection.sol index 85523e6212..76a3de7a28 100644 --- a/evm/contracts/core/03-connection/IIBCConnection.sol +++ b/evm/contracts/core/03-connection/IIBCConnection.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../25-handler/IBCMsgs.sol"; diff --git a/evm/contracts/core/04-channel/IBCChannelHandshake.sol b/evm/contracts/core/04-channel/IBCChannelHandshake.sol index 08bab33d51..ab48c9927e 100644 --- a/evm/contracts/core/04-channel/IBCChannelHandshake.sol +++ b/evm/contracts/core/04-channel/IBCChannelHandshake.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/utils/Strings.sol"; import "../../proto/ibc/core/channel/v1/channel.sol"; diff --git a/evm/contracts/core/04-channel/IBCPacket.sol b/evm/contracts/core/04-channel/IBCPacket.sol index 467e4439d5..8efcff062b 100644 --- a/evm/contracts/core/04-channel/IBCPacket.sol +++ b/evm/contracts/core/04-channel/IBCPacket.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/utils/Strings.sol"; import "../../proto/ibc/core/channel/v1/channel.sol"; diff --git a/evm/contracts/core/04-channel/IIBCChannel.sol b/evm/contracts/core/04-channel/IIBCChannel.sol index e208f073de..6dfb1d92cb 100644 --- a/evm/contracts/core/04-channel/IIBCChannel.sol +++ b/evm/contracts/core/04-channel/IIBCChannel.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../25-handler/IBCMsgs.sol"; diff --git a/evm/contracts/core/05-port/IIBCModule.sol b/evm/contracts/core/05-port/IIBCModule.sol index e5aa2679db..aab66264a8 100644 --- a/evm/contracts/core/05-port/IIBCModule.sol +++ b/evm/contracts/core/05-port/IIBCModule.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../proto/ibc/core/channel/v1/channel.sol"; diff --git a/evm/contracts/core/05-port/ModuleManager.sol b/evm/contracts/core/05-port/ModuleManager.sol index 005e70f5f8..b44dc3c97c 100644 --- a/evm/contracts/core/05-port/ModuleManager.sol +++ b/evm/contracts/core/05-port/ModuleManager.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "./IIBCModule.sol"; diff --git a/evm/contracts/core/24-host/IBCCommitment.sol b/evm/contracts/core/24-host/IBCCommitment.sol index 7239a679e3..916a270fb8 100644 --- a/evm/contracts/core/24-host/IBCCommitment.sol +++ b/evm/contracts/core/24-host/IBCCommitment.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "solady/utils/LibString.sol"; diff --git a/evm/contracts/core/24-host/IBCCommitmentTestHelper.sol b/evm/contracts/core/24-host/IBCCommitmentTestHelper.sol index 1fd863f9fa..96195e5dcf 100644 --- a/evm/contracts/core/24-host/IBCCommitmentTestHelper.sol +++ b/evm/contracts/core/24-host/IBCCommitmentTestHelper.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "./IBCCommitment.sol"; diff --git a/evm/contracts/core/24-host/IBCHost.sol b/evm/contracts/core/24-host/IBCHost.sol index b4dfaa7f77..943ae915bc 100644 --- a/evm/contracts/core/24-host/IBCHost.sol +++ b/evm/contracts/core/24-host/IBCHost.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/utils/Context.sol"; import "../../proto/ibc/core/client/v1/client.sol"; diff --git a/evm/contracts/core/24-host/IBCStore.sol b/evm/contracts/core/24-host/IBCStore.sol index ee3df107a4..6fc836087e 100644 --- a/evm/contracts/core/24-host/IBCStore.sol +++ b/evm/contracts/core/24-host/IBCStore.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../proto/ibc/core/connection/v1/connection.sol"; import "../../proto/ibc/core/channel/v1/channel.sol"; diff --git a/evm/contracts/core/25-handler/IBCChannelHandler.sol b/evm/contracts/core/25-handler/IBCChannelHandler.sol index 180edbcf63..576baa37fb 100644 --- a/evm/contracts/core/25-handler/IBCChannelHandler.sol +++ b/evm/contracts/core/25-handler/IBCChannelHandler.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../25-handler/IBCMsgs.sol"; import "../24-host/IBCHost.sol"; diff --git a/evm/contracts/core/25-handler/IBCClientHandler.sol b/evm/contracts/core/25-handler/IBCClientHandler.sol index fcf1cbec7f..ab20f9c1d9 100644 --- a/evm/contracts/core/25-handler/IBCClientHandler.sol +++ b/evm/contracts/core/25-handler/IBCClientHandler.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../24-host/IBCHost.sol"; import "../02-client/IIBCClient.sol"; diff --git a/evm/contracts/core/25-handler/IBCConnectionHandler.sol b/evm/contracts/core/25-handler/IBCConnectionHandler.sol index 3b58fcf0ed..cf497577c5 100644 --- a/evm/contracts/core/25-handler/IBCConnectionHandler.sol +++ b/evm/contracts/core/25-handler/IBCConnectionHandler.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../25-handler/IBCMsgs.sol"; import "../24-host/IBCHost.sol"; diff --git a/evm/contracts/core/25-handler/IBCHandler.sol b/evm/contracts/core/25-handler/IBCHandler.sol index 03da846fe1..9fd8b3f96d 100644 --- a/evm/contracts/core/25-handler/IBCHandler.sol +++ b/evm/contracts/core/25-handler/IBCHandler.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../24-host/IBCHost.sol"; import "./IBCClientHandler.sol"; diff --git a/evm/contracts/core/25-handler/IBCMsgs.sol b/evm/contracts/core/25-handler/IBCMsgs.sol index c3710bcd2c..bdda098849 100644 --- a/evm/contracts/core/25-handler/IBCMsgs.sol +++ b/evm/contracts/core/25-handler/IBCMsgs.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../proto/ibc/core/client/v1/client.sol"; import "../../proto/ibc/core/connection/v1/connection.sol"; diff --git a/evm/contracts/core/25-handler/IBCPacketHandler.sol b/evm/contracts/core/25-handler/IBCPacketHandler.sol index 9cb7edb8ef..897ff0d9cf 100644 --- a/evm/contracts/core/25-handler/IBCPacketHandler.sol +++ b/evm/contracts/core/25-handler/IBCPacketHandler.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/utils/Context.sol"; import "../25-handler/IBCMsgs.sol"; @@ -50,7 +50,7 @@ abstract contract IBCPacketHandler is Context, ModuleManager { IbcCoreClientV1Height.Data calldata timeoutHeight, uint64 timeoutTimestamp, bytes calldata data - ) external { + ) external virtual { require( authenticateCapability( channelCapabilityPath(sourcePort, sourceChannel) diff --git a/evm/contracts/core/25-handler/IBCQuerier.sol b/evm/contracts/core/25-handler/IBCQuerier.sol index 5786a6ab17..05e5dc0f34 100644 --- a/evm/contracts/core/25-handler/IBCQuerier.sol +++ b/evm/contracts/core/25-handler/IBCQuerier.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../proto/ibc/core/client/v1/client.sol"; import "../02-client/ILightClient.sol"; diff --git a/evm/contracts/core/DevnetIBCHandlerInit.sol b/evm/contracts/core/DevnetIBCHandlerInit.sol index fa179c96c4..b8a2231e5a 100644 --- a/evm/contracts/core/DevnetIBCHandlerInit.sol +++ b/evm/contracts/core/DevnetIBCHandlerInit.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "./OwnableIBCHandler.sol"; import "./24-host/IBCHost.sol"; diff --git a/evm/contracts/core/DevnetOwnableIBCHandler.sol b/evm/contracts/core/DevnetOwnableIBCHandler.sol index 0e751f456c..9f45e4cb37 100644 --- a/evm/contracts/core/DevnetOwnableIBCHandler.sol +++ b/evm/contracts/core/DevnetOwnableIBCHandler.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "./OwnableIBCHandler.sol"; import "./DevnetIBCHandlerInit.sol"; diff --git a/evm/contracts/core/IMembershipVerifier.sol b/evm/contracts/core/IMembershipVerifier.sol index e5fd291177..15a16204de 100644 --- a/evm/contracts/core/IMembershipVerifier.sol +++ b/evm/contracts/core/IMembershipVerifier.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../proto/ibc/core/client/v1/client.sol"; diff --git a/evm/contracts/core/IZKVerifier.sol b/evm/contracts/core/IZKVerifier.sol index 5d91406551..8e05dff461 100644 --- a/evm/contracts/core/IZKVerifier.sol +++ b/evm/contracts/core/IZKVerifier.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; interface IZKVerifier { function verifyProof( diff --git a/evm/contracts/core/OwnableIBCHandler.sol b/evm/contracts/core/OwnableIBCHandler.sol index 3226c43f0e..02408a1d44 100644 --- a/evm/contracts/core/OwnableIBCHandler.sol +++ b/evm/contracts/core/OwnableIBCHandler.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "@openzeppelin/contracts/access/Ownable.sol"; import "./25-handler/IBCHandler.sol"; diff --git a/evm/contracts/lib/CometblsHelp.sol b/evm/contracts/lib/CometblsHelp.sol index 5155ff3c17..fbe2583bbe 100644 --- a/evm/contracts/lib/CometblsHelp.sol +++ b/evm/contracts/lib/CometblsHelp.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../proto/union/ibc/lightclients/cometbls/v1/cometbls.sol"; import "../proto/ibc/lightclients/wasm/v1/wasm.sol"; diff --git a/evm/contracts/lib/Encoder.sol b/evm/contracts/lib/Encoder.sol index e649c772ef..92db893e36 100644 --- a/evm/contracts/lib/Encoder.sol +++ b/evm/contracts/lib/Encoder.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "./../proto/ProtoBufRuntime.sol"; diff --git a/evm/contracts/lib/ICS23.sol b/evm/contracts/lib/ICS23.sol index 8e81580aa2..cdb1946b56 100644 --- a/evm/contracts/lib/ICS23.sol +++ b/evm/contracts/lib/ICS23.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {BytesLib} from "solidity-bytes-utils/BytesLib.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; diff --git a/evm/contracts/lib/MerkleTree.sol b/evm/contracts/lib/MerkleTree.sol index f201500d59..4ce4c4d818 100644 --- a/evm/contracts/lib/MerkleTree.sol +++ b/evm/contracts/lib/MerkleTree.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; library MerkleTree { uint8 constant LEAF_PREFIX = 0x00; diff --git a/evm/contracts/lib/Pairing.sol b/evm/contracts/lib/Pairing.sol index 58847aeec3..d2dcd6fab2 100644 --- a/evm/contracts/lib/Pairing.sol +++ b/evm/contracts/lib/Pairing.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; library Pairing { uint256 constant PRIME_Q = diff --git a/evm/contracts/proto/GoogleProtobufAny.sol b/evm/contracts/proto/GoogleProtobufAny.sol index bd36647dd8..2fedbf8643 100644 --- a/evm/contracts/proto/GoogleProtobufAny.sol +++ b/evm/contracts/proto/GoogleProtobufAny.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "./ProtoBufRuntime.sol"; library GoogleProtobufAny { diff --git a/evm/contracts/proto/MockClient.sol b/evm/contracts/proto/MockClient.sol index de6da42c73..7bcf96484a 100644 --- a/evm/contracts/proto/MockClient.sol +++ b/evm/contracts/proto/MockClient.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "./ProtoBufRuntime.sol"; import "./GoogleProtobufAny.sol"; import "./ibc/core/connection/v1/connection.sol"; diff --git a/evm/contracts/proto/ProtoBufRuntime.sol b/evm/contracts/proto/ProtoBufRuntime.sol index f42ee77cc7..b38306c742 100644 --- a/evm/contracts/proto/ProtoBufRuntime.sol +++ b/evm/contracts/proto/ProtoBufRuntime.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; library GoogleProtobufDuration { //struct definition diff --git a/evm/contracts/proto/cosmos/auth/v1beta1/auth.sol b/evm/contracts/proto/cosmos/auth/v1beta1/auth.sol index 07db93710e..4d525fb769 100644 --- a/evm/contracts/proto/cosmos/auth/v1beta1/auth.sol +++ b/evm/contracts/proto/cosmos/auth/v1beta1/auth.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../ProtoBufRuntime.sol"; import "../../../GoogleProtobufAny.sol"; import "../../../cosmos_proto/cosmos.sol"; diff --git a/evm/contracts/proto/cosmos/base/query/v1beta1/pagination.sol b/evm/contracts/proto/cosmos/base/query/v1beta1/pagination.sol index 4bc657377c..c0cc7fce80 100644 --- a/evm/contracts/proto/cosmos/base/query/v1beta1/pagination.sol +++ b/evm/contracts/proto/cosmos/base/query/v1beta1/pagination.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/cosmos/base/v1beta1/coin.sol b/evm/contracts/proto/cosmos/base/v1beta1/coin.sol index 24cb4339f8..b4015fe5fe 100644 --- a/evm/contracts/proto/cosmos/base/v1beta1/coin.sol +++ b/evm/contracts/proto/cosmos/base/v1beta1/coin.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../ProtoBufRuntime.sol"; import "../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/cosmos/ics23/v1/proofs.sol b/evm/contracts/proto/cosmos/ics23/v1/proofs.sol index b7f8746328..120206cc03 100644 --- a/evm/contracts/proto/cosmos/ics23/v1/proofs.sol +++ b/evm/contracts/proto/cosmos/ics23/v1/proofs.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../ProtoBufRuntime.sol"; import "../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/cosmos/upgrade/v1beta1/upgrade.sol b/evm/contracts/proto/cosmos/upgrade/v1beta1/upgrade.sol index 7d5c5948b4..3a53d5f179 100644 --- a/evm/contracts/proto/cosmos/upgrade/v1beta1/upgrade.sol +++ b/evm/contracts/proto/cosmos/upgrade/v1beta1/upgrade.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../ProtoBufRuntime.sol"; import "../../../GoogleProtobufAny.sol"; import "../../../cosmos_proto/cosmos.sol"; diff --git a/evm/contracts/proto/cosmos_proto/cosmos.sol b/evm/contracts/proto/cosmos_proto/cosmos.sol index d1ca41f707..8019b8e781 100644 --- a/evm/contracts/proto/cosmos_proto/cosmos.sol +++ b/evm/contracts/proto/cosmos_proto/cosmos.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../ProtoBufRuntime.sol"; import "../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/google/api/http.sol b/evm/contracts/proto/google/api/http.sol index 420322ef4a..91c8a66fb3 100644 --- a/evm/contracts/proto/google/api/http.sol +++ b/evm/contracts/proto/google/api/http.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../ProtoBufRuntime.sol"; import "../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/fee/v1/ack.sol b/evm/contracts/proto/ibc/applications/fee/v1/ack.sol index 478a6a4b8a..ebdc6b0ae7 100644 --- a/evm/contracts/proto/ibc/applications/fee/v1/ack.sol +++ b/evm/contracts/proto/ibc/applications/fee/v1/ack.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/fee/v1/fee.sol b/evm/contracts/proto/ibc/applications/fee/v1/fee.sol index fb815b31e6..1f11e9724f 100644 --- a/evm/contracts/proto/ibc/applications/fee/v1/fee.sol +++ b/evm/contracts/proto/ibc/applications/fee/v1/fee.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../../cosmos/base/v1beta1/coin.sol"; diff --git a/evm/contracts/proto/ibc/applications/fee/v1/genesis.sol b/evm/contracts/proto/ibc/applications/fee/v1/genesis.sol index b63f26c5b0..0ac7425cb5 100644 --- a/evm/contracts/proto/ibc/applications/fee/v1/genesis.sol +++ b/evm/contracts/proto/ibc/applications/fee/v1/genesis.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/fee/v1/metadata.sol b/evm/contracts/proto/ibc/applications/fee/v1/metadata.sol index ab9c8635ff..02efe83e5d 100644 --- a/evm/contracts/proto/ibc/applications/fee/v1/metadata.sol +++ b/evm/contracts/proto/ibc/applications/fee/v1/metadata.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/fee/v1/query.sol b/evm/contracts/proto/ibc/applications/fee/v1/query.sol index bf63555118..3328e2dd74 100644 --- a/evm/contracts/proto/ibc/applications/fee/v1/query.sol +++ b/evm/contracts/proto/ibc/applications/fee/v1/query.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/fee/v1/tx.sol b/evm/contracts/proto/ibc/applications/fee/v1/tx.sol index 37d4219358..7f90954d40 100644 --- a/evm/contracts/proto/ibc/applications/fee/v1/tx.sol +++ b/evm/contracts/proto/ibc/applications/fee/v1/tx.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/controller.sol b/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/controller.sol index c1f1934aab..b0d75784a0 100644 --- a/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/controller.sol +++ b/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/controller.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../../ProtoBufRuntime.sol"; import "../../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/query.sol b/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/query.sol index c81f05df7d..776c61948e 100644 --- a/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/query.sol +++ b/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/query.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../../ProtoBufRuntime.sol"; import "../../../../../GoogleProtobufAny.sol"; import "./controller.sol"; diff --git a/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/tx.sol b/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/tx.sol index a44b106e51..3d17fac998 100644 --- a/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/tx.sol +++ b/evm/contracts/proto/ibc/applications/interchain_accounts/controller/v1/tx.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../../ProtoBufRuntime.sol"; import "../../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.sol b/evm/contracts/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.sol index 365cf407e2..6d74c45b0f 100644 --- a/evm/contracts/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.sol +++ b/evm/contracts/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../../ProtoBufRuntime.sol"; import "../../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/interchain_accounts/host/v1/host.sol b/evm/contracts/proto/ibc/applications/interchain_accounts/host/v1/host.sol index 99c28d1762..3dd94af8fb 100644 --- a/evm/contracts/proto/ibc/applications/interchain_accounts/host/v1/host.sol +++ b/evm/contracts/proto/ibc/applications/interchain_accounts/host/v1/host.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../../ProtoBufRuntime.sol"; import "../../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/interchain_accounts/host/v1/query.sol b/evm/contracts/proto/ibc/applications/interchain_accounts/host/v1/query.sol index f67ca17a70..0f4bcb0552 100644 --- a/evm/contracts/proto/ibc/applications/interchain_accounts/host/v1/query.sol +++ b/evm/contracts/proto/ibc/applications/interchain_accounts/host/v1/query.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../../ProtoBufRuntime.sol"; import "../../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/interchain_accounts/v1/account.sol b/evm/contracts/proto/ibc/applications/interchain_accounts/v1/account.sol index 619ee8b1f2..79569e4163 100644 --- a/evm/contracts/proto/ibc/applications/interchain_accounts/v1/account.sol +++ b/evm/contracts/proto/ibc/applications/interchain_accounts/v1/account.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../../cosmos_proto/cosmos.sol"; diff --git a/evm/contracts/proto/ibc/applications/interchain_accounts/v1/metadata.sol b/evm/contracts/proto/ibc/applications/interchain_accounts/v1/metadata.sol index 31f2a1fbae..303e7cdef0 100644 --- a/evm/contracts/proto/ibc/applications/interchain_accounts/v1/metadata.sol +++ b/evm/contracts/proto/ibc/applications/interchain_accounts/v1/metadata.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/interchain_accounts/v1/packet.sol b/evm/contracts/proto/ibc/applications/interchain_accounts/v1/packet.sol index 702c07b609..f9054f0bbb 100644 --- a/evm/contracts/proto/ibc/applications/interchain_accounts/v1/packet.sol +++ b/evm/contracts/proto/ibc/applications/interchain_accounts/v1/packet.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/transfer/v1/authz.sol b/evm/contracts/proto/ibc/applications/transfer/v1/authz.sol index b7af76462e..be733abe11 100644 --- a/evm/contracts/proto/ibc/applications/transfer/v1/authz.sol +++ b/evm/contracts/proto/ibc/applications/transfer/v1/authz.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../../cosmos_proto/cosmos.sol"; diff --git a/evm/contracts/proto/ibc/applications/transfer/v1/genesis.sol b/evm/contracts/proto/ibc/applications/transfer/v1/genesis.sol index a545a58c78..8118ca20fb 100644 --- a/evm/contracts/proto/ibc/applications/transfer/v1/genesis.sol +++ b/evm/contracts/proto/ibc/applications/transfer/v1/genesis.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "./transfer.sol"; diff --git a/evm/contracts/proto/ibc/applications/transfer/v1/query.sol b/evm/contracts/proto/ibc/applications/transfer/v1/query.sol index b7bc8b6134..e4a90da9df 100644 --- a/evm/contracts/proto/ibc/applications/transfer/v1/query.sol +++ b/evm/contracts/proto/ibc/applications/transfer/v1/query.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/transfer/v1/transfer.sol b/evm/contracts/proto/ibc/applications/transfer/v1/transfer.sol index 7ac323970c..8c11023507 100644 --- a/evm/contracts/proto/ibc/applications/transfer/v1/transfer.sol +++ b/evm/contracts/proto/ibc/applications/transfer/v1/transfer.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/transfer/v1/tx.sol b/evm/contracts/proto/ibc/applications/transfer/v1/tx.sol index 0a06fabbec..1729d61bc2 100644 --- a/evm/contracts/proto/ibc/applications/transfer/v1/tx.sol +++ b/evm/contracts/proto/ibc/applications/transfer/v1/tx.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/applications/transfer/v2/packet.sol b/evm/contracts/proto/ibc/applications/transfer/v2/packet.sol index 8860198fbf..d8b62a5d54 100644 --- a/evm/contracts/proto/ibc/applications/transfer/v2/packet.sol +++ b/evm/contracts/proto/ibc/applications/transfer/v2/packet.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/core/channel/v1/channel.sol b/evm/contracts/proto/ibc/core/channel/v1/channel.sol index e855df77e7..f106ede604 100644 --- a/evm/contracts/proto/ibc/core/channel/v1/channel.sol +++ b/evm/contracts/proto/ibc/core/channel/v1/channel.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/core/channel/v1/genesis.sol b/evm/contracts/proto/ibc/core/channel/v1/genesis.sol index 243a4f820a..75a76e791b 100644 --- a/evm/contracts/proto/ibc/core/channel/v1/genesis.sol +++ b/evm/contracts/proto/ibc/core/channel/v1/genesis.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/core/channel/v1/query.sol b/evm/contracts/proto/ibc/core/channel/v1/query.sol index 56dd74142e..40a38ee3f2 100644 --- a/evm/contracts/proto/ibc/core/channel/v1/query.sol +++ b/evm/contracts/proto/ibc/core/channel/v1/query.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../client/v1/client.sol"; diff --git a/evm/contracts/proto/ibc/core/channel/v1/tx.sol b/evm/contracts/proto/ibc/core/channel/v1/tx.sol index 5b7cf2493c..c45cf12c60 100644 --- a/evm/contracts/proto/ibc/core/channel/v1/tx.sol +++ b/evm/contracts/proto/ibc/core/channel/v1/tx.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/core/client/v1/client.sol b/evm/contracts/proto/ibc/core/client/v1/client.sol index 6645e523a6..89fee43f0e 100644 --- a/evm/contracts/proto/ibc/core/client/v1/client.sol +++ b/evm/contracts/proto/ibc/core/client/v1/client.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../../cosmos/upgrade/v1beta1/upgrade.sol"; diff --git a/evm/contracts/proto/ibc/core/client/v1/genesis.sol b/evm/contracts/proto/ibc/core/client/v1/genesis.sol index 5df6d7bf0f..0b7b75f018 100644 --- a/evm/contracts/proto/ibc/core/client/v1/genesis.sol +++ b/evm/contracts/proto/ibc/core/client/v1/genesis.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "./client.sol"; diff --git a/evm/contracts/proto/ibc/core/client/v1/query.sol b/evm/contracts/proto/ibc/core/client/v1/query.sol index 8359b9ff2e..c816190bff 100644 --- a/evm/contracts/proto/ibc/core/client/v1/query.sol +++ b/evm/contracts/proto/ibc/core/client/v1/query.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../../cosmos/base/query/v1beta1/pagination.sol"; diff --git a/evm/contracts/proto/ibc/core/client/v1/tx.sol b/evm/contracts/proto/ibc/core/client/v1/tx.sol index 08e50f0c71..e05871f82d 100644 --- a/evm/contracts/proto/ibc/core/client/v1/tx.sol +++ b/evm/contracts/proto/ibc/core/client/v1/tx.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/core/commitment/v1/commitment.sol b/evm/contracts/proto/ibc/core/commitment/v1/commitment.sol index 827e0624d9..2f95e17c6a 100644 --- a/evm/contracts/proto/ibc/core/commitment/v1/commitment.sol +++ b/evm/contracts/proto/ibc/core/commitment/v1/commitment.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../../cosmos/ics23/v1/proofs.sol"; diff --git a/evm/contracts/proto/ibc/core/connection/v1/connection.sol b/evm/contracts/proto/ibc/core/connection/v1/connection.sol index 0cf062e75d..f12d1451e0 100644 --- a/evm/contracts/proto/ibc/core/connection/v1/connection.sol +++ b/evm/contracts/proto/ibc/core/connection/v1/connection.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/core/connection/v1/genesis.sol b/evm/contracts/proto/ibc/core/connection/v1/genesis.sol index 0666230a08..2ff4d38f66 100644 --- a/evm/contracts/proto/ibc/core/connection/v1/genesis.sol +++ b/evm/contracts/proto/ibc/core/connection/v1/genesis.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/core/connection/v1/query.sol b/evm/contracts/proto/ibc/core/connection/v1/query.sol index 30acb13353..8378bd95ff 100644 --- a/evm/contracts/proto/ibc/core/connection/v1/query.sol +++ b/evm/contracts/proto/ibc/core/connection/v1/query.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/core/connection/v1/tx.sol b/evm/contracts/proto/ibc/core/connection/v1/tx.sol index 2240731076..262fdd7db4 100644 --- a/evm/contracts/proto/ibc/core/connection/v1/tx.sol +++ b/evm/contracts/proto/ibc/core/connection/v1/tx.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/core/types/v1/genesis.sol b/evm/contracts/proto/ibc/core/types/v1/genesis.sol index 667951976b..2cde803199 100644 --- a/evm/contracts/proto/ibc/core/types/v1/genesis.sol +++ b/evm/contracts/proto/ibc/core/types/v1/genesis.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/lightclients/solomachine/v2/solomachine.sol b/evm/contracts/proto/ibc/lightclients/solomachine/v2/solomachine.sol index e3c84d1b03..8602ef5aa0 100644 --- a/evm/contracts/proto/ibc/lightclients/solomachine/v2/solomachine.sol +++ b/evm/contracts/proto/ibc/lightclients/solomachine/v2/solomachine.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../core/connection/v1/connection.sol"; diff --git a/evm/contracts/proto/ibc/lightclients/solomachine/v3/solomachine.sol b/evm/contracts/proto/ibc/lightclients/solomachine/v3/solomachine.sol index 9d895192c9..4998037562 100644 --- a/evm/contracts/proto/ibc/lightclients/solomachine/v3/solomachine.sol +++ b/evm/contracts/proto/ibc/lightclients/solomachine/v3/solomachine.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/lightclients/tendermint/v1/tendermint.sol b/evm/contracts/proto/ibc/lightclients/tendermint/v1/tendermint.sol index 85a303368b..88f0246538 100644 --- a/evm/contracts/proto/ibc/lightclients/tendermint/v1/tendermint.sol +++ b/evm/contracts/proto/ibc/lightclients/tendermint/v1/tendermint.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../../tendermint/types/validator.sol"; diff --git a/evm/contracts/proto/ibc/lightclients/wasm/v1/genesis.sol b/evm/contracts/proto/ibc/lightclients/wasm/v1/genesis.sol index aad48760ab..ec7e0b7cc7 100644 --- a/evm/contracts/proto/ibc/lightclients/wasm/v1/genesis.sol +++ b/evm/contracts/proto/ibc/lightclients/wasm/v1/genesis.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/lightclients/wasm/v1/query.sol b/evm/contracts/proto/ibc/lightclients/wasm/v1/query.sol index f1e0d25e96..8551f7cc7e 100644 --- a/evm/contracts/proto/ibc/lightclients/wasm/v1/query.sol +++ b/evm/contracts/proto/ibc/lightclients/wasm/v1/query.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../../cosmos/base/query/v1beta1/pagination.sol"; diff --git a/evm/contracts/proto/ibc/lightclients/wasm/v1/tx.sol b/evm/contracts/proto/ibc/lightclients/wasm/v1/tx.sol index b35f111ee8..1779285efd 100644 --- a/evm/contracts/proto/ibc/lightclients/wasm/v1/tx.sol +++ b/evm/contracts/proto/ibc/lightclients/wasm/v1/tx.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/ibc/lightclients/wasm/v1/wasm.sol b/evm/contracts/proto/ibc/lightclients/wasm/v1/wasm.sol index b29a860e22..814bff207b 100644 --- a/evm/contracts/proto/ibc/lightclients/wasm/v1/wasm.sol +++ b/evm/contracts/proto/ibc/lightclients/wasm/v1/wasm.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../ProtoBufRuntime.sol"; import "../../../../GoogleProtobufAny.sol"; import "../../../core/client/v1/client.sol"; diff --git a/evm/contracts/proto/tendermint/crypto/keys.sol b/evm/contracts/proto/tendermint/crypto/keys.sol index 3bebdacad3..a11a177fda 100644 --- a/evm/contracts/proto/tendermint/crypto/keys.sol +++ b/evm/contracts/proto/tendermint/crypto/keys.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../ProtoBufRuntime.sol"; import "../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/tendermint/crypto/proof.sol b/evm/contracts/proto/tendermint/crypto/proof.sol index 7f6633b4db..f4fdcda1ca 100644 --- a/evm/contracts/proto/tendermint/crypto/proof.sol +++ b/evm/contracts/proto/tendermint/crypto/proof.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../ProtoBufRuntime.sol"; import "../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/tendermint/types/canonical.sol b/evm/contracts/proto/tendermint/types/canonical.sol index 1f372d24d8..60547d6d62 100644 --- a/evm/contracts/proto/tendermint/types/canonical.sol +++ b/evm/contracts/proto/tendermint/types/canonical.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../ProtoBufRuntime.sol"; import "../../GoogleProtobufAny.sol"; import "./types.sol"; diff --git a/evm/contracts/proto/tendermint/types/types.sol b/evm/contracts/proto/tendermint/types/types.sol index 62a29acebe..b8e7612d91 100644 --- a/evm/contracts/proto/tendermint/types/types.sol +++ b/evm/contracts/proto/tendermint/types/types.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../ProtoBufRuntime.sol"; import "../../GoogleProtobufAny.sol"; import "../crypto/proof.sol"; diff --git a/evm/contracts/proto/tendermint/types/validator.sol b/evm/contracts/proto/tendermint/types/validator.sol index e5314ebbd4..39dcf7ddbf 100644 --- a/evm/contracts/proto/tendermint/types/validator.sol +++ b/evm/contracts/proto/tendermint/types/validator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../ProtoBufRuntime.sol"; import "../../GoogleProtobufAny.sol"; import "../crypto/keys.sol"; diff --git a/evm/contracts/proto/tendermint/version/types.sol b/evm/contracts/proto/tendermint/version/types.sol index 3ad4bde127..4726956b51 100644 --- a/evm/contracts/proto/tendermint/version/types.sol +++ b/evm/contracts/proto/tendermint/version/types.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../ProtoBufRuntime.sol"; import "../../GoogleProtobufAny.sol"; diff --git a/evm/contracts/proto/union/ibc/lightclients/cometbls/v1/cometbls.sol b/evm/contracts/proto/union/ibc/lightclients/cometbls/v1/cometbls.sol index 1b3639b201..1d05eb00a9 100644 --- a/evm/contracts/proto/union/ibc/lightclients/cometbls/v1/cometbls.sol +++ b/evm/contracts/proto/union/ibc/lightclients/cometbls/v1/cometbls.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../../../ProtoBufRuntime.sol"; import "../../../../../GoogleProtobufAny.sol"; import "../../../../../tendermint/types/types.sol"; diff --git a/evm/tests/src/02-client/IBCClient.t.sol b/evm/tests/src/02-client/IBCClient.t.sol index af05a681a8..47460915ae 100644 --- a/evm/tests/src/02-client/IBCClient.t.sol +++ b/evm/tests/src/02-client/IBCClient.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {ILightClient} from "../../../contracts/core/02-client/ILightClient.sol"; import {MockClient} from "../../../contracts/clients/MockClient.sol"; diff --git a/evm/tests/src/03-connection/IBCConnection.t.sol b/evm/tests/src/03-connection/IBCConnection.t.sol index bcee25119d..90b424a8e5 100644 --- a/evm/tests/src/03-connection/IBCConnection.t.sol +++ b/evm/tests/src/03-connection/IBCConnection.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {IBCMsgs} from "../../../contracts/core/25-handler/IBCMsgs.sol"; import {MockClient} from "../../../contracts/clients/MockClient.sol"; diff --git a/evm/tests/src/04-channel/IBCChannelHandshake.t.sol b/evm/tests/src/04-channel/IBCChannelHandshake.t.sol index 6a8faebdc1..ac6bd81eaf 100644 --- a/evm/tests/src/04-channel/IBCChannelHandshake.t.sol +++ b/evm/tests/src/04-channel/IBCChannelHandshake.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {IBCMsgs} from "../../../contracts/core/25-handler/IBCMsgs.sol"; import {MockClient} from "../../../contracts/clients/MockClient.sol"; diff --git a/evm/tests/src/04-channel/IBCPacket.t.sol b/evm/tests/src/04-channel/IBCPacket.t.sol index 09a6342e67..24e419c5a5 100644 --- a/evm/tests/src/04-channel/IBCPacket.t.sol +++ b/evm/tests/src/04-channel/IBCPacket.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {IBCMsgs} from "../../../contracts/core/25-handler/IBCMsgs.sol"; import {IbcCoreClientV1Height as ClientHeight} from "../../../contracts/proto/MockClient.sol"; diff --git a/evm/tests/src/24-host/IBCCommitment.t.sol b/evm/tests/src/24-host/IBCCommitment.t.sol index 6a7d02b176..850dd43d2a 100644 --- a/evm/tests/src/24-host/IBCCommitment.t.sol +++ b/evm/tests/src/24-host/IBCCommitment.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {IBCCommitment} from "../../../contracts/core/24-host/IBCCommitment.sol"; diff --git a/evm/tests/src/25-handler/IBCChannelHandler.t.sol b/evm/tests/src/25-handler/IBCChannelHandler.t.sol index 5b9415fc49..85e69f467b 100644 --- a/evm/tests/src/25-handler/IBCChannelHandler.t.sol +++ b/evm/tests/src/25-handler/IBCChannelHandler.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {IBCMsgs} from "../../../contracts/core/25-handler/IBCMsgs.sol"; import {MockClient} from "../../../contracts/clients/MockClient.sol"; diff --git a/evm/tests/src/25-handler/IBCClientHandler.t.sol b/evm/tests/src/25-handler/IBCClientHandler.t.sol index 02e79e32bf..b22a867fcb 100644 --- a/evm/tests/src/25-handler/IBCClientHandler.t.sol +++ b/evm/tests/src/25-handler/IBCClientHandler.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {ILightClient} from "../../../contracts/core/02-client/ILightClient.sol"; import {MockClient} from "../../../contracts/clients/MockClient.sol"; diff --git a/evm/tests/src/25-handler/IBCConnectionHandler.t.sol b/evm/tests/src/25-handler/IBCConnectionHandler.t.sol index 5ad0c0a12f..fcbb0ae4c9 100644 --- a/evm/tests/src/25-handler/IBCConnectionHandler.t.sol +++ b/evm/tests/src/25-handler/IBCConnectionHandler.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {ILightClient} from "../../../contracts/core/02-client/ILightClient.sol"; import {MockClient} from "../../../contracts/clients/MockClient.sol"; diff --git a/evm/tests/src/25-handler/IBCPacketHandler.t.sol b/evm/tests/src/25-handler/IBCPacketHandler.t.sol index adf43b2dbc..d6691e0412 100644 --- a/evm/tests/src/25-handler/IBCPacketHandler.t.sol +++ b/evm/tests/src/25-handler/IBCPacketHandler.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {IBCMsgs} from "../../../contracts/core/25-handler/IBCMsgs.sol"; import {IbcCoreClientV1Height as ClientHeight} from "../../../contracts/proto/MockClient.sol"; diff --git a/evm/tests/src/ICS23.t.sol b/evm/tests/src/ICS23.t.sol index 4a37cfbbf6..fe0e18e890 100644 --- a/evm/tests/src/ICS23.t.sol +++ b/evm/tests/src/ICS23.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "forge-std/Test.sol"; import "../../contracts/proto/cosmos/ics23/v1/proofs.sol"; diff --git a/evm/tests/src/MockApp.t.sol b/evm/tests/src/MockApp.t.sol index 5866b4e34a..355997f251 100644 --- a/evm/tests/src/MockApp.t.sol +++ b/evm/tests/src/MockApp.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../contracts/proto/ibc/core/channel/v1/channel.sol"; import "../../contracts/core/05-port/IIBCModule.sol"; diff --git a/evm/tests/src/TestPlus.sol b/evm/tests/src/TestPlus.sol index c0f3e40969..5bd344732b 100644 --- a/evm/tests/src/TestPlus.sol +++ b/evm/tests/src/TestPlus.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "forge-std/Test.sol"; import "./utils/MsgMocks.sol"; diff --git a/evm/tests/src/TestableIBCHandler.t.sol b/evm/tests/src/TestableIBCHandler.t.sol index 6a89fc9bfb..642b3cdf13 100644 --- a/evm/tests/src/TestableIBCHandler.t.sol +++ b/evm/tests/src/TestableIBCHandler.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../contracts/core/OwnableIBCHandler.sol"; diff --git a/evm/tests/src/apps/ucs/01-relay/Relay.t.sol b/evm/tests/src/apps/ucs/01-relay/Relay.t.sol index 64d376d9b2..b54ab81618 100644 --- a/evm/tests/src/apps/ucs/01-relay/Relay.t.sol +++ b/evm/tests/src/apps/ucs/01-relay/Relay.t.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "forge-std/Test.sol"; import "solidity-stringutils/strings.sol"; diff --git a/evm/tests/src/utils/Cometbls.sol b/evm/tests/src/utils/Cometbls.sol index f572acc051..ad22b16cf3 100644 --- a/evm/tests/src/utils/Cometbls.sol +++ b/evm/tests/src/utils/Cometbls.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "forge-std/Test.sol"; import {IBCMsgs} from "../../../contracts/core/25-handler/IBCMsgs.sol"; diff --git a/evm/tests/src/utils/IBCHandler_Testable.sol b/evm/tests/src/utils/IBCHandler_Testable.sol index 7cb8d3dc57..161f53d52e 100644 --- a/evm/tests/src/utils/IBCHandler_Testable.sol +++ b/evm/tests/src/utils/IBCHandler_Testable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {IBCHandler} from "../../../contracts/core/25-handler/IBCHandler.sol"; import {IbcCoreConnectionV1ConnectionEnd} from "../../../contracts/proto/ibc/core/connection/v1/connection.sol"; diff --git a/evm/tests/src/utils/MembershipVerifier_Testable.sol b/evm/tests/src/utils/MembershipVerifier_Testable.sol index e011f63ff7..f72436e333 100644 --- a/evm/tests/src/utils/MembershipVerifier_Testable.sol +++ b/evm/tests/src/utils/MembershipVerifier_Testable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "../../../contracts/core/IMembershipVerifier.sol"; diff --git a/evm/tests/src/utils/MockApp.sol b/evm/tests/src/utils/MockApp.sol index b8c5ae6408..142bf986d2 100644 --- a/evm/tests/src/utils/MockApp.sol +++ b/evm/tests/src/utils/MockApp.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import {IbcCoreChannelV1Packet as Packet, IbcCoreChannelV1GlobalEnums as ChannelEnums, IbcCoreChannelV1Counterparty as ChannelCounterparty} from "../../../contracts/proto/ibc/core/channel/v1/channel.sol"; import {IIBCModule} from "../../../contracts/core/05-port/IIBCModule.sol"; diff --git a/evm/tests/src/utils/MsgMocks.sol b/evm/tests/src/utils/MsgMocks.sol index 34b26243cc..737ee2887c 100644 --- a/evm/tests/src/utils/MsgMocks.sol +++ b/evm/tests/src/utils/MsgMocks.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "forge-std/Test.sol"; import {IBCMsgs} from "../../../contracts/core/25-handler/IBCMsgs.sol"; diff --git a/evm/tests/src/utils/TestUtils.sol b/evm/tests/src/utils/TestUtils.sol index 571f054308..c0bc01fe43 100644 --- a/evm/tests/src/utils/TestUtils.sol +++ b/evm/tests/src/utils/TestUtils.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.21; +pragma solidity ^0.8.23; import "forge-std/Test.sol"; import {IBCMsgs} from "../../../contracts/core/25-handler/IBCMsgs.sol"; diff --git a/flake.nix b/flake.nix index 9a4bd2ae0e..2c159634da 100644 --- a/flake.nix +++ b/flake.nix @@ -200,7 +200,42 @@ iohk-nix.overlays.crypto foundry.overlay (_: _: { - solc = nixpkgs-solc.legacyPackages.${system}.solc; + solc = + let + jsoncppVersion = "1.9.3"; + jsoncppUrl = "https://github.com/open-source-parsers/jsoncpp/archive/${jsoncppVersion}.tar.gz"; + jsoncpp = pkgs.fetchzip { + url = jsoncppUrl; + sha256 = "1vbhi503rgwarf275ajfdb8vpdcbn1f7917wjkf8jghqwb1c24lq"; + }; + range3Version = "0.12.0"; + range3Url = "https://github.com/ericniebler/range-v3/archive/${range3Version}.tar.gz"; + range3 = pkgs.fetchzip { + url = range3Url; + sha256 = "sha256-bRSX91+ROqG1C3nB9HSQaKgLzOHEFy9mrD2WW3PRBWU="; + }; + fmtlibVersion = "9.1.0"; + fmtlibUrl = "https://github.com/fmtlib/fmt/archive/${fmtlibVersion}.tar.gz"; + fmtlib = pkgs.fetchzip { + url = fmtlibUrl; + sha256 = "1mnvxqsan034d2jiqnw2yvkljl7lwvhakmj5bscwp1fpkn655bbw"; + }; + in + nixpkgs-solc.legacyPackages.${system}.solc.overrideAttrs (old: old // rec { + version = "0.8.23"; + src = pkgs.fetchzip { + url = "https://github.com/ethereum/solidity/releases/download/v${version}/solidity_${version}.tar.gz"; + sha256 = "sha256-9GIDfjkjDFrZQ0uqopDycMWYUN+M9yLF9NpOgSksXqI="; + }; + postPatch = '' + substituteInPlace cmake/jsoncpp.cmake \ + --replace "${jsoncppUrl}" ${jsoncpp} + substituteInPlace cmake/range-v3.cmake \ + --replace "${range3Url}" ${range3} + substituteInPlace cmake/fmtlib.cmake \ + --replace "${fmtlibUrl}" ${fmtlib} + ''; + }); }) ]); From 09d76c7eaf8c9a2171a3a920c7ac5e2b69aada71 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Mon, 8 Jan 2024 17:51:36 +0100 Subject: [PATCH 02/14] feat(us01-relay): implement initial solidity tests --- evm/tests/src/apps/ucs/01-relay/Relay.t.sol | 390 ++++++++++++++++++++ 1 file changed, 390 insertions(+) diff --git a/evm/tests/src/apps/ucs/01-relay/Relay.t.sol b/evm/tests/src/apps/ucs/01-relay/Relay.t.sol index b54ab81618..751aacb7ec 100644 --- a/evm/tests/src/apps/ucs/01-relay/Relay.t.sol +++ b/evm/tests/src/apps/ucs/01-relay/Relay.t.sol @@ -4,9 +4,45 @@ import "forge-std/Test.sol"; import "solidity-stringutils/strings.sol"; import "solady/utils/LibString.sol"; import "../../../../../contracts/apps/ucs/01-relay/Relay.sol"; +import "../../../../../contracts/apps/ucs/01-relay/ERC20Denom.sol"; +import "../../../../../contracts/apps/ucs/01-relay/IERC20Denom.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "../../../utils/IBCHandler_Testable.sol"; +import {IBCHandler} from "../../../../../contracts/core/25-handler/IBCHandler.sol"; +import {IBCConnection} from "../../../../../contracts/core/03-connection/IBCConnection.sol"; +import {IBCClient} from "../../../../../contracts/core/02-client/IBCClient.sol"; +import {IBCChannelHandshake} from "../../../../../contracts/core/04-channel/IBCChannelHandshake.sol"; +import {IIBCPacket} from "../../../../../contracts/core/04-channel/IIBCChannel.sol"; +import {IBCPacket} from "../../../../../contracts/core/04-channel/IBCPacket.sol"; + +contract IBCHandlerFake is IBCHandler { + constructor() + IBCHandler( + address(new IBCClient()), + address(new IBCConnection()), + address(new IBCChannelHandshake()), + address(new IBCPacket()) + ) + {} + + function sendPacket( + string calldata sourcePort, + string calldata sourceChannel, + IbcCoreClientV1Height.Data calldata timeoutHeight, + uint64 timeoutTimestamp, + bytes calldata data + ) external override {} +} contract RelayTests is Test { using LibString for *; + using strings for *; + + IBCHandler ibcHandler; + + constructor() { + ibcHandler = new IBCHandlerFake(); + } function testRelay_isRemote_ok() public { assertEq(RelayLib.isRemote("a", "b", "a/b/X"), true); @@ -37,4 +73,358 @@ contract RelayTests is Test { function testRelay_hexToAddress(address addr) public { assertEq(RelayLib.hexToAddress(addr.toHexString()), addr); } + + function testRelay_onRecvPacketProcessing_onlySelf( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + address relayer + ) public { + vm.startPrank(address(ibcHandler)); + + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + relay.onRecvPacketProcessing( + IbcCoreChannelV1Packet.Data({ + sequence: sequence, + source_port: sourcePort, + source_channel: sourceChannel, + destination_port: destinationPort, + destination_channel: destinationChannel, + data: hex"00", + timeout_height: IbcCoreClientV1Height.Data({ + revision_number: timeoutRevisionNumber, + revision_height: timeoutRevisionHeight + }), + timeout_timestamp: timeoutTimestamp + }), + relayer + ); + } + + function testRelay_onRecvPacket_invalidIdentity( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + address relayer + ) public { + vm.startPrank(address(ibcHandler)); + + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.record(); + bytes memory acknowledgement = relay.onRecvPacket( + IbcCoreChannelV1Packet.Data({ + sequence: sequence, + source_port: sourcePort, + source_channel: sourceChannel, + destination_port: destinationPort, + destination_channel: destinationChannel, + data: hex"00", + timeout_height: IbcCoreClientV1Height.Data({ + revision_number: timeoutRevisionNumber, + revision_height: timeoutRevisionHeight + }), + timeout_timestamp: timeoutTimestamp + }), + relayer + ); + (bytes32[] memory reads, bytes32[] memory writes) = vm.accesses( + address(relay) + ); + assertEq(writes.length, 0); + assertEq(acknowledgement, abi.encodePacked(RelayLib.ACK_FAILURE)); + } + + function testRelay_send_local( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + bytes memory sender, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = new UCS01Relay(ibcHandler); + + vm.prank(address(ibcHandler)); + relay.onChanOpenTry( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + RelayLib.VERSION, + RelayLib.VERSION + ); + + ERC20Denom denomAddress = new ERC20Denom(denomName); + IERC20Denom(denomAddress).mint(address(this), amount); + IERC20Denom(denomAddress).approve(address(relay), amount); + + LocalToken[] memory localTokens = new LocalToken[](1); + localTokens[0].denom = address(denomAddress); + localTokens[0].amount = amount; + + vm.expectEmit(false, false, false, false); + emit RelayLib.Sent(address(0), "", "", address(0), 0); + + relay.send( + destinationPort, + destinationChannel, + sender, + localTokens, + 0, + 0 + ); + } + + function testRelay_onRecvPacket_localToken( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + bytes memory sender, + address receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(receiver != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = new UCS01Relay(ibcHandler); + + vm.prank(address(ibcHandler)); + relay.onChanOpenTry( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + RelayLib.VERSION, + RelayLib.VERSION + ); + + ERC20Denom denomAddress = new ERC20Denom(denomName); + IERC20Denom(denomAddress).mint(address(this), amount); + IERC20Denom(denomAddress).approve(address(relay), amount); + + LocalToken[] memory localTokens = new LocalToken[](1); + localTokens[0].denom = address(denomAddress); + localTokens[0].amount = amount; + + vm.expectEmit(false, false, false, false); + emit RelayLib.Sent(address(0), "", "", address(0), 0); + + relay.send( + destinationPort, + destinationChannel, + sender, + localTokens, + 0, + 0 + ); + + Token[] memory tokens = new Token[](1); + tokens[0].denom = RelayLib.makeForeignDenom( + destinationPort, + destinationChannel, + address(denomAddress).toHexString() + ); + tokens[0].amount = amount; + + vm.expectEmit(false, false, false, false); + emit RelayLib.Received("", address(0), "", address(0), 0); + + vm.prank(address(relay)); + relay.onRecvPacketProcessing( + IbcCoreChannelV1Packet.Data({ + sequence: sequence, + source_port: sourcePort, + source_channel: sourceChannel, + destination_port: destinationPort, + destination_channel: destinationChannel, + data: RelayPacketLib.encode( + RelayPacket({ + sender: sender, + receiver: abi.encodePacked(receiver), + tokens: tokens + }) + ), + timeout_height: IbcCoreClientV1Height.Data({ + revision_number: timeoutRevisionNumber, + revision_height: timeoutRevisionHeight + }), + timeout_timestamp: timeoutTimestamp + }), + relayer + ); + } + + function testRelay_onRecvPacket_remoteToken( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + bytes memory sender, + address receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(receiver != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = new UCS01Relay(ibcHandler); + + Token[] memory tokens = new Token[](1); + tokens[0].denom = denomName; + tokens[0].amount = amount; + + vm.expectEmit(false, false, false, false); + emit RelayLib.DenomCreated("", address(0)); + + vm.expectEmit(false, false, false, false); + emit RelayLib.Received("", address(0), "", address(0), 0); + + vm.prank(address(relay)); + relay.onRecvPacketProcessing( + IbcCoreChannelV1Packet.Data({ + sequence: sequence, + source_port: sourcePort, + source_channel: sourceChannel, + destination_port: destinationPort, + destination_channel: destinationChannel, + data: RelayPacketLib.encode( + RelayPacket({ + sender: sender, + receiver: abi.encodePacked(receiver), + tokens: tokens + }) + ), + timeout_height: IbcCoreClientV1Height.Data({ + revision_number: timeoutRevisionNumber, + revision_height: timeoutRevisionHeight + }), + timeout_timestamp: timeoutTimestamp + }), + relayer + ); + } + + function testRelay_send_remote( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + bytes memory sender, + address receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(receiver != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = new UCS01Relay(ibcHandler); + + { + Token[] memory tokens = new Token[](1); + tokens[0].denom = denomName; + tokens[0].amount = amount; + + vm.expectEmit(false, false, false, false); + emit RelayLib.DenomCreated("", address(0)); + + vm.expectEmit(false, false, false, false); + emit IERC20.Transfer(address(0), address(0), 0); + + vm.expectEmit(false, false, false, false); + emit RelayLib.Received("", address(0), "", address(0), 0); + + vm.prank(address(relay)); + relay.onRecvPacketProcessing( + IbcCoreChannelV1Packet.Data({ + sequence: sequence, + source_port: sourcePort, + source_channel: sourceChannel, + destination_port: destinationPort, + destination_channel: destinationChannel, + data: RelayPacketLib.encode( + RelayPacket({ + sender: sender, + receiver: abi.encodePacked(receiver), + tokens: tokens + }) + ), + timeout_height: IbcCoreClientV1Height.Data({ + revision_number: timeoutRevisionNumber, + revision_height: timeoutRevisionHeight + }), + timeout_timestamp: timeoutTimestamp + }), + relayer + ); + } + + { + address denomAddress = relay.getDenomAddress( + RelayLib.makeForeignDenom(sourcePort, sourceChannel, denomName) + ); + + LocalToken[] memory localTokens = new LocalToken[](1); + localTokens[0].denom = denomAddress; + localTokens[0].amount = amount; + + vm.startPrank(receiver); + IERC20Denom(denomAddress).approve(address(relay), amount); + + vm.expectEmit(false, false, false, false); + emit RelayLib.Sent(address(0), "", "", address(0), 0); + + relay.send( + destinationPort, + destinationChannel, + sender, + localTokens, + 0, + 0 + ); + } + } } From ad1f374fa04b62b468dc46ed42152667ab46498b Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Mon, 8 Jan 2024 18:32:22 +0100 Subject: [PATCH 03/14] feat(evm): add lcov file to coverage output/upgrade foudry monthly --- evm/evm.nix | 4 ++-- flake.lock | 8 ++++---- flake.nix | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/evm/evm.nix b/evm/evm.nix index d30af38dec..485e84e439 100644 --- a/evm/evm.nix +++ b/evm/evm.nix @@ -313,12 +313,12 @@ }; evm-coverage = - pkgs.runCommand "evm-coverage.log" + pkgs.runCommand "evm-coverage" { buildInputs = [ wrappedForge pkgs.lcov ]; } '' forge coverage --ir-minimum --report lcov && \ - genhtml lcov.info -o $out --branch-coverag + genhtml lcov.info -o $out --branch-coverag && mv lcov.info $out ''; forge = wrappedForge; diff --git a/flake.lock b/flake.lock index 7e2b41326f..24bf363358 100644 --- a/flake.lock +++ b/flake.lock @@ -195,16 +195,16 @@ ] }, "locked": { - "lastModified": 1704791364, - "narHash": "sha256-ebZIEDDwXLnYimP79kbuLPiSWVMgc//FiVH/UVTMHlA=", + "lastModified": 1704705059, + "narHash": "sha256-fAfVGg4xrFsJy9EE9abkdxxMNEM80+V56JmUjaRnpIE=", "owner": "shazow", "repo": "foundry.nix", - "rev": "c91128d616bcf70feedee7b51401587011f3b791", + "rev": "ee8da03e7b8526fe289ff76af74319a429b46e5d", "type": "github" }, "original": { "owner": "shazow", - "ref": "main", + "ref": "monthly", "repo": "foundry.nix", "type": "github" } diff --git a/flake.nix b/flake.nix index 2c159634da..07f6285264 100644 --- a/flake.nix +++ b/flake.nix @@ -24,7 +24,7 @@ inputs.nixpkgs.follows = "nixpkgs"; }; foundry = { - url = "github:shazow/foundry.nix/main"; + url = "github:shazow/foundry.nix/monthly"; inputs.nixpkgs.follows = "nixpkgs"; }; rust-overlay = { From c0c45e45b80447464f89184357c6a291bbec90c9 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Tue, 9 Jan 2024 16:09:57 +0100 Subject: [PATCH 04/14] feat(evm): missing virtual `onTimeoutPacket`, better error string --- evm/contracts/apps/Base.sol | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/evm/contracts/apps/Base.sol b/evm/contracts/apps/Base.sol index 9d3e5d2f23..5d2c52c5b4 100644 --- a/evm/contracts/apps/Base.sol +++ b/evm/contracts/apps/Base.sol @@ -26,7 +26,7 @@ abstract contract IBCAppBase is Context, IIBCModule { function _checkIBC() internal view virtual { require( ibcAddress() == _msgSender(), - "_checkIBC: caller is not the IBC contract" + "IBCAppBase: caller is not the IBC contract" ); } @@ -127,4 +127,9 @@ abstract contract IBCAppBase is Context, IIBCModule { bytes calldata acknowledgement, address relayer ) external virtual override onlyIBC {} + + function onTimeoutPacket( + IbcCoreChannelV1Packet.Data calldata packet, + address relayer + ) external virtual override onlyIBC {} } From 35aa7b2607569f623de1f0fe6f6c9f33ae9c3d1f Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Tue, 9 Jan 2024 16:10:26 +0100 Subject: [PATCH 05/14] feat(evm): better error string --- evm/contracts/apps/ucs/01-relay/ERC20Denom.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evm/contracts/apps/ucs/01-relay/ERC20Denom.sol b/evm/contracts/apps/ucs/01-relay/ERC20Denom.sol index c514c998b8..47fa0e51a6 100644 --- a/evm/contracts/apps/ucs/01-relay/ERC20Denom.sol +++ b/evm/contracts/apps/ucs/01-relay/ERC20Denom.sol @@ -11,12 +11,12 @@ contract ERC20Denom is ERC20, IERC20Denom { } function mint(address to, uint256 amount) external { - require(msg.sender == admin, "only admin"); + require(msg.sender == admin, "ERC20Denom: only admin"); _mint(to, amount); } function burn(address from, uint256 amount) external { - require(msg.sender == admin, "only admin"); + require(msg.sender == admin, "ERC20Denom: only admin"); _burn(from, amount); } } From 995ec1a2b066e53c43225525f08bbfabf714c3f1 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Tue, 9 Jan 2024 16:10:42 +0100 Subject: [PATCH 06/14] feat(evm): ucs01: more sanity checks, better errors and simplify --- evm/contracts/apps/ucs/01-relay/Relay.sol | 54 ++++++++++++++--------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/evm/contracts/apps/ucs/01-relay/Relay.sol b/evm/contracts/apps/ucs/01-relay/Relay.sol index 79bc3ddfdf..18ad3101c3 100644 --- a/evm/contracts/apps/ucs/01-relay/Relay.sol +++ b/evm/contracts/apps/ucs/01-relay/Relay.sol @@ -51,6 +51,13 @@ library RelayLib { address token, uint256 amount ); + event Timeout( + address sender, + string receiver, + string denom, + address token, + uint256 amount + ); function isValidVersion( string memory version @@ -87,7 +94,7 @@ library RelayLib { function hexToAddress( string memory _a ) internal pure returns (address _parsedAddress) { - require(bytes(_a).length == 42, "ucs01-relay: invalid address"); + require(bytes(_a).length == 42, "ucs01-relay: invalid hex address"); bytes memory tmp = bytes(_a); uint160 iaddr = 0; uint160 b1; @@ -116,7 +123,7 @@ library RelayLib { } function bytesToAddress(bytes memory b) internal pure returns (address) { - require(b.length == 20, "ucs01-relay: invalid address"); + require(b.length == 20, "ucs01-relay: invalid bytes address"); return address(uint160(bytes20(b))); } } @@ -170,18 +177,25 @@ contract UCS01Relay is IBCAppBase { return denomToAddress[denom]; } - function getAddressDenom(address addr) public view returns (string memory) { - return addressToDenom[addr]; - } - function getOutstanding( string memory sourcePort, string memory sourceChannel, address token ) public view returns (uint256) { + require( + token != address(0), + "ucs01-relay: getOutstanding: address is zero" + ); return outstanding[sourcePort][sourceChannel][token]; } + function getCounterpartyEndpoint( + string memory portId, + string memory channelId + ) public view returns (IbcCoreChannelV1Counterparty.Data memory) { + return counterpartyEndpoints[portId][channelId]; + } + function increaseOutstanding( string memory portId, string memory channelId, @@ -298,15 +312,16 @@ contract UCS01Relay is IBCAppBase { string memory channelId, RelayPacket memory packet ) internal { + string memory receiver = packet.receiver.toHexString(); // We're going to refund, the receiver will be the sender. - address receiver = RelayLib.bytesToAddress(packet.sender); + address userToRefund = RelayLib.bytesToAddress(packet.sender); for (uint256 i = 0; i < packet.tokens.length; i++) { Token memory token = packet.tokens[i]; // Either we tried to send back a remote native token // which we burnt, or a locally native token that we escrowed. address denomAddress = denomToAddress[token.denom]; if (denomAddress != address(0)) { - IERC20Denom(denomAddress).mint(receiver, token.amount); + IERC20Denom(denomAddress).mint(userToRefund, token.amount); } else { // It must be in the form 0x... denomAddress = RelayLib.hexToAddress(token.denom); @@ -316,17 +331,18 @@ contract UCS01Relay is IBCAppBase { denomAddress, token.amount ); - IERC20(denomAddress).transfer(receiver, token.amount); + IERC20(denomAddress).transfer(userToRefund, token.amount); } + emit RelayLib.Timeout( + userToRefund, + receiver, + token.denom, + denomAddress, + token.amount + ); } } - function tokensLanded( - string memory portId, - string memory channelId, - RelayPacket memory packet - ) internal {} - function onRecvPacketProcessing( IbcCoreChannelV1Packet.Data calldata ibcPacket, address relayer @@ -415,13 +431,7 @@ contract UCS01Relay is IBCAppBase { "ucs01-relay: single byte ack" ); RelayPacket memory packet = RelayPacketLib.decode(ibcPacket.data); - if (acknowledgement[0] == RelayLib.ACK_SUCCESS) { - tokensLanded( - ibcPacket.source_port, - ibcPacket.source_channel, - packet - ); - } else { + if (acknowledgement[0] == RelayLib.ACK_FAILURE) { refundTokens( ibcPacket.source_port, ibcPacket.source_channel, From a2003d20ecc514b3fc1cf3c7d9ba1ad23c496da9 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Tue, 9 Jan 2024 16:11:14 +0100 Subject: [PATCH 07/14] feat(evm): `VIA_IR` is better with `OPTIMIZER = false` --- evm/evm.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evm/evm.nix b/evm/evm.nix index 485e84e439..2b1825791b 100644 --- a/evm/evm.nix +++ b/evm/evm.nix @@ -80,9 +80,9 @@ hash = "sha256-9D9Mxuk/5bzX3tZjRAnWk7LP/GMOe0NRsrMuvOfKy78="; }; foundryEnv = { - FOUNDRY_OPTIMIZER = "true"; + FOUNDRY_OPTIMIZER = "false"; FOUNDRY_VIA_IR = "true"; - FOUNDRY_OPTIMIZER_RUNS = "10000"; + FOUNDRY_OPTIMIZER_RUNS = "0"; FOUNDRY_SRC = "${evmSources}/contracts"; FOUNDRY_TEST = "${evmSources}/tests/src"; FOUNDRY_LIBS = ''["${libraries}"]''; From f2a602a0654df4a8484b7a5619244ca093041234 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Tue, 9 Jan 2024 16:11:47 +0100 Subject: [PATCH 08/14] feat(evm): ucs01: introduce more tests --- evm/tests/src/apps/ucs/01-relay/Relay.t.sol | 1475 +++++++++++++++---- 1 file changed, 1198 insertions(+), 277 deletions(-) diff --git a/evm/tests/src/apps/ucs/01-relay/Relay.t.sol b/evm/tests/src/apps/ucs/01-relay/Relay.t.sol index 751aacb7ec..4ca5bb33b5 100644 --- a/evm/tests/src/apps/ucs/01-relay/Relay.t.sol +++ b/evm/tests/src/apps/ucs/01-relay/Relay.t.sol @@ -16,6 +16,8 @@ import {IIBCPacket} from "../../../../../contracts/core/04-channel/IIBCChannel.s import {IBCPacket} from "../../../../../contracts/core/04-channel/IBCPacket.sol"; contract IBCHandlerFake is IBCHandler { + IbcCoreChannelV1Packet.Data[] packets; + constructor() IBCHandler( address(new IBCClient()), @@ -31,262 +33,145 @@ contract IBCHandlerFake is IBCHandler { IbcCoreClientV1Height.Data calldata timeoutHeight, uint64 timeoutTimestamp, bytes calldata data - ) external override {} + ) external override { + packets.push( + IbcCoreChannelV1Packet.Data({ + sequence: 0, + source_port: sourcePort, + source_channel: sourceChannel, + destination_port: "dummy-port", + destination_channel: "dummy-channel", + data: data, + timeout_height: timeoutHeight, + timeout_timestamp: timeoutTimestamp + }) + ); + } + + function lastPacket() + public + view + returns (IbcCoreChannelV1Packet.Data memory) + { + return packets[packets.length - 1]; + } } contract RelayTests is Test { using LibString for *; using strings for *; - IBCHandler ibcHandler; + IBCHandlerFake ibcHandler; constructor() { ibcHandler = new IBCHandlerFake(); } - function testRelay_isRemote_ok() public { - assertEq(RelayLib.isRemote("a", "b", "a/b/X"), true); - assertEq(RelayLib.isRemote("aa.bb", "c", "aa.bb/c/X"), true); - } - - function testRelay_isRemote_ko() public { - assertEq(RelayLib.isRemote("a", "b", "b/b/X"), false); - assertEq(RelayLib.isRemote("aa.bb", "c", "aa.b/c/X"), false); - } - - function testRelay_makeForeignDenom() public { - assertEq(RelayLib.makeForeignDenom("a", "b", "BLA"), "a/b/BLA"); - assertEq( - RelayLib.makeForeignDenom("wasm.xyz", "channel-1", "muno"), - "wasm.xyz/channel-1/muno" - ); - } - - function testRelay_makeDenomPrefix() public { - assertEq(RelayLib.makeDenomPrefix("a", "b"), "a/b/"); - assertEq( - RelayLib.makeDenomPrefix("wasm.xyz", "channel-99"), - "wasm.xyz/channel-99/" - ); - } - - function testRelay_hexToAddress(address addr) public { - assertEq(RelayLib.hexToAddress(addr.toHexString()), addr); - } - - function testRelay_onRecvPacketProcessing_onlySelf( - uint64 sequence, + function initChannel( + UCS01Relay relay, string memory sourcePort, string memory sourceChannel, string memory destinationPort, - string memory destinationChannel, - uint64 timeoutRevisionNumber, - uint64 timeoutRevisionHeight, - uint64 timeoutTimestamp, - address relayer + string memory destinationChannel ) public { - vm.startPrank(address(ibcHandler)); - - UCS01Relay relay = new UCS01Relay(ibcHandler); - vm.expectRevert(); - relay.onRecvPacketProcessing( - IbcCoreChannelV1Packet.Data({ - sequence: sequence, - source_port: sourcePort, - source_channel: sourceChannel, - destination_port: destinationPort, - destination_channel: destinationChannel, - data: hex"00", - timeout_height: IbcCoreClientV1Height.Data({ - revision_number: timeoutRevisionNumber, - revision_height: timeoutRevisionHeight - }), - timeout_timestamp: timeoutTimestamp + vm.prank(address(ibcHandler)); + relay.onChanOpenTry( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel }), - relayer + RelayLib.VERSION, + RelayLib.VERSION ); } - function testRelay_onRecvPacket_invalidIdentity( - uint64 sequence, + function createRelay( string memory sourcePort, string memory sourceChannel, string memory destinationPort, - string memory destinationChannel, - uint64 timeoutRevisionNumber, - uint64 timeoutRevisionHeight, - uint64 timeoutTimestamp, - address relayer - ) public { - vm.startPrank(address(ibcHandler)); - + string memory destinationChannel + ) public returns (UCS01Relay) { UCS01Relay relay = new UCS01Relay(ibcHandler); - vm.record(); - bytes memory acknowledgement = relay.onRecvPacket( - IbcCoreChannelV1Packet.Data({ - sequence: sequence, - source_port: sourcePort, - source_channel: sourceChannel, - destination_port: destinationPort, - destination_channel: destinationChannel, - data: hex"00", - timeout_height: IbcCoreClientV1Height.Data({ - revision_number: timeoutRevisionNumber, - revision_height: timeoutRevisionHeight - }), - timeout_timestamp: timeoutTimestamp - }), - relayer - ); - (bytes32[] memory reads, bytes32[] memory writes) = vm.accesses( - address(relay) + + initChannel( + relay, + destinationPort, + destinationChannel, + sourcePort, + sourceChannel ); - assertEq(writes.length, 0); - assertEq(acknowledgement, abi.encodePacked(RelayLib.ACK_FAILURE)); + + return relay; } - function testRelay_send_local( + function sendLocalToken( + UCS01Relay relay, string memory sourcePort, string memory sourceChannel, - string memory destinationPort, - string memory destinationChannel, - bytes memory sender, - address relayer, + address sender, + bytes memory receiver, string memory denomName, uint128 amount - ) public { - vm.assume(relayer != address(0)); - vm.assume(amount > 0); - - UCS01Relay relay = new UCS01Relay(ibcHandler); - - vm.prank(address(ibcHandler)); - relay.onChanOpenTry( - IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, - new string[](0), - destinationPort, - destinationChannel, - IbcCoreChannelV1Counterparty.Data({ - port_id: sourcePort, - channel_id: sourceChannel - }), - RelayLib.VERSION, - RelayLib.VERSION - ); + ) public returns (address) { + address denomAddress = address(new ERC20Denom(denomName)); + IERC20Denom(denomAddress).mint(address(sender), amount); - ERC20Denom denomAddress = new ERC20Denom(denomName); - IERC20Denom(denomAddress).mint(address(this), amount); + vm.prank(sender); IERC20Denom(denomAddress).approve(address(relay), amount); LocalToken[] memory localTokens = new LocalToken[](1); - localTokens[0].denom = address(denomAddress); + localTokens[0].denom = denomAddress; localTokens[0].amount = amount; + vm.expectEmit(); + emit IERC20.Transfer(address(sender), address(relay), amount); + vm.expectEmit(false, false, false, false); emit RelayLib.Sent(address(0), "", "", address(0), 0); - relay.send( - destinationPort, - destinationChannel, - sender, - localTokens, - 0, - 0 - ); + vm.prank(sender); + relay.send(sourcePort, sourceChannel, receiver, localTokens, 0, 0); + + return denomAddress; } - function testRelay_onRecvPacket_localToken( - uint64 sequence, + function sendRemoteToken( + UCS01Relay relay, string memory sourcePort, string memory sourceChannel, - string memory destinationPort, - string memory destinationChannel, - uint64 timeoutRevisionNumber, - uint64 timeoutRevisionHeight, - uint64 timeoutTimestamp, bytes memory sender, address receiver, - address relayer, - string memory denomName, + address denomAddress, uint128 amount ) public { - vm.assume(receiver != address(0)); - vm.assume(relayer != address(0)); - vm.assume(amount > 0); - - UCS01Relay relay = new UCS01Relay(ibcHandler); - - vm.prank(address(ibcHandler)); - relay.onChanOpenTry( - IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, - new string[](0), - destinationPort, - destinationChannel, - IbcCoreChannelV1Counterparty.Data({ - port_id: sourcePort, - channel_id: sourceChannel - }), - RelayLib.VERSION, - RelayLib.VERSION - ); - - ERC20Denom denomAddress = new ERC20Denom(denomName); - IERC20Denom(denomAddress).mint(address(this), amount); + vm.prank(receiver); IERC20Denom(denomAddress).approve(address(relay), amount); LocalToken[] memory localTokens = new LocalToken[](1); - localTokens[0].denom = address(denomAddress); + localTokens[0].denom = denomAddress; localTokens[0].amount = amount; - vm.expectEmit(false, false, false, false); - emit RelayLib.Sent(address(0), "", "", address(0), 0); - - relay.send( - destinationPort, - destinationChannel, - sender, - localTokens, - 0, - 0 - ); + // Transfer from user to relay + vm.expectEmit(); + emit IERC20.Transfer(address(receiver), address(relay), amount); - Token[] memory tokens = new Token[](1); - tokens[0].denom = RelayLib.makeForeignDenom( - destinationPort, - destinationChannel, - address(denomAddress).toHexString() - ); - tokens[0].amount = amount; + // Burn from relay to zero + vm.expectEmit(); + emit IERC20.Transfer(address(relay), address(0), amount); vm.expectEmit(false, false, false, false); - emit RelayLib.Received("", address(0), "", address(0), 0); + emit RelayLib.Sent(address(0), "", "", address(0), 0); - vm.prank(address(relay)); - relay.onRecvPacketProcessing( - IbcCoreChannelV1Packet.Data({ - sequence: sequence, - source_port: sourcePort, - source_channel: sourceChannel, - destination_port: destinationPort, - destination_channel: destinationChannel, - data: RelayPacketLib.encode( - RelayPacket({ - sender: sender, - receiver: abi.encodePacked(receiver), - tokens: tokens - }) - ), - timeout_height: IbcCoreClientV1Height.Data({ - revision_number: timeoutRevisionNumber, - revision_height: timeoutRevisionHeight - }), - timeout_timestamp: timeoutTimestamp - }), - relayer - ); + vm.prank(receiver); + relay.send(sourcePort, sourceChannel, sender, localTokens, 0, 0); } - function testRelay_onRecvPacket_remoteToken( + function receiveRemoteToken( + UCS01Relay relay, uint64 sequence, string memory sourcePort, string memory sourceChannel, @@ -301,12 +186,6 @@ contract RelayTests is Test { string memory denomName, uint128 amount ) public { - vm.assume(receiver != address(0)); - vm.assume(relayer != address(0)); - vm.assume(amount > 0); - - UCS01Relay relay = new UCS01Relay(ibcHandler); - Token[] memory tokens = new Token[](1); tokens[0].denom = denomName; tokens[0].amount = amount; @@ -314,11 +193,14 @@ contract RelayTests is Test { vm.expectEmit(false, false, false, false); emit RelayLib.DenomCreated("", address(0)); + vm.expectEmit(false, false, false, false); + emit IERC20.Transfer(address(0), address(0), 0); + vm.expectEmit(false, false, false, false); emit RelayLib.Received("", address(0), "", address(0), 0); - vm.prank(address(relay)); - relay.onRecvPacketProcessing( + vm.prank(address(ibcHandler)); + relay.onRecvPacket( IbcCoreChannelV1Packet.Data({ sequence: sequence, source_port: sourcePort, @@ -342,89 +224,1128 @@ contract RelayTests is Test { ); } - function testRelay_send_remote( - uint64 sequence, - string memory sourcePort, - string memory sourceChannel, - string memory destinationPort, - string memory destinationChannel, - uint64 timeoutRevisionNumber, - uint64 timeoutRevisionHeight, - uint64 timeoutTimestamp, - bytes memory sender, - address receiver, - address relayer, - string memory denomName, - uint128 amount - ) public { - vm.assume(receiver != address(0)); - vm.assume(relayer != address(0)); - vm.assume(amount > 0); + function testRelay_isRemote_ok() public { + assertEq(RelayLib.isRemote("a", "b", "a/b/X"), true); + assertEq(RelayLib.isRemote("aa.bb", "c", "aa.bb/c/X"), true); + } - UCS01Relay relay = new UCS01Relay(ibcHandler); + function testRelay_isRemote_ko() public { + assertEq(RelayLib.isRemote("a", "b", "b/b/X"), false); + assertEq(RelayLib.isRemote("aa.bb", "c", "aa.b/c/X"), false); + } - { - Token[] memory tokens = new Token[](1); - tokens[0].denom = denomName; - tokens[0].amount = amount; + function testRelay_makeForeignDenom() public { + assertEq(RelayLib.makeForeignDenom("a", "b", "BLA"), "a/b/BLA"); + assertEq( + RelayLib.makeForeignDenom("wasm.xyz", "channel-1", "muno"), + "wasm.xyz/channel-1/muno" + ); + } + + function testRelay_makeDenomPrefix() public { + assertEq(RelayLib.makeDenomPrefix("a", "b"), "a/b/"); + assertEq( + RelayLib.makeDenomPrefix("wasm.xyz", "channel-99"), + "wasm.xyz/channel-99/" + ); + } + + function testRelay_hexToAddress(address addr) public { + assertEq(RelayLib.hexToAddress(addr.toHexString()), addr); + } + + function testRelay_openInit_onlyIBC( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + relay.onChanOpenInit( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + RelayLib.VERSION + ); + } + + function testRelay_openInit_wrongVersion( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + vm.prank(address(ibcHandler)); + relay.onChanOpenInit( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + "blabla" + ); + } + + function testRelay_openInit_setCounterparty( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.prank(address(ibcHandler)); + relay.onChanOpenInit( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + RelayLib.VERSION + ); + IbcCoreChannelV1Counterparty.Data memory counterparty = relay + .getCounterpartyEndpoint(destinationPort, destinationChannel); + assertEq(counterparty.port_id, sourcePort); + assertEq(counterparty.channel_id, sourceChannel); + } + + function testRelay_openTry_onlyIBC( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + relay.onChanOpenTry( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + RelayLib.VERSION, + RelayLib.VERSION + ); + } + + function testRelay_openTry_setCounterparty( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.prank(address(ibcHandler)); + relay.onChanOpenTry( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + RelayLib.VERSION, + RelayLib.VERSION + ); + IbcCoreChannelV1Counterparty.Data memory counterparty = relay + .getCounterpartyEndpoint(destinationPort, destinationChannel); + assertEq(counterparty.port_id, sourcePort); + assertEq(counterparty.channel_id, sourceChannel); + } + + function testRelay_openTry_wrongVersion( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + vm.prank(address(ibcHandler)); + relay.onChanOpenTry( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + "0xDEADC0DE", + RelayLib.VERSION + ); + } + + function testRelay_openTry_wrongCounterpartyVersion( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + vm.prank(address(ibcHandler)); + relay.onChanOpenTry( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + RelayLib.VERSION, + "ok" + ); + } + + function testRelay_openAck_onlyIBC( + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + relay.onChanOpenAck( + destinationPort, + destinationChannel, + sourceChannel, + RelayLib.VERSION + ); + } + + function testRelay_openAck_wrongVersion( + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + vm.prank(address(ibcHandler)); + relay.onChanOpenAck( + destinationPort, + destinationChannel, + sourceChannel, + "ucs01version" + ); + } + + function testRelay_openAck_setCounterpartyChannel( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.prank(address(ibcHandler)); + relay.onChanOpenInit( + IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: "" + }), + RelayLib.VERSION + ); + IbcCoreChannelV1Counterparty.Data memory counterparty = relay + .getCounterpartyEndpoint(destinationPort, destinationChannel); + assertEq(counterparty.port_id, sourcePort); + assertEq(counterparty.channel_id, ""); + vm.prank(address(ibcHandler)); + relay.onChanOpenAck( + destinationPort, + destinationChannel, + sourceChannel, + RelayLib.VERSION + ); + counterparty = relay.getCounterpartyEndpoint( + destinationPort, + destinationChannel + ); + assertEq(counterparty.port_id, sourcePort); + assertEq(counterparty.channel_id, sourceChannel); + } + + function testRelay_openConfirm_onlyIBC( + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + relay.onChanOpenConfirm(destinationPort, destinationChannel); + } + + function testRelay_openConfirm( + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.prank(address(ibcHandler)); + relay.onChanOpenConfirm(destinationPort, destinationChannel); + } + + function testRelay_closeInit_onlyIBC( + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + relay.onChanCloseInit(destinationPort, destinationChannel); + } + + function testRelay_closeInit_impossible( + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + vm.prank(address(ibcHandler)); + relay.onChanCloseInit(destinationPort, destinationChannel); + } + + function testRelay_closeConfirm_onlyIBC( + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + relay.onChanCloseConfirm(destinationPort, destinationChannel); + } + + function testRelay_closeConfirm_impossible( + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + vm.prank(address(ibcHandler)); + relay.onChanCloseConfirm(destinationPort, destinationChannel); + } + + function testRelay_onRecvPacketProcessing_onlySelf( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + address relayer + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + vm.prank(address(ibcHandler)); + relay.onRecvPacketProcessing( + IbcCoreChannelV1Packet.Data({ + sequence: sequence, + source_port: sourcePort, + source_channel: sourceChannel, + destination_port: destinationPort, + destination_channel: destinationChannel, + data: hex"00", + timeout_height: IbcCoreClientV1Height.Data({ + revision_number: timeoutRevisionNumber, + revision_height: timeoutRevisionHeight + }), + timeout_timestamp: timeoutTimestamp + }), + relayer + ); + } + + function testRelay_onRecvPacket_invalidIdentity( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + address relayer + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.record(); + vm.prank(address(ibcHandler)); + bytes memory acknowledgement = relay.onRecvPacket( + IbcCoreChannelV1Packet.Data({ + sequence: sequence, + source_port: sourcePort, + source_channel: sourceChannel, + destination_port: destinationPort, + destination_channel: destinationChannel, + data: hex"00", + timeout_height: IbcCoreClientV1Height.Data({ + revision_number: timeoutRevisionNumber, + revision_height: timeoutRevisionHeight + }), + timeout_timestamp: timeoutTimestamp + }), + relayer + ); + (bytes32[] memory reads, bytes32[] memory writes) = vm.accesses( + address(relay) + ); + assertEq(writes.length, 0); + assertEq(acknowledgement, abi.encodePacked(RelayLib.ACK_FAILURE)); + } + + function testRelay_receive_localToken( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + address sender, + bytes memory receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(sender != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); + + address denomAddress = address(new ERC20Denom(denomName)); + IERC20Denom(denomAddress).mint(address(sender), amount); + + LocalToken[] memory localTokens = new LocalToken[](1); + localTokens[0].denom = denomAddress; + localTokens[0].amount = amount; + + vm.prank(sender); + IERC20Denom(denomAddress).approve(address(relay), amount); + + // A single transfer without mint as the token was previously escrowed + vm.expectEmit(); + emit IERC20.Transfer(address(sender), address(relay), amount); + + vm.expectEmit(false, false, false, false); + emit RelayLib.Sent(address(0), "", "", address(0), 0); + + vm.prank(sender); + relay.send( + destinationPort, + destinationChannel, + receiver, + localTokens, + 0, + 0 + ); + + Token[] memory tokens = new Token[](1); + tokens[0].denom = RelayLib.makeForeignDenom( + destinationPort, + destinationChannel, + denomAddress.toHexString() + ); + tokens[0].amount = amount; + + // A single transfer without mint as the token was previously escrowed + vm.expectEmit(false, false, false, false); + emit IERC20.Transfer(address(0), address(sender), amount); + + vm.expectEmit(false, false, false, false); + emit RelayLib.Received("", address(0), "", address(0), 0); + + uint256 outstandingBefore = relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ); + + vm.prank(address(ibcHandler)); + relay.onRecvPacket( + IbcCoreChannelV1Packet.Data({ + sequence: sequence, + source_port: sourcePort, + source_channel: sourceChannel, + destination_port: destinationPort, + destination_channel: destinationChannel, + data: RelayPacketLib.encode( + RelayPacket({ + sender: receiver, + receiver: abi.encodePacked(sender), + tokens: tokens + }) + ), + timeout_height: IbcCoreClientV1Height.Data({ + revision_number: timeoutRevisionNumber, + revision_height: timeoutRevisionHeight + }), + timeout_timestamp: timeoutTimestamp + }), + relayer + ); + + // Local tokens are tracked, outstanding for the channel must be diminished by the amount + assertEq( + relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ) + amount, + outstandingBefore + ); + } + + function testRelay_receive_remoteToken( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + bytes memory sender, + address receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(receiver != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); + + receiveRemoteToken( + relay, + sequence, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + timeoutRevisionNumber, + timeoutRevisionHeight, + timeoutTimestamp, + sender, + receiver, + relayer, + denomName, + amount + ); + } + + function testRelay_send_local( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + address sender, + bytes memory receiver, + string memory denomName, + uint128 amount + ) public { + vm.assume(sender != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); + + address denomAddress = address(new ERC20Denom(denomName)); + IERC20Denom(denomAddress).mint(sender, amount); + + LocalToken[] memory localTokens = new LocalToken[](1); + localTokens[0].denom = denomAddress; + localTokens[0].amount = amount; + + vm.prank(sender); + IERC20Denom(denomAddress).approve(address(relay), amount); + + assertEq( + relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ), + 0 + ); + + vm.expectEmit(); + emit IERC20.Transfer(address(sender), address(relay), amount); + + vm.expectEmit(false, false, false, false); + emit RelayLib.Sent(address(0), "", "", address(0), 0); + + vm.prank(sender); + relay.send( + destinationPort, + destinationChannel, + receiver, + localTokens, + 0, + 0 + ); + + // Local tokens must be tracked as outstanding for the channel + assertEq( + relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ), + amount + ); + } + + function testRelay_send_remote( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + bytes memory sender, + address receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(receiver != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); + + receiveRemoteToken( + relay, + sequence, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + timeoutRevisionNumber, + timeoutRevisionHeight, + timeoutTimestamp, + sender, + receiver, + relayer, + denomName, + amount + ); + + { + address denomAddress = relay.getDenomAddress( + RelayLib.makeForeignDenom(sourcePort, sourceChannel, denomName) + ); + + LocalToken[] memory localTokens = new LocalToken[](1); + localTokens[0].denom = denomAddress; + localTokens[0].amount = amount; + + vm.prank(receiver); + IERC20Denom(denomAddress).approve(address(relay), amount); + + // Transfer from user to relay + vm.expectEmit(false, false, false, false); + emit IERC20.Transfer(address(receiver), address(relay), amount); + + // Burn from relay to zero + vm.expectEmit(); + emit IERC20.Transfer(address(relay), address(0), amount); vm.expectEmit(false, false, false, false); - emit RelayLib.DenomCreated("", address(0)); + emit RelayLib.Sent(address(0), "", "", address(0), 0); + + uint256 outstandingBefore = relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ); + + vm.prank(receiver); + relay.send( + destinationPort, + destinationChannel, + abi.encodePacked(receiver), + localTokens, + 0, + 0 + ); + + uint256 outstandingAfter = relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ); + + // Remote tokens are not tracked as outstanding + assertEq(outstandingBefore, outstandingAfter); + } + } + + function testRelay_timeout_refund_local( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + address sender, + bytes memory receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(sender != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); - vm.expectEmit(false, false, false, false); - emit IERC20.Transfer(address(0), address(0), 0); + address denomAddress = sendLocalToken( + relay, + destinationPort, + destinationChannel, + sender, + receiver, + denomName, + amount + ); - vm.expectEmit(false, false, false, false); - emit RelayLib.Received("", address(0), "", address(0), 0); - - vm.prank(address(relay)); - relay.onRecvPacketProcessing( - IbcCoreChannelV1Packet.Data({ - sequence: sequence, - source_port: sourcePort, - source_channel: sourceChannel, - destination_port: destinationPort, - destination_channel: destinationChannel, - data: RelayPacketLib.encode( - RelayPacket({ - sender: sender, - receiver: abi.encodePacked(receiver), - tokens: tokens - }) - ), - timeout_height: IbcCoreClientV1Height.Data({ - revision_number: timeoutRevisionNumber, - revision_height: timeoutRevisionHeight - }), - timeout_timestamp: timeoutTimestamp - }), - relayer - ); - } + IbcCoreChannelV1Packet.Data memory packet = ibcHandler.lastPacket(); - { - address denomAddress = relay.getDenomAddress( - RelayLib.makeForeignDenom(sourcePort, sourceChannel, denomName) - ); + vm.expectEmit(); + emit IERC20.Transfer(address(relay), address(sender), amount); - LocalToken[] memory localTokens = new LocalToken[](1); - localTokens[0].denom = denomAddress; - localTokens[0].amount = amount; + vm.expectEmit(false, false, false, false); + emit RelayLib.Timeout(address(0), "", "", address(this), 0); - vm.startPrank(receiver); - IERC20Denom(denomAddress).approve(address(relay), amount); + assertEq( + relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ), + amount + ); - vm.expectEmit(false, false, false, false); - emit RelayLib.Sent(address(0), "", "", address(0), 0); + vm.prank(address(ibcHandler)); + relay.onTimeoutPacket(packet, relayer); - relay.send( + /* Tokens must be unescrowed and no longer outstanding */ + assertEq( + relay.getOutstanding( destinationPort, destinationChannel, - sender, - localTokens, - 0, - 0 - ); - } + denomAddress + ), + 0 + ); + } + + function testRelay_timeout_refund_remote( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + bytes memory sender, + address receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(receiver != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); + + receiveRemoteToken( + relay, + sequence, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + timeoutRevisionNumber, + timeoutRevisionHeight, + timeoutTimestamp, + sender, + receiver, + relayer, + denomName, + amount + ); + + address denomAddress = relay.getDenomAddress( + RelayLib.makeForeignDenom(sourcePort, sourceChannel, denomName) + ); + + sendRemoteToken( + relay, + destinationPort, + destinationChannel, + sender, + receiver, + denomAddress, + amount + ); + + IbcCoreChannelV1Packet.Data memory packet = ibcHandler.lastPacket(); + + vm.expectEmit(); + emit IERC20.Transfer(address(0), address(receiver), amount); + + vm.expectEmit(false, false, false, false); + emit RelayLib.Timeout(address(0), "", "", address(this), 0); + + uint256 outstandingBefore = relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ); + + vm.prank(address(ibcHandler)); + relay.onTimeoutPacket(packet, relayer); + + // Outstanding must not be touched + assertEq( + relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ), + outstandingBefore + ); + } + + function testRelay_ack_failure_refund_local( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + address sender, + bytes memory receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(sender != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); + + address denomAddress = sendLocalToken( + relay, + destinationPort, + destinationChannel, + sender, + receiver, + denomName, + amount + ); + + IbcCoreChannelV1Packet.Data memory packet = ibcHandler.lastPacket(); + + vm.expectEmit(); + emit IERC20.Transfer(address(relay), address(sender), amount); + + vm.expectEmit(false, false, false, false); + emit RelayLib.Timeout(address(0), "", "", address(this), 0); + + assertEq( + relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ), + amount + ); + + vm.prank(address(ibcHandler)); + relay.onAcknowledgementPacket( + packet, + abi.encodePacked(RelayLib.ACK_FAILURE), + relayer + ); + + /* Tokens must be unescrowed and no longer outstanding */ + assertEq( + relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ), + 0 + ); + } + + function testRelay_ack_failure_refund_remote( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + bytes memory sender, + address receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(receiver != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); + + receiveRemoteToken( + relay, + sequence, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + timeoutRevisionNumber, + timeoutRevisionHeight, + timeoutTimestamp, + sender, + receiver, + relayer, + denomName, + amount + ); + + address denomAddress = relay.getDenomAddress( + RelayLib.makeForeignDenom(sourcePort, sourceChannel, denomName) + ); + + sendRemoteToken( + relay, + destinationPort, + destinationChannel, + sender, + receiver, + denomAddress, + amount + ); + + IbcCoreChannelV1Packet.Data memory packet = ibcHandler.lastPacket(); + + vm.expectEmit(); + emit IERC20.Transfer(address(0), address(receiver), amount); + + vm.expectEmit(false, false, false, false); + emit RelayLib.Timeout(address(0), "", "", address(this), 0); + + uint256 outstandingBefore = relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ); + + vm.prank(address(ibcHandler)); + relay.onAcknowledgementPacket( + packet, + abi.encodePacked(RelayLib.ACK_FAILURE), + relayer + ); + + // Outstanding must not be touched + assertEq( + relay.getOutstanding( + destinationPort, + destinationChannel, + denomAddress + ), + outstandingBefore + ); + } + + function testRelay_ack_success_noop_local( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + address sender, + bytes memory receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(sender != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); + + address denomAddress = sendLocalToken( + relay, + destinationPort, + destinationChannel, + sender, + receiver, + denomName, + amount + ); + + IbcCoreChannelV1Packet.Data memory packet = ibcHandler.lastPacket(); + + vm.record(); + + vm.prank(address(ibcHandler)); + relay.onAcknowledgementPacket( + packet, + abi.encodePacked(RelayLib.ACK_SUCCESS), + relayer + ); + + (bytes32[] memory reads, bytes32[] memory writes) = vm.accesses( + address(relay) + ); + assertEq(writes.length, 0); + } + + function testRelay_ack_success_noop_remote( + uint64 sequence, + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel, + uint64 timeoutRevisionNumber, + uint64 timeoutRevisionHeight, + uint64 timeoutTimestamp, + bytes memory sender, + address receiver, + address relayer, + string memory denomName, + uint128 amount + ) public { + vm.assume(receiver != address(0)); + vm.assume(relayer != address(0)); + vm.assume(amount > 0); + + UCS01Relay relay = createRelay( + destinationPort, + destinationChannel, + sourcePort, + sourceChannel + ); + + receiveRemoteToken( + relay, + sequence, + sourcePort, + sourceChannel, + destinationPort, + destinationChannel, + timeoutRevisionNumber, + timeoutRevisionHeight, + timeoutTimestamp, + sender, + receiver, + relayer, + denomName, + amount + ); + + address denomAddress = relay.getDenomAddress( + RelayLib.makeForeignDenom(sourcePort, sourceChannel, denomName) + ); + + sendRemoteToken( + relay, + destinationPort, + destinationChannel, + sender, + receiver, + denomAddress, + amount + ); + + IbcCoreChannelV1Packet.Data memory packet = ibcHandler.lastPacket(); + + vm.record(); + + vm.prank(address(ibcHandler)); + relay.onAcknowledgementPacket( + packet, + abi.encodePacked(RelayLib.ACK_SUCCESS), + relayer + ); + + (bytes32[] memory reads, bytes32[] memory writes) = vm.accesses( + address(relay) + ); + assertEq(writes.length, 0); } } From 2098d31ced1e80aa7f288b5478dec8309189a479 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Tue, 9 Jan 2024 16:27:13 +0100 Subject: [PATCH 09/14] chore: spellcheck --- dictionary.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dictionary.txt b/dictionary.txt index f664ac4e2e..d8f84a866a 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -280,9 +280,11 @@ feegrant feegrantkeeper feegrantmodule fetchurl +fetchzip fkey fksmg floorlog +fmtlib foldl frunk fubar @@ -385,6 +387,7 @@ jemalloc jemallocator jetbrains journalctl +jsoncpp jsonschema jwtsecret karel From 0d2b31f0a5382916126aec1ad9d4cfe78afa0391 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Wed, 10 Jan 2024 14:31:10 +0100 Subject: [PATCH 10/14] feat(evm): rename parameters for clarity --- evm/contracts/apps/ucs/01-relay/Relay.sol | 40 +++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/evm/contracts/apps/ucs/01-relay/Relay.sol b/evm/contracts/apps/ucs/01-relay/Relay.sol index 18ad3101c3..c38195de0d 100644 --- a/evm/contracts/apps/ucs/01-relay/Relay.sol +++ b/evm/contracts/apps/ucs/01-relay/Relay.sol @@ -190,37 +190,37 @@ contract UCS01Relay is IBCAppBase { } function getCounterpartyEndpoint( - string memory portId, - string memory channelId + string memory sourcePort, + string memory sourceChannel ) public view returns (IbcCoreChannelV1Counterparty.Data memory) { - return counterpartyEndpoints[portId][channelId]; + return counterpartyEndpoints[sourcePort][sourceChannel]; } function increaseOutstanding( - string memory portId, - string memory channelId, + string memory sourcePort, + string memory sourceChannel, address token, uint256 amount ) internal { - outstanding[portId][channelId][token] = outstanding[portId][channelId][ + outstanding[sourcePort][sourceChannel][token] = outstanding[portId][channelId][ token ].add(amount); } function decreaseOutstanding( - string memory portId, - string memory channelId, + string memory sourcePort, + string memory sourceChannel, address token, uint256 amount ) internal { - outstanding[portId][channelId][token] = outstanding[portId][channelId][ + outstanding[sourcePort][sourceChannel][token] = outstanding[portId][channelId][ token ].sub(amount); } function sendToken( - string calldata portId, - string calldata channelId, + string calldata sourcePort, + string calldata sourceChannel, string memory counterpartyPortId, string memory counterpartyChannelId, LocalToken calldata localToken @@ -245,8 +245,8 @@ contract UCS01Relay is IBCAppBase { ); } else { increaseOutstanding( - portId, - channelId, + sourcePort, + sourceChannel, localToken.denom, localToken.amount ); @@ -255,15 +255,15 @@ contract UCS01Relay is IBCAppBase { } function send( - string calldata portId, - string calldata channelId, + string calldata sourcePort, + string calldata sourceChannel, bytes calldata receiver, LocalToken[] calldata tokens, uint64 counterpartyTimeoutRevisionNumber, uint64 counterpartyTimeoutRevisionHeight ) public { IbcCoreChannelV1Counterparty.Data - memory counterparty = counterpartyEndpoints[portId][channelId]; + memory counterparty = counterpartyEndpoints[sourcePort][sourceChannel]; Token[] memory normalizedTokens = new Token[](tokens.length); // For each token, we transfer them locally then: // - if the token is locally native, keep it escrowed @@ -271,8 +271,8 @@ contract UCS01Relay is IBCAppBase { for (uint256 i = 0; i < tokens.length; i++) { LocalToken calldata localToken = tokens[i]; string memory addressDenom = sendToken( - portId, - channelId, + sourcePort, + sourceChannel, counterparty.port_id, counterparty.channel_id, localToken @@ -299,8 +299,8 @@ contract UCS01Relay is IBCAppBase { revision_height: counterpartyTimeoutRevisionHeight }); ibcHandler.sendPacket( - portId, - channelId, + sourcePort, + sourceChannel, timeoutHeight, 0, packet.encode() From f719687be703a9f43040efed73e6ba7c9cfd2472 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Wed, 10 Jan 2024 14:31:35 +0100 Subject: [PATCH 11/14] feat(cosmwasm): ucs01: return unauthorized instead of panicking --- cosmwasm/ucs01-relay/src/ibc.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cosmwasm/ucs01-relay/src/ibc.rs b/cosmwasm/ucs01-relay/src/ibc.rs index 42903f081b..bbda03d600 100644 --- a/cosmwasm/ucs01-relay/src/ibc.rs +++ b/cosmwasm/ucs01-relay/src/ibc.rs @@ -108,8 +108,7 @@ pub fn ibc_channel_close( _env: Env, _channel: IbcChannelCloseMsg, ) -> Result { - // Not allowed. - unimplemented!(); + Err(ContractError::Unauthorized) } #[cfg_attr(not(feature = "library"), entry_point)] From 9844982ced4e25fdb40570135b1577510c8a21b7 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Wed, 10 Jan 2024 14:32:29 +0100 Subject: [PATCH 12/14] feat(cosmwasm): ucs01: ensure local/remote protocol versions match --- cosmwasm/ucs01-relay/src/error.rs | 7 +++++++ cosmwasm/ucs01-relay/src/ibc.rs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/cosmwasm/ucs01-relay/src/error.rs b/cosmwasm/ucs01-relay/src/error.rs index bd8e965a74..6b1c2a9298 100644 --- a/cosmwasm/ucs01-relay/src/error.rs +++ b/cosmwasm/ucs01-relay/src/error.rs @@ -53,6 +53,13 @@ pub enum ContractError { protocol_version: String, }, + #[error("Channel {channel_id} protocol version {protocol_version} mismatch counterparty protocol version {counterparty_protocol_version}")] + ProtocolMismatch { + channel_id: String, + protocol_version: String, + counterparty_protocol_version: String, + }, + #[error("Only myself is able to trigger this message")] Unauthorized, } diff --git a/cosmwasm/ucs01-relay/src/ibc.rs b/cosmwasm/ucs01-relay/src/ibc.rs index bbda03d600..42dd9b9bd0 100644 --- a/cosmwasm/ucs01-relay/src/ibc.rs +++ b/cosmwasm/ucs01-relay/src/ibc.rs @@ -92,6 +92,13 @@ pub(crate) fn enforce_order_and_version( protocol_version: version.to_string(), }); } + if version != channel.version { + return Err(ContractError::ProtocolMismatch { + channel_id: channel.endpoint.channel_id.clone(), + protocol_version: channel.version.to_string(), + counterparty_protocol_version: version.to_string() + }); + } } if channel.order != channel_ordering { return Err(ContractError::InvalidChannelOrdering { From 2b79494e10f3869c54c43d764d3127b074f589f3 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Wed, 10 Jan 2024 14:32:59 +0100 Subject: [PATCH 13/14] feat(cosmwasm): ucs01: add more protocol check tests --- cosmwasm/ucs01-relay/src/ibc.rs | 171 +++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 1 deletion(-) diff --git a/cosmwasm/ucs01-relay/src/ibc.rs b/cosmwasm/ucs01-relay/src/ibc.rs index 42dd9b9bd0..c2196492f3 100644 --- a/cosmwasm/ucs01-relay/src/ibc.rs +++ b/cosmwasm/ucs01-relay/src/ibc.rs @@ -96,7 +96,7 @@ pub(crate) fn enforce_order_and_version( return Err(ContractError::ProtocolMismatch { channel_id: channel.endpoint.channel_id.clone(), protocol_version: channel.version.to_string(), - counterparty_protocol_version: version.to_string() + counterparty_protocol_version: version.to_string(), }); } } @@ -238,3 +238,172 @@ pub fn ibc_packet_timeout( }), } } + +#[cfg(test)] +mod tests { + use cosmwasm_std::{IbcChannel, IbcEndpoint}; + use ucs01_relay_api::protocol::TransferProtocol; + + use super::enforce_order_and_version; + use crate::{ + error::ContractError, + protocol::{Ics20Protocol, Ucs01Protocol}, + }; + + #[test] + fn enforce_channel_version_ucs01() { + let port_id = "port-1"; + let channel_id = "channel-1"; + let connection_id = "connection-1"; + let protocol_version = Ucs01Protocol::VERSION; + let counterparty_port_id = "port-2"; + let counterparty_channel_id = "channel-2"; + assert_eq!( + enforce_order_and_version( + &IbcChannel::new( + IbcEndpoint { + port_id: port_id.into(), + channel_id: channel_id.into() + }, + IbcEndpoint { + port_id: counterparty_port_id.into(), + channel_id: counterparty_channel_id.into() + }, + cosmwasm_std::IbcOrder::Unordered, + protocol_version, + connection_id + ), + None + ), + Ok(()) + ); + } + + #[test] + fn enforce_channel_version_ics20() { + let port_id = "port-1"; + let channel_id = "channel-1"; + let connection_id = "connection-1"; + let protocol_version = Ics20Protocol::VERSION; + let counterparty_port_id = "port-2"; + let counterparty_channel_id = "channel-2"; + assert_eq!( + enforce_order_and_version( + &IbcChannel::new( + IbcEndpoint { + port_id: port_id.into(), + channel_id: channel_id.into() + }, + IbcEndpoint { + port_id: counterparty_port_id.into(), + channel_id: counterparty_channel_id.into() + }, + cosmwasm_std::IbcOrder::Unordered, + protocol_version, + connection_id + ), + None + ), + Ok(()) + ); + } + + #[test] + fn enforce_channel_wrong_version() { + let port_id = "port-1"; + let channel_id = "channel-1"; + let connection_id = "connection-1"; + let protocol_version = "ucs01-0999"; + let counterparty_port_id = "port-2"; + let counterparty_channel_id = "channel-2"; + assert_eq!( + enforce_order_and_version( + &IbcChannel::new( + IbcEndpoint { + port_id: port_id.into(), + channel_id: channel_id.into() + }, + IbcEndpoint { + port_id: counterparty_port_id.into(), + channel_id: counterparty_channel_id.into() + }, + cosmwasm_std::IbcOrder::Unordered, + protocol_version, + connection_id + ), + None + ), + Err(ContractError::UnknownProtocol { + channel_id: channel_id.into(), + protocol_version: protocol_version.into() + }) + ); + } + + #[test] + fn enforce_channel_counterparty_wrong_version() { + let port_id = "port-1"; + let channel_id = "channel-1"; + let connection_id = "connection-1"; + let protocol_version = Ucs01Protocol::VERSION; + let counterparty_port_id = "port-2"; + let counterparty_channel_id = "channel-2"; + let counterparty_protocol_version = "ucs01-0999"; + assert_eq!( + enforce_order_and_version( + &IbcChannel::new( + IbcEndpoint { + port_id: port_id.into(), + channel_id: channel_id.into() + }, + IbcEndpoint { + port_id: counterparty_port_id.into(), + channel_id: counterparty_channel_id.into() + }, + cosmwasm_std::IbcOrder::Unordered, + protocol_version, + connection_id + ), + Some(counterparty_protocol_version) + ), + Err(ContractError::UnknownProtocol { + channel_id: channel_id.into(), + protocol_version: counterparty_protocol_version.into() + }) + ); + } + + #[test] + fn enforce_channel_protocol_mismatch() { + let port_id = "port-1"; + let channel_id = "channel-1"; + let connection_id = "connection-1"; + let protocol_version = Ucs01Protocol::VERSION; + let counterparty_port_id = "port-2"; + let counterparty_channel_id = "channel-2"; + let counterparty_protocol_version = Ics20Protocol::VERSION; + assert_eq!( + enforce_order_and_version( + &IbcChannel::new( + IbcEndpoint { + port_id: port_id.into(), + channel_id: channel_id.into() + }, + IbcEndpoint { + port_id: counterparty_port_id.into(), + channel_id: counterparty_channel_id.into() + }, + cosmwasm_std::IbcOrder::Unordered, + protocol_version, + connection_id + ), + Some(counterparty_protocol_version) + ), + Err(ContractError::ProtocolMismatch { + channel_id: channel_id.into(), + protocol_version: protocol_version.into(), + counterparty_protocol_version: counterparty_protocol_version.into() + }) + ); + } +} From 699bc0beb866db4381e09402eccb8c85284aeabc Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Wed, 10 Jan 2024 14:42:41 +0100 Subject: [PATCH 14/14] feat(evm): ucs01-relay: ensure channel ordering on init/try --- evm/contracts/apps/ucs/01-relay/Relay.sol | 30 +++++++--- evm/tests/src/apps/ucs/01-relay/Relay.t.sol | 63 ++++++++++++++++++--- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/evm/contracts/apps/ucs/01-relay/Relay.sol b/evm/contracts/apps/ucs/01-relay/Relay.sol index c38195de0d..06ba5060b4 100644 --- a/evm/contracts/apps/ucs/01-relay/Relay.sol +++ b/evm/contracts/apps/ucs/01-relay/Relay.sol @@ -31,6 +31,8 @@ struct RelayPacket { library RelayLib { using LibString for *; + IbcCoreChannelV1GlobalEnums.Order public constant ORDER = + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED; string public constant VERSION = "ucs01-0"; bytes1 public constant ACK_SUCCESS = 0x01; bytes1 public constant ACK_FAILURE = 0x00; @@ -202,9 +204,9 @@ contract UCS01Relay is IBCAppBase { address token, uint256 amount ) internal { - outstanding[sourcePort][sourceChannel][token] = outstanding[portId][channelId][ - token - ].add(amount); + outstanding[sourcePort][sourceChannel][token] = outstanding[sourcePort][ + sourceChannel + ][token].add(amount); } function decreaseOutstanding( @@ -213,9 +215,9 @@ contract UCS01Relay is IBCAppBase { address token, uint256 amount ) internal { - outstanding[sourcePort][sourceChannel][token] = outstanding[portId][channelId][ - token - ].sub(amount); + outstanding[sourcePort][sourceChannel][token] = outstanding[sourcePort][ + sourceChannel + ][token].sub(amount); } function sendToken( @@ -263,7 +265,9 @@ contract UCS01Relay is IBCAppBase { uint64 counterpartyTimeoutRevisionHeight ) public { IbcCoreChannelV1Counterparty.Data - memory counterparty = counterpartyEndpoints[sourcePort][sourceChannel]; + memory counterparty = counterpartyEndpoints[sourcePort][ + sourceChannel + ]; Token[] memory normalizedTokens = new Token[](tokens.length); // For each token, we transfer them locally then: // - if the token is locally native, keep it escrowed @@ -452,7 +456,7 @@ contract UCS01Relay is IBCAppBase { } function onChanOpenInit( - IbcCoreChannelV1GlobalEnums.Order _order, + IbcCoreChannelV1GlobalEnums.Order order, string[] calldata _connectionHops, string calldata portId, string calldata channelId, @@ -463,11 +467,15 @@ contract UCS01Relay is IBCAppBase { RelayLib.isValidVersion(version), "ucs01-relay: invalid version" ); + require( + order == RelayLib.ORDER, + "ucs01-relay: invalid channel ordering" + ); counterpartyEndpoints[portId][channelId] = counterpartyEndpoint; } function onChanOpenTry( - IbcCoreChannelV1GlobalEnums.Order _order, + IbcCoreChannelV1GlobalEnums.Order order, string[] calldata _connectionHops, string calldata portId, string calldata channelId, @@ -483,6 +491,10 @@ contract UCS01Relay is IBCAppBase { RelayLib.isValidVersion(counterpartyVersion), "ucs01-relay: invalid counterparty version" ); + require( + order == RelayLib.ORDER, + "ucs01-relay: invalid channel ordering" + ); counterpartyEndpoints[portId][channelId] = counterpartyEndpoint; } diff --git a/evm/tests/src/apps/ucs/01-relay/Relay.t.sol b/evm/tests/src/apps/ucs/01-relay/Relay.t.sol index 4ca5bb33b5..4bcb6b0103 100644 --- a/evm/tests/src/apps/ucs/01-relay/Relay.t.sol +++ b/evm/tests/src/apps/ucs/01-relay/Relay.t.sol @@ -76,7 +76,7 @@ contract RelayTests is Test { ) public { vm.prank(address(ibcHandler)); relay.onChanOpenTry( - IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED, new string[](0), destinationPort, destinationChannel, @@ -263,7 +263,7 @@ contract RelayTests is Test { UCS01Relay relay = new UCS01Relay(ibcHandler); vm.expectRevert(); relay.onChanOpenInit( - IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED, new string[](0), destinationPort, destinationChannel, @@ -285,7 +285,7 @@ contract RelayTests is Test { vm.expectRevert(); vm.prank(address(ibcHandler)); relay.onChanOpenInit( - IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED, new string[](0), destinationPort, destinationChannel, @@ -297,13 +297,14 @@ contract RelayTests is Test { ); } - function testRelay_openInit_setCounterparty( + function testRelay_openInit_wrongOrdering( string memory sourcePort, string memory sourceChannel, string memory destinationPort, string memory destinationChannel ) public { UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); vm.prank(address(ibcHandler)); relay.onChanOpenInit( IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, @@ -316,6 +317,27 @@ contract RelayTests is Test { }), RelayLib.VERSION ); + } + + function testRelay_openInit_setCounterparty( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.prank(address(ibcHandler)); + relay.onChanOpenInit( + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + RelayLib.VERSION + ); IbcCoreChannelV1Counterparty.Data memory counterparty = relay .getCounterpartyEndpoint(destinationPort, destinationChannel); assertEq(counterparty.port_id, sourcePort); @@ -331,7 +353,7 @@ contract RelayTests is Test { UCS01Relay relay = new UCS01Relay(ibcHandler); vm.expectRevert(); relay.onChanOpenTry( - IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED, new string[](0), destinationPort, destinationChannel, @@ -353,7 +375,7 @@ contract RelayTests is Test { UCS01Relay relay = new UCS01Relay(ibcHandler); vm.prank(address(ibcHandler)); relay.onChanOpenTry( - IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED, new string[](0), destinationPort, destinationChannel, @@ -380,7 +402,7 @@ contract RelayTests is Test { vm.expectRevert(); vm.prank(address(ibcHandler)); relay.onChanOpenTry( - IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED, new string[](0), destinationPort, destinationChannel, @@ -393,7 +415,7 @@ contract RelayTests is Test { ); } - function testRelay_openTry_wrongCounterpartyVersion( + function testRelay_openTry_wrongOrdering( string memory sourcePort, string memory sourceChannel, string memory destinationPort, @@ -412,6 +434,29 @@ contract RelayTests is Test { channel_id: sourceChannel }), RelayLib.VERSION, + RelayLib.VERSION + ); + } + + function testRelay_openTry_wrongCounterpartyVersion( + string memory sourcePort, + string memory sourceChannel, + string memory destinationPort, + string memory destinationChannel + ) public { + UCS01Relay relay = new UCS01Relay(ibcHandler); + vm.expectRevert(); + vm.prank(address(ibcHandler)); + relay.onChanOpenTry( + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED, + new string[](0), + destinationPort, + destinationChannel, + IbcCoreChannelV1Counterparty.Data({ + port_id: sourcePort, + channel_id: sourceChannel + }), + RelayLib.VERSION, "ok" ); } @@ -456,7 +501,7 @@ contract RelayTests is Test { UCS01Relay relay = new UCS01Relay(ibcHandler); vm.prank(address(ibcHandler)); relay.onChanOpenInit( - IbcCoreChannelV1GlobalEnums.Order.ORDER_ORDERED, + IbcCoreChannelV1GlobalEnums.Order.ORDER_UNORDERED, new string[](0), destinationPort, destinationChannel,