diff --git a/contracts/evmx/Forwarder.sol b/contracts/evmx/Forwarder.sol index f6d214c2..6cc7b4ef 100644 --- a/contracts/evmx/Forwarder.sol +++ b/contracts/evmx/Forwarder.sol @@ -20,7 +20,7 @@ abstract contract ForwarderStorage is IForwarder { /// @notice chain slug on which the contract is deployed uint32 public chainSlug; /// @notice on-chain address associated with this forwarder - address public onChainAddress; + bytes32 public onChainAddress; // slot 51 /// @notice caches the latest async promise address for the last call @@ -51,7 +51,7 @@ contract Forwarder is ForwarderStorage, Initializable, AddressResolverUtil { /// @param addressResolver_ address resolver contract function initialize( uint32 chainSlug_, - address onChainAddress_, + bytes32 onChainAddress_, address addressResolver_ ) public initializer { chainSlug = chainSlug_; @@ -79,7 +79,7 @@ contract Forwarder is ForwarderStorage, Initializable, AddressResolverUtil { /// @notice Returns the on-chain address associated with this forwarder. /// @return The on-chain address. - function getOnChainAddress() external view returns (address) { + function getOnChainAddress() external view returns (bytes32) { return onChainAddress; } @@ -119,7 +119,7 @@ contract Forwarder is ForwarderStorage, Initializable, AddressResolverUtil { ) = IAppGateway(msg.sender).getOverrideParams(); // get the switchboard address from the watcher precompile config - address switchboard = watcherPrecompileConfig().switchboards(chainSlug, sbType); + bytes32 switchboard = watcherPrecompileConfig().switchboards(chainSlug, sbType); // Queue the call in the middleware. deliveryHelper__().queue( diff --git a/contracts/evmx/base/AppGatewayBase.sol b/contracts/evmx/base/AppGatewayBase.sol index 1c8af3a6..9fdd9051 100644 --- a/contracts/evmx/base/AppGatewayBase.sol +++ b/contracts/evmx/base/AppGatewayBase.sol @@ -9,6 +9,7 @@ import "../interfaces/IPromise.sol"; import {InvalidPromise, FeesNotSet, AsyncModifierNotUsed} from "../../utils/common/Errors.sol"; import {FAST} from "../../utils/common/Constants.sol"; +import { toBytes32Format } from "../../utils/common/Converters.sol"; /// @title AppGatewayBase /// @notice Abstract contract for the app gateway @@ -122,7 +123,7 @@ abstract contract AppGatewayBase is AddressResolverUtil, IAppGateway { /// @param isValid Boolean flag indicating whether the contract is authorized (true) or not (false) /// @dev This function retrieves the onchain address using the contractId and chainSlug, then calls the watcher precompile to update the plug's validity status function _setValidPlug(uint32 chainSlug_, bytes32 contractId, bool isValid) internal { - address onchainAddress = getOnChainAddress(contractId, chainSlug_); + bytes32 onchainAddress = getOnChainAddress(contractId, chainSlug_); watcherPrecompileConfig().setIsValidPlug(chainSlug_, onchainAddress, isValid); } @@ -154,6 +155,8 @@ abstract contract AppGatewayBase is AddressResolverUtil, IAppGateway { isValidPromise[asyncPromise] = true; onCompleteData = abi.encode(chainSlug_, true); + bytes32 switchboardAddress = watcherPrecompileConfig().switchboards(chainSlug_, sbType); + QueuePayloadParams memory queuePayloadParams = QueuePayloadParams({ chainSlug: chainSlug_, callType: CallType.DEPLOY, @@ -161,8 +164,8 @@ abstract contract AppGatewayBase is AddressResolverUtil, IAppGateway { isPlug: isPlug_, writeFinality: overrideParams.writeFinality, asyncPromise: asyncPromise, - switchboard: watcherPrecompileConfig().switchboards(chainSlug_, sbType), - target: address(0), + switchboard: switchboardAddress, + target: toBytes32Format(address(0)), appGateway: address(this), gasLimit: overrideParams.gasLimit, value: overrideParams.value, @@ -190,7 +193,7 @@ abstract contract AppGatewayBase is AddressResolverUtil, IAppGateway { /// @notice Gets the socket address /// @param chainSlug_ The chain slug /// @return socketAddress_ The socket address - function getSocketAddress(uint32 chainSlug_) public view returns (address) { + function getSocketAddress(uint32 chainSlug_) public view returns (bytes32) { return watcherPrecompileConfig().sockets(chainSlug_); } @@ -201,9 +204,9 @@ abstract contract AppGatewayBase is AddressResolverUtil, IAppGateway { function getOnChainAddress( bytes32 contractId_, uint32 chainSlug_ - ) public view returns (address onChainAddress) { + ) public view returns (bytes32 onChainAddress) { if (forwarderAddresses[contractId_][chainSlug_] == address(0)) { - return address(0); + return bytes32(0x0); } onChainAddress = IForwarder(forwarderAddresses[contractId_][chainSlug_]) diff --git a/contracts/evmx/interfaces/IAppGateway.sol b/contracts/evmx/interfaces/IAppGateway.sol index 7036cd43..bb76633c 100644 --- a/contracts/evmx/interfaces/IAppGateway.sol +++ b/contracts/evmx/interfaces/IAppGateway.sol @@ -44,7 +44,7 @@ interface IAppGateway { function getOnChainAddress( bytes32 contractId_, uint32 chainSlug_ - ) external view returns (address onChainAddress); + ) external view returns (bytes32 onChainAddress); /// @notice get the forwarder address of a contract /// @param contractId_ The contract id diff --git a/contracts/evmx/interfaces/IForwarder.sol b/contracts/evmx/interfaces/IForwarder.sol index b609fc31..58fee6ce 100644 --- a/contracts/evmx/interfaces/IForwarder.sol +++ b/contracts/evmx/interfaces/IForwarder.sol @@ -6,7 +6,7 @@ pragma solidity ^0.8.21; interface IForwarder { /// @notice Returns the on-chain address of the contract being referenced /// @return The on-chain address - function getOnChainAddress() external view returns (address); + function getOnChainAddress() external view returns (bytes32); /// @notice Returns the chain slug of the on chain contract /// @return The chain slug diff --git a/contracts/evmx/interfaces/IWatcherPrecompileConfig.sol b/contracts/evmx/interfaces/IWatcherPrecompileConfig.sol index fcfc4026..71db3e45 100644 --- a/contracts/evmx/interfaces/IWatcherPrecompileConfig.sol +++ b/contracts/evmx/interfaces/IWatcherPrecompileConfig.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.21; -import {AppGatewayConfig, PlugConfig} from "../../utils/common/Structs.sol"; +import {AppGatewayConfig, PlugConfigGeneric} from "../../utils/common/Structs.sol"; /// @title IWatcherPrecompileConfig /// @notice Interface for the Watcher Precompile system that handles payload verification and execution @@ -11,16 +11,16 @@ interface IWatcherPrecompileConfig { function evmxSlug() external view returns (uint32); /// @notice Maps chain slug to their associated switchboard - function switchboards(uint32 chainSlug, bytes32 sbType) external view returns (address); + function switchboards(uint32 chainSlug, bytes32 sbType) external view returns (bytes32); /// @notice Maps chain slug to their associated socket - function sockets(uint32 chainSlug) external view returns (address); + function sockets(uint32 chainSlug) external view returns (bytes32); /// @notice Maps chain slug to their associated contract factory plug - function contractFactoryPlug(uint32 chainSlug) external view returns (address); + function contractFactoryPlug(uint32 chainSlug) external view returns (bytes32); /// @notice Maps chain slug to their associated fees plug - function feesPlug(uint32 chainSlug) external view returns (address); + function feesPlug(uint32 chainSlug) external view returns (bytes32); /// @notice Maps nonce to whether it has been used function isNonceUsed(uint256 nonce) external view returns (bool); @@ -29,28 +29,28 @@ interface IWatcherPrecompileConfig { function isValidPlug( address appGateway, uint32 chainSlug, - address plug + bytes32 plug ) external view returns (bool); /// @notice Sets the switchboard for a network - function setSwitchboard(uint32 chainSlug_, bytes32 sbType_, address switchboard_) external; + function setSwitchboard(uint32 chainSlug_, bytes32 sbType_, bytes32 switchboard_) external; /// @notice Sets valid plugs for each chain slug /// @dev This function is used to verify if a plug deployed on a chain slug is valid connection to the app gateway - function setIsValidPlug(uint32 chainSlug_, address plug_, bool isValid_) external; + function setIsValidPlug(uint32 chainSlug_, bytes32 plug_, bool isValid_) external; /// @notice Retrieves the configuration for a specific plug on a network function getPlugConfigs( uint32 chainSlug_, - address plug_ - ) external view returns (bytes32, address); + bytes32 plug_ + ) external view returns (bytes32, bytes32); /// @notice Verifies connections between components function verifyConnections( uint32 chainSlug_, - address target_, + bytes32 target_, address appGateway_, - address switchboard_, + bytes32 switchboard_, address middleware_ ) external view; diff --git a/contracts/evmx/payload-delivery/FeesManager.sol b/contracts/evmx/payload-delivery/FeesManager.sol index 7f5e5e61..2f10809d 100644 --- a/contracts/evmx/payload-delivery/FeesManager.sol +++ b/contracts/evmx/payload-delivery/FeesManager.sol @@ -445,7 +445,7 @@ contract FeesManager is FeesManagerStorage, Initializable, Ownable, AddressResol return transmitterCredits > watcherFees ? transmitterCredits - watcherFees : 0; } - function _getSwitchboard(uint32 chainSlug_) internal view returns (address) { + function _getSwitchboard(uint32 chainSlug_) internal view returns (bytes32) { return watcherPrecompile__().watcherPrecompileConfig__().switchboards(chainSlug_, sbType); } @@ -483,7 +483,7 @@ contract FeesManager is FeesManagerStorage, Initializable, Ownable, AddressResol deliveryHelper__().queue(queuePayloadParams); } - function _getFeesPlugAddress(uint32 chainSlug_) internal view returns (address) { + function _getFeesPlugAddress(uint32 chainSlug_) internal view returns (bytes32) { return watcherPrecompileConfig().feesPlug(chainSlug_); } diff --git a/contracts/evmx/payload-delivery/app-gateway/DeliveryUtils.sol b/contracts/evmx/payload-delivery/app-gateway/DeliveryUtils.sol index 14dc88bb..ac1fa6f4 100644 --- a/contracts/evmx/payload-delivery/app-gateway/DeliveryUtils.sol +++ b/contracts/evmx/payload-delivery/app-gateway/DeliveryUtils.sol @@ -63,7 +63,7 @@ abstract contract DeliveryUtils is /// @notice Gets the payload delivery plug address /// @param chainSlug_ The chain identifier /// @return address The address of the payload delivery plug - function getDeliveryHelperPlugAddress(uint32 chainSlug_) public view returns (address) { + function getDeliveryHelperPlugAddress(uint32 chainSlug_) public view returns (bytes32) { return watcherPrecompileConfig().contractFactoryPlug(chainSlug_); } diff --git a/contracts/evmx/payload-delivery/app-gateway/RequestQueue.sol b/contracts/evmx/payload-delivery/app-gateway/RequestQueue.sol index 73a7b809..3c398908 100644 --- a/contracts/evmx/payload-delivery/app-gateway/RequestQueue.sol +++ b/contracts/evmx/payload-delivery/app-gateway/RequestQueue.sol @@ -176,7 +176,7 @@ abstract contract RequestQueue is DeliveryUtils { function _createDeployPayloadDetails( QueuePayloadParams memory queuePayloadParams_ - ) internal returns (bytes memory payload, address target) { + ) internal returns (bytes memory payload, bytes32 target) { bytes32 salt = keccak256( abi.encode(queuePayloadParams_.appGateway, queuePayloadParams_.chainSlug, saltCounter++) ); @@ -204,7 +204,7 @@ abstract contract RequestQueue is DeliveryUtils { QueuePayloadParams memory queuePayloadParams_ ) internal returns (PayloadSubmitParams memory) { bytes memory payload = queuePayloadParams_.payload; - address target = queuePayloadParams_.target; + bytes32 target = queuePayloadParams_.target; if (queuePayloadParams_.callType == CallType.DEPLOY) { (payload, target) = _createDeployPayloadDetails(queuePayloadParams_); } diff --git a/contracts/evmx/watcherPrecompile/WatcherPrecompileConfig.sol b/contracts/evmx/watcherPrecompile/WatcherPrecompileConfig.sol index b0a3984f..fab9ae15 100644 --- a/contracts/evmx/watcherPrecompile/WatcherPrecompileConfig.sol +++ b/contracts/evmx/watcherPrecompile/WatcherPrecompileConfig.sol @@ -7,7 +7,7 @@ import {Ownable} from "solady/auth/Ownable.sol"; import "../interfaces/IWatcherPrecompileConfig.sol"; import {AddressResolverUtil} from "../AddressResolverUtil.sol"; import {InvalidWatcherSignature, NonceUsed} from "../../utils/common/Errors.sol"; -import "./core/WatcherIdUtils.sol"; +import {toBytes32Format} from "../../utils/common/Converters.sol"; /// @title WatcherPrecompileConfig /// @notice Configuration contract for the Watcher Precompile system @@ -29,28 +29,28 @@ contract WatcherPrecompileConfig is // slot 102: _plugConfigs /// @notice Maps network and plug to their configuration - /// @dev chainSlug => plug => PlugConfig - mapping(uint32 => mapping(address => PlugConfig)) internal _plugConfigs; + /// @dev chainSlug => plug => PlugConfigGeneric + mapping(uint32 => mapping(bytes32 => PlugConfigGeneric)) internal _plugConfigs; // slot 103: switchboards /// @notice Maps chain slug to their associated switchboard /// @dev chainSlug => sb type => switchboard address - mapping(uint32 => mapping(bytes32 => address)) public switchboards; + mapping(uint32 => mapping(bytes32 => bytes32)) public switchboards; // slot 104: sockets /// @notice Maps chain slug to their associated socket /// @dev chainSlug => socket address - mapping(uint32 => address) public sockets; + mapping(uint32 => bytes32) public sockets; // slot 105: contractFactoryPlug /// @notice Maps chain slug to their associated contract factory plug /// @dev chainSlug => contract factory plug address - mapping(uint32 => address) public contractFactoryPlug; + mapping(uint32 => bytes32) public contractFactoryPlug; // slot 106: feesPlug /// @notice Maps chain slug to their associated fees plug /// @dev chainSlug => fees plug address - mapping(uint32 => address) public feesPlug; + mapping(uint32 => bytes32) public feesPlug; // slot 107: isNonceUsed /// @notice Maps nonce to whether it has been used @@ -59,19 +59,19 @@ contract WatcherPrecompileConfig is // slot 108: isValidPlug // appGateway => chainSlug => plug => isValid - mapping(address => mapping(uint32 => mapping(address => bool))) public isValidPlug; + mapping(address => mapping(uint32 => mapping(bytes32 => bool))) public isValidPlug; /// @notice Emitted when a new plug is configured for an app gateway /// @param appGatewayId The id of the app gateway /// @param chainSlug The identifier of the destination network /// @param plug The address of the plug - event PlugAdded(bytes32 appGatewayId, uint32 chainSlug, address plug); + event PlugAdded(bytes32 appGatewayId, uint32 chainSlug, bytes32 plug); /// @notice Emitted when a switchboard is set for a network /// @param chainSlug The identifier of the network /// @param sbType The type of switchboard /// @param switchboard The address of the switchboard - event SwitchboardSet(uint32 chainSlug, bytes32 sbType, address switchboard); + event SwitchboardSet(uint32 chainSlug, bytes32 sbType, bytes32 switchboard); /// @notice Emitted when contracts are set for a network /// @param chainSlug The identifier of the network @@ -80,9 +80,9 @@ contract WatcherPrecompileConfig is /// @param feesPlug The address of the fees plug event OnChainContractSet( uint32 chainSlug, - address socket, - address contractFactoryPlug, - address feesPlug + bytes32 socket, + bytes32 contractFactoryPlug, + bytes32 feesPlug ); /// @notice Emitted when a valid plug is set for an app gateway @@ -90,7 +90,7 @@ contract WatcherPrecompileConfig is /// @param chainSlug The identifier of the network /// @param plug The address of the plug /// @param isValid Whether the plug is valid - event IsValidPlugSet(address appGateway, uint32 chainSlug, address plug, bool isValid); + event IsValidPlugSet(address appGateway, uint32 chainSlug, bytes32 plug, bool isValid); error InvalidGateway(); error InvalidSwitchboard(); @@ -124,7 +124,7 @@ contract WatcherPrecompileConfig is for (uint256 i = 0; i < configs_.length; i++) { // Store the plug configuration for this network and plug - _plugConfigs[configs_[i].chainSlug][configs_[i].plug] = PlugConfig({ + _plugConfigs[configs_[i].chainSlug][configs_[i].plug] = PlugConfigGeneric({ appGatewayId: configs_[i].appGatewayId, switchboard: configs_[i].switchboard }); @@ -137,9 +137,9 @@ contract WatcherPrecompileConfig is /// @param chainSlug_ The identifier of the network function setOnChainContracts( uint32 chainSlug_, - address socket_, - address contractFactoryPlug_, - address feesPlug_ + bytes32 socket_, + bytes32 contractFactoryPlug_, + bytes32 feesPlug_ ) external onlyOwner { sockets[chainSlug_] = socket_; contractFactoryPlug[chainSlug_] = contractFactoryPlug_; @@ -155,7 +155,7 @@ contract WatcherPrecompileConfig is function setSwitchboard( uint32 chainSlug_, bytes32 sbType_, - address switchboard_ + bytes32 switchboard_ ) external onlyOwner { switchboards[chainSlug_][sbType_] = switchboard_; emit SwitchboardSet(chainSlug_, sbType_, switchboard_); @@ -167,7 +167,7 @@ contract WatcherPrecompileConfig is /// @param chainSlug_ The identifier of the network /// @param plug_ The address of the plug /// @param isValid_ Whether the plug is valid - function setIsValidPlug(uint32 chainSlug_, address plug_, bool isValid_) external { + function setIsValidPlug(uint32 chainSlug_, bytes32 plug_, bool isValid_) external { isValidPlug[msg.sender][chainSlug_][plug_] = isValid_; emit IsValidPlugSet(msg.sender, chainSlug_, plug_, isValid_); } @@ -180,8 +180,8 @@ contract WatcherPrecompileConfig is /// @dev Returns zero addresses if configuration doesn't exist function getPlugConfigs( uint32 chainSlug_, - address plug_ - ) public view returns (bytes32, address) { + bytes32 plug_ + ) public view returns (bytes32, bytes32) { return ( _plugConfigs[chainSlug_][plug_].appGatewayId, _plugConfigs[chainSlug_][plug_].switchboard @@ -196,9 +196,9 @@ contract WatcherPrecompileConfig is /// @param switchboard_ The address of the switchboard function verifyConnections( uint32 chainSlug_, - address target_, + bytes32 target_, address appGateway_, - address switchboard_, + bytes32 switchboard_, address middleware_ ) external view { // if target is contractFactoryPlug, return @@ -207,8 +207,8 @@ contract WatcherPrecompileConfig is middleware_ == address(deliveryHelper__()) && target_ == contractFactoryPlug[chainSlug_] ) return; - (bytes32 appGatewayId, address switchboard) = getPlugConfigs(chainSlug_, target_); - if (appGatewayId != WatcherIdUtils.encodeAppGatewayId(appGateway_)) revert InvalidGateway(); + (bytes32 appGatewayId, bytes32 switchboard) = getPlugConfigs(chainSlug_, target_); + if (appGatewayId != toBytes32Format(appGateway_)) revert InvalidGateway(); if (switchboard != switchboard_) revert InvalidSwitchboard(); } diff --git a/contracts/evmx/watcherPrecompile/core/RequestHandler.sol b/contracts/evmx/watcherPrecompile/core/RequestHandler.sol index d6f620eb..368324e2 100644 --- a/contracts/evmx/watcherPrecompile/core/RequestHandler.sol +++ b/contracts/evmx/watcherPrecompile/core/RequestHandler.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.21; import "./WatcherPrecompileCore.sol"; +import {WatcherIdUtils} from "./WatcherIdUtils.sol"; /// @title RequestHandler /// @notice Contract that handles request submission and processing @@ -21,7 +22,7 @@ abstract contract RequestHandler is WatcherPrecompileCore { function submitRequest( PayloadSubmitParams[] memory payloadSubmitParams_ ) public returns (uint40 requestCount) { - address appGateway = _checkAppGateways(payloadSubmitParams_); + _checkAppGateways(payloadSubmitParams_); requestCount = nextRequestCount++; uint40 batchCount = nextBatchCount; diff --git a/contracts/evmx/watcherPrecompile/core/WatcherIdUtils.sol b/contracts/evmx/watcherPrecompile/core/WatcherIdUtils.sol index 1d2ed762..9972fbea 100644 --- a/contracts/evmx/watcherPrecompile/core/WatcherIdUtils.sol +++ b/contracts/evmx/watcherPrecompile/core/WatcherIdUtils.sol @@ -2,14 +2,6 @@ pragma solidity ^0.8.22; library WatcherIdUtils { - function encodeAppGatewayId(address appGateway_) internal pure returns (bytes32) { - return bytes32(uint256(uint160(appGateway_))); - } - - function decodeAppGatewayId(bytes32 appGatewayId_) internal pure returns (address) { - return address(uint160(uint256(appGatewayId_))); - } - /// @notice Creates a payload ID from the given parameters /// @param requestCount_ The request count /// @param batchCount_ The batch count @@ -21,7 +13,7 @@ library WatcherIdUtils { uint40 requestCount_, uint40 batchCount_, uint40 payloadCount_, - address switchboard_, + bytes32 switchboard_, uint32 chainSlug_ ) internal pure returns (bytes32) { return diff --git a/contracts/evmx/watcherPrecompile/core/WatcherPrecompile.sol b/contracts/evmx/watcherPrecompile/core/WatcherPrecompile.sol index 878ef213..ec38dc40 100644 --- a/contracts/evmx/watcherPrecompile/core/WatcherPrecompile.sol +++ b/contracts/evmx/watcherPrecompile/core/WatcherPrecompile.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.21; import "./RequestHandler.sol"; import {LibCall} from "solady/utils/LibCall.sol"; +import {fromBytes32Format} from "../../../utils/common/Converters.sol"; /// @title WatcherPrecompile /// @notice Contract that handles request submission, iteration and execution @@ -254,7 +255,7 @@ contract WatcherPrecompile is RequestHandler { for (uint256 i = 0; i < params_.length; i++) { if (appGatewayCalled[params_[i].triggerId]) revert AppGatewayAlreadyCalled(); - address appGateway = WatcherIdUtils.decodeAppGatewayId(params_[i].appGatewayId); + address appGateway = fromBytes32Format(params_[i].appGatewayId); if ( !watcherPrecompileConfig__.isValidPlug( appGateway, diff --git a/contracts/evmx/watcherPrecompile/core/WatcherPrecompileCore.sol b/contracts/evmx/watcherPrecompile/core/WatcherPrecompileCore.sol index 9da6d736..df11155c 100644 --- a/contracts/evmx/watcherPrecompile/core/WatcherPrecompileCore.sol +++ b/contracts/evmx/watcherPrecompile/core/WatcherPrecompileCore.sol @@ -7,7 +7,7 @@ import {Ownable} from "solady/auth/Ownable.sol"; import "solady/utils/Initializable.sol"; import {AddressResolverUtil} from "../../AddressResolverUtil.sol"; import {IFeesManager} from "../../interfaces/IFeesManager.sol"; -import "./WatcherIdUtils.sol"; +import {toBytes32Format} from "../../../utils/common/Converters.sol"; import "./WatcherPrecompileStorage.sol"; /// @title WatcherPrecompileCore @@ -92,7 +92,7 @@ abstract contract WatcherPrecompileCore is params_.value, params_.payload, params_.target, - WatcherIdUtils.encodeAppGatewayId(params_.appGateway), + toBytes32Format(params_.appGateway), prevDigestsHash ); @@ -163,7 +163,7 @@ abstract contract WatcherPrecompileCore is p.value, p.payload, p.target, - WatcherIdUtils.encodeAppGatewayId(p.appGateway), + toBytes32Format(p.appGateway), p.prevDigestsHash ); prevDigestsHash = keccak256(abi.encodePacked(prevDigestsHash, getDigest(digestParams))); diff --git a/contracts/evmx/watcherPrecompile/core/WatcherPrecompileStorage.sol b/contracts/evmx/watcherPrecompile/core/WatcherPrecompileStorage.sol index 2ef880e3..9d063c90 100644 --- a/contracts/evmx/watcherPrecompile/core/WatcherPrecompileStorage.sol +++ b/contracts/evmx/watcherPrecompile/core/WatcherPrecompileStorage.sol @@ -8,7 +8,7 @@ import {IPromise} from "../../interfaces/IPromise.sol"; import {IMiddleware} from "../../interfaces/IMiddleware.sol"; import {QUERY, FINALIZE, SCHEDULE, MAX_COPY_BYTES} from "../../../utils/common/Constants.sol"; import {InvalidCallerTriggered, TimeoutDelayTooLarge, TimeoutAlreadyResolved, InvalidInboxCaller, ResolvingTimeoutTooEarly, CallFailed, AppGatewayAlreadyCalled, InvalidWatcherSignature, NonceUsed, RequestAlreadyExecuted} from "../../../utils/common/Errors.sol"; -import {ResolvedPromises, AppGatewayConfig, LimitParams, WriteFinality, UpdateLimitParams, PlugConfig, DigestParams, TimeoutRequest, QueuePayloadParams, PayloadParams, RequestParams, RequestMetadata} from "../../../utils/common/Structs.sol"; +import {ResolvedPromises, AppGatewayConfig, LimitParams, WriteFinality, UpdateLimitParams, PlugConfigGeneric, DigestParams, TimeoutRequest, QueuePayloadParams, PayloadParams, RequestParams, RequestMetadata} from "../../../utils/common/Structs.sol"; /// @title WatcherPrecompileStorage /// @notice Storage contract for the WatcherPrecompile system diff --git a/contracts/protocol/Socket.sol b/contracts/protocol/Socket.sol index 2b39f518..463d436a 100644 --- a/contracts/protocol/Socket.sol +++ b/contracts/protocol/Socket.sol @@ -77,7 +77,7 @@ contract Socket is SocketUtils { // check if the call type is valid if (executeParams_.callType == CallType.READ) revert ReadOnlyCall(); - PlugConfig memory plugConfig = _plugConfigs[executeParams_.target]; + PlugConfigEvm memory plugConfig = _plugConfigs[executeParams_.target]; // check if the plug is disconnected if (plugConfig.appGatewayId == bytes32(0)) revert PlugNotFound(); @@ -182,7 +182,7 @@ contract Socket is SocketUtils { * @notice To trigger to a connected remote chain. Should only be called by a plug. */ function _triggerAppGateway(address plug_) internal returns (bytes32 triggerId) { - PlugConfig memory plugConfig = _plugConfigs[plug_]; + PlugConfigEvm memory plugConfig = _plugConfigs[plug_]; // if no sibling plug is found for the given chain slug, revert // sends the trigger to connected app gateway diff --git a/contracts/protocol/SocketConfig.sol b/contracts/protocol/SocketConfig.sol index e3fb0194..90cba878 100644 --- a/contracts/protocol/SocketConfig.sol +++ b/contracts/protocol/SocketConfig.sol @@ -7,7 +7,7 @@ import {IPlug} from "./interfaces/IPlug.sol"; import "./interfaces/ISocketFeeManager.sol"; import "../utils/AccessControl.sol"; import {GOVERNANCE_ROLE, RESCUE_ROLE, SWITCHBOARD_DISABLER_ROLE} from "../utils/common/AccessRoles.sol"; -import {CallType, PlugConfig, SwitchboardStatus, ExecutionStatus} from "../utils/common/Structs.sol"; +import {CallType, PlugConfigEvm, SwitchboardStatus, ExecutionStatus} from "../utils/common/Structs.sol"; import {PlugNotFound, InvalidAppGateway, InvalidTransmitter} from "../utils/common/Errors.sol"; import {MAX_COPY_BYTES} from "../utils/common/Constants.sol"; @@ -25,7 +25,7 @@ abstract contract SocketConfig is ISocket, AccessControl { mapping(address => SwitchboardStatus) public isValidSwitchboard; // @notice mapping of plug address to its config - mapping(address => PlugConfig) internal _plugConfigs; + mapping(address => PlugConfigEvm) internal _plugConfigs; // @notice max copy bytes for socket uint16 public maxCopyBytes = 2048; // 2KB @@ -83,7 +83,7 @@ abstract contract SocketConfig is ISocket, AccessControl { if (isValidSwitchboard[switchboard_] != SwitchboardStatus.REGISTERED) revert InvalidSwitchboard(); - PlugConfig storage _plugConfig = _plugConfigs[msg.sender]; + PlugConfigEvm storage _plugConfig = _plugConfigs[msg.sender]; _plugConfig.appGatewayId = appGatewayId_; _plugConfig.switchboard = switchboard_; @@ -107,7 +107,7 @@ abstract contract SocketConfig is ISocket, AccessControl { function getPlugConfig( address plugAddress_ ) external view returns (bytes32 appGatewayId, address switchboard) { - PlugConfig memory _plugConfig = _plugConfigs[plugAddress_]; + PlugConfigEvm memory _plugConfig = _plugConfigs[plugAddress_]; return (_plugConfig.appGatewayId, _plugConfig.switchboard); } } diff --git a/contracts/utils/common/Converters.sol b/contracts/utils/common/Converters.sol new file mode 100644 index 00000000..4f290e4b --- /dev/null +++ b/contracts/utils/common/Converters.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Apache 2 +pragma solidity ^0.8.21; + +error NotAnEvmAddress(bytes32 bytes32FormatAddress); + +function toBytes32Format(address addr) pure returns (bytes32) { + return bytes32(uint256(uint160(addr))); +} + +function fromBytes32Format(bytes32 bytes32FormatAddress) pure returns (address) { + if (uint256(bytes32FormatAddress) >> 160 != 0) { + revert NotAnEvmAddress(bytes32FormatAddress); + } + return address(uint160(uint256(bytes32FormatAddress))); +} diff --git a/contracts/utils/common/Structs.sol b/contracts/utils/common/Structs.sol index 2f93bf17..5efcc880 100644 --- a/contracts/utils/common/Structs.sol +++ b/contracts/utils/common/Structs.sol @@ -82,20 +82,27 @@ struct UpdateLimitParams { } struct AppGatewayConfig { - address plug; + bytes32 plug; bytes32 appGatewayId; - address switchboard; + bytes32 switchboard; uint32 chainSlug; } // Plug config: -struct PlugConfig { +struct PlugConfigGeneric { + bytes32 appGatewayId; + bytes32 switchboard; +} + +// Plug config: +struct PlugConfigEvm { bytes32 appGatewayId; address switchboard; } + //trigger: struct TriggerParams { bytes32 triggerId; - address plug; + bytes32 plug; bytes32 appGatewayId; uint32 chainSlug; bytes overrides; @@ -146,7 +153,7 @@ struct UserCredits { // digest: struct DigestParams { - address socket; + bytes32 socket; address transmitter; bytes32 payloadId; uint256 deadline; @@ -154,7 +161,7 @@ struct DigestParams { uint256 gasLimit; uint256 value; bytes payload; - address target; + bytes32 target; bytes32 appGatewayId; bytes32 prevDigestsHash; } @@ -166,8 +173,8 @@ struct QueuePayloadParams { IsPlug isPlug; WriteFinality writeFinality; address asyncPromise; - address switchboard; - address target; + bytes32 switchboard; + bytes32 target; address appGateway; uint256 gasLimit; uint256 value; @@ -183,8 +190,8 @@ struct PayloadSubmitParams { Parallel isParallel; WriteFinality writeFinality; address asyncPromise; - address switchboard; - address target; + bytes32 switchboard; + bytes32 target; address appGateway; uint256 gasLimit; uint256 value; @@ -204,8 +211,8 @@ struct PayloadParams { // Parallel isParallel; // WriteFinality writeFinality; address asyncPromise; - address switchboard; - address target; + bytes32 switchboard; + bytes32 target; address appGateway; bytes32 payloadId; bytes32 prevDigestsHash; @@ -272,3 +279,24 @@ struct PayloadIdParams { uint32 chainSlug; address switchboard; } + +struct SolanaInstruction { + SolanaInstructionData data; + SolanaInstructionDataDescription description; +} + +struct SolanaInstructionData { + bytes32 programId; + bytes8 instructionDiscriminator; + bytes32[] accounts; + bytes[] functionArguments; +} + +struct SolanaInstructionDataDescription { + // flags for accounts + // 0 bit - isWritable (0|1) + // 1 bit - isSigner (0|1) + bytes1[] accountFlags; + // names for function argument types used later in data decoding in watcher and transmitter + string[] functionArgumentTypeNames; +} \ No newline at end of file diff --git a/script/counter/ReadOnchainCounters.s.sol b/script/counter/ReadOnchainCounters.s.sol index 011ab4fb..4a041e95 100644 --- a/script/counter/ReadOnchainCounters.s.sol +++ b/script/counter/ReadOnchainCounters.s.sol @@ -5,21 +5,22 @@ import {Script} from "forge-std/Script.sol"; import {console} from "forge-std/console.sol"; import {Counter} from "../../test/apps/app-gateways/counter/Counter.sol"; import {CounterAppGateway} from "../../test/apps/app-gateways/counter/CounterAppGateway.sol"; +import {fromBytes32Format} from "../../contracts/utils/common/Converters.sol"; contract CheckCounters is Script { function run() external { CounterAppGateway gateway = CounterAppGateway(vm.envAddress("APP_GATEWAY")); vm.createSelectFork(vm.envString("EVMX_RPC")); - address counterInstanceArbitrumSepolia = gateway.getOnChainAddress( - gateway.counter(), - 421614 + address counterInstanceArbitrumSepolia = fromBytes32Format( + gateway.getOnChainAddress(gateway.counter(), 421614) ); - address counterInstanceOptimismSepolia = gateway.getOnChainAddress( - gateway.counter(), - 11155420 + address counterInstanceOptimismSepolia = fromBytes32Format( + gateway.getOnChainAddress(gateway.counter(), 11155420) + ); + address counterInstanceBaseSepolia = fromBytes32Format( + gateway.getOnChainAddress(gateway.counter(), 84532) ); - address counterInstanceBaseSepolia = gateway.getOnChainAddress(gateway.counter(), 84532); if (counterInstanceArbitrumSepolia != address(0)) { vm.createSelectFork(vm.envString("ARBITRUM_SEPOLIA_RPC")); diff --git a/test/DeliveryHelper.t.sol b/test/DeliveryHelper.t.sol index a14321b7..54ac2ff4 100644 --- a/test/DeliveryHelper.t.sol +++ b/test/DeliveryHelper.t.sol @@ -153,28 +153,28 @@ contract DeliveryHelperTest is SetupTest { AppGatewayConfig[] memory gateways = new AppGatewayConfig[](4); gateways[0] = AppGatewayConfig({ - plug: address(arbConfig.contractFactoryPlug), + plug: toBytes32Format(address(arbConfig.contractFactoryPlug)), chainSlug: arbChainSlug, appGatewayId: _encodeAppGatewayId(address(deliveryHelper)), - switchboard: address(arbConfig.switchboard) + switchboard: toBytes32Format(address(arbConfig.switchboard)) }); gateways[1] = AppGatewayConfig({ - plug: address(optConfig.contractFactoryPlug), + plug: toBytes32Format(address(optConfig.contractFactoryPlug)), chainSlug: optChainSlug, appGatewayId: _encodeAppGatewayId(address(deliveryHelper)), - switchboard: address(optConfig.switchboard) + switchboard: toBytes32Format(address(optConfig.switchboard)) }); gateways[2] = AppGatewayConfig({ - plug: address(arbConfig.feesPlug), + plug: toBytes32Format(address(arbConfig.feesPlug)), chainSlug: arbChainSlug, appGatewayId: _encodeAppGatewayId(address(feesManager)), - switchboard: address(arbConfig.switchboard) + switchboard: toBytes32Format(address(arbConfig.switchboard)) }); gateways[3] = AppGatewayConfig({ - plug: address(optConfig.feesPlug), + plug: toBytes32Format(address(optConfig.feesPlug)), chainSlug: optChainSlug, appGatewayId: _encodeAppGatewayId(address(feesManager)), - switchboard: address(optConfig.switchboard) + switchboard: toBytes32Format(address(optConfig.switchboard)) }); bytes memory watcherSignature = _createWatcherSignature( @@ -285,13 +285,13 @@ contract DeliveryHelperTest is SetupTest { SocketContracts memory socketConfig = getSocketConfig(chainSlug_); for (uint i = 0; i < contractIds_.length; i++) { - address plug = appGateway_.getOnChainAddress(contractIds_[i], chainSlug_); + bytes32 plug = appGateway_.getOnChainAddress(contractIds_[i], chainSlug_); gateways[i] = AppGatewayConfig({ plug: plug, chainSlug: chainSlug_, appGatewayId: _encodeAppGatewayId(address(appGateway_)), - switchboard: address(socketConfig.switchboard) + switchboard: toBytes32Format(address(socketConfig.switchboard)) }); } @@ -359,10 +359,10 @@ contract DeliveryHelperTest is SetupTest { uint32 chainSlug_, bytes32 contractId_, IAppGateway appGateway_ - ) internal view returns (address, address) { - address app = appGateway_.getOnChainAddress(contractId_, chainSlug_); + ) internal view returns (bytes32, address) { + bytes32 plug = appGateway_.getOnChainAddress(contractId_, chainSlug_); address forwarder = appGateway_.forwarderAddresses(contractId_, chainSlug_); - return (app, forwarder); + return (plug, forwarder); } function getContractFactoryPlug(uint32 chainSlug_) internal view returns (address) { diff --git a/test/Inbox.t.sol b/test/Inbox.t.sol index c9306913..966570c1 100644 --- a/test/Inbox.t.sol +++ b/test/Inbox.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.21; import {CounterAppGateway} from "./apps/app-gateways/counter/CounterAppGateway.sol"; import {Counter} from "./apps/app-gateways/counter/Counter.sol"; import "./DeliveryHelper.t.sol"; +import {toBytes32Format} from "../contracts/utils/common/Converters.sol"; contract TriggerTest is DeliveryHelperTest { uint256 constant feesAmount = 0.01 ether; @@ -40,10 +41,10 @@ contract TriggerTest is DeliveryHelperTest { // Setup gateway config for the watcher AppGatewayConfig[] memory gateways = new AppGatewayConfig[](1); gateways[0] = AppGatewayConfig({ - plug: address(counter), + plug: toBytes32Format(address(counter)), chainSlug: arbChainSlug, appGatewayId: _encodeAppGatewayId(address(gateway)), - switchboard: address(arbConfig.switchboard) + switchboard: toBytes32Format(address(arbConfig.switchboard)) }); bytes memory watcherSignature = _createWatcherSignature( @@ -54,7 +55,7 @@ contract TriggerTest is DeliveryHelperTest { watcherPrecompileConfig.setAppGateways(gateways, signatureNonce++, watcherSignature); hoax(watcherEOA); - watcherPrecompileConfig.setIsValidPlug(arbChainSlug, address(counter), true); + watcherPrecompileConfig.setIsValidPlug(arbChainSlug, toBytes32Format(address(counter)), true); } function testIncrementAfterTrigger() public { @@ -92,7 +93,7 @@ contract TriggerTest is DeliveryHelperTest { triggerId: triggerId, chainSlug: arbChainSlug, appGatewayId: _encodeAppGatewayId(address(gateway)), - plug: address(counter), + plug: toBytes32Format(address(counter)), payload: payload, overrides: bytes("") }); diff --git a/test/SetupTest.t.sol b/test/SetupTest.t.sol index 8153cd27..c1e7586c 100644 --- a/test/SetupTest.t.sol +++ b/test/SetupTest.t.sol @@ -20,6 +20,7 @@ import {FeesPlug} from "../contracts/evmx/payload-delivery/FeesPlug.sol"; import {SocketFeeManager} from "../contracts/protocol/SocketFeeManager.sol"; import {ETH_ADDRESS} from "../contracts/utils/common/Constants.sol"; import {ResolvedPromises, OnChainFees} from "../contracts/utils/common/Structs.sol"; +import {toBytes32Format, fromBytes32Format} from "../contracts/utils/common/Converters.sol"; import "solady/utils/ERC1967Factory.sol"; import "./apps/app-gateways/USDC.sol"; @@ -104,13 +105,13 @@ contract SetupTest is Test { hoax(watcherEOA); watcherPrecompileConfig.setOnChainContracts( chainSlug_, - address(socket), - address(contractFactoryPlug), - address(feesPlug) + toBytes32Format(address(socket)), + toBytes32Format(address(contractFactoryPlug)), + toBytes32Format(address(feesPlug)) ); SocketFeeManager socketFeeManager = new SocketFeeManager(owner, socketFees); hoax(watcherEOA); - watcherPrecompileConfig.setSwitchboard(chainSlug_, FAST, address(switchboard)); + watcherPrecompileConfig.setSwitchboard(chainSlug_, FAST, toBytes32Format(address(switchboard))); return SocketContracts({ @@ -256,7 +257,7 @@ contract SetupTest is Test { isLastPayload ); } else { - (, bytes memory returnData) = _uploadProofAndExecute(payloadParams); + (, bytes memory returnData) = _uploadProofAndExecute(payloadParams); //TODO:GW: test for solana apigateway and forwarder should reach this point _resolveAndExpectFinalizeRequested( payloadParams.payloadId, payloadParams, @@ -285,7 +286,8 @@ contract SetupTest is Test { return socketBatcher.attestAndExecute( params, - payloadParams.switchboard, + // SocketBatcher is only used in EVM so we convert to address + fromBytes32Format(payloadParams.switchboard), digest, watcherProof, transmitterSig, @@ -309,7 +311,7 @@ contract SetupTest is Test { ) internal view returns (bytes memory, bytes32) { SocketContracts memory socketConfig = getSocketConfig(params_.payloadHeader.getChainSlug()); DigestParams memory digestParams_ = DigestParams( - address(socketConfig.socket), + toBytes32Format(address(socketConfig.socket)), transmitterEOA, params_.payloadId, params_.deadline, @@ -371,7 +373,7 @@ contract SetupTest is Test { gasLimit: payloadParams.gasLimit, value: payloadParams.value, payload: payloadParams.payload, - target: payloadParams.target, + target: fromBytes32Format(payloadParams.target), requestCount: payloadParams.payloadHeader.getRequestCount(), batchCount: payloadParams.payloadHeader.getBatchCount(), payloadCount: payloadParams.payloadHeader.getPayloadCount(), diff --git a/test/apps/Counter.t.sol b/test/apps/Counter.t.sol index f2c58c2c..9bf8f60b 100644 --- a/test/apps/Counter.t.sol +++ b/test/apps/Counter.t.sol @@ -38,7 +38,7 @@ contract CounterTest is DeliveryHelperTest { deploySetup(); deployCounterApp(arbChainSlug); - (address onChain, address forwarder) = getOnChainAndForwarderAddresses( + (bytes32 onChain, address forwarder) = getOnChainAndForwarderAddresses( arbChainSlug, counterId, counterGateway @@ -67,20 +67,21 @@ contract CounterTest is DeliveryHelperTest { deploySetup(); deployCounterApp(arbChainSlug); - (address arbCounter, address arbCounterForwarder) = getOnChainAndForwarderAddresses( + (bytes32 arbCounter, address arbCounterForwarder) = getOnChainAndForwarderAddresses( arbChainSlug, counterId, counterGateway ); + address arbCounterAddress = fromBytes32Format(arbCounter); - uint256 arbCounterBefore = Counter(arbCounter).counter(); + uint256 arbCounterBefore = Counter(arbCounterAddress).counter(); address[] memory instances = new address[](1); instances[0] = arbCounterForwarder; counterGateway.incrementCounters(instances); executeRequest(new bytes[](0)); - assertEq(Counter(arbCounter).counter(), arbCounterBefore + 1); + assertEq(Counter(arbCounterAddress).counter(), arbCounterBefore + 1); } function testCounterIncrementMultipleChains() public { @@ -88,19 +89,21 @@ contract CounterTest is DeliveryHelperTest { deployCounterApp(arbChainSlug); deployCounterApp(optChainSlug); - (address arbCounter, address arbCounterForwarder) = getOnChainAndForwarderAddresses( + (bytes32 arbCounter, address arbCounterForwarder) = getOnChainAndForwarderAddresses( arbChainSlug, counterId, counterGateway ); - (address optCounter, address optCounterForwarder) = getOnChainAndForwarderAddresses( + address arbCounterAddress = fromBytes32Format(arbCounter); + (bytes32 optCounter, address optCounterForwarder) = getOnChainAndForwarderAddresses( optChainSlug, counterId, counterGateway ); + address optCounterAddress = fromBytes32Format(optCounter); - uint256 arbCounterBefore = Counter(arbCounter).counter(); - uint256 optCounterBefore = Counter(optCounter).counter(); + uint256 arbCounterBefore = Counter(arbCounterAddress).counter(); + uint256 optCounterBefore = Counter(optCounterAddress).counter(); address[] memory instances = new address[](2); instances[0] = arbCounterForwarder; @@ -112,8 +115,8 @@ contract CounterTest is DeliveryHelperTest { chains[1] = optChainSlug; executeRequest(new bytes[](0)); - assertEq(Counter(arbCounter).counter(), arbCounterBefore + 1); - assertEq(Counter(optCounter).counter(), optCounterBefore + 1); + assertEq(Counter(arbCounterAddress).counter(), arbCounterBefore + 1); + assertEq(Counter(optCounterAddress).counter(), optCounterBefore + 1); } function testCounterReadMultipleChains() external { diff --git a/test/apps/ParallelCounter.t.sol b/test/apps/ParallelCounter.t.sol index 5e7e193f..dfea2bb8 100644 --- a/test/apps/ParallelCounter.t.sol +++ b/test/apps/ParallelCounter.t.sol @@ -43,23 +43,23 @@ contract ParallelCounterTest is DeliveryHelperTest { chainSlugs[1] = optChainSlug; deployCounterApps(chainSlugs); - (address onChainArb1, address forwarderArb1) = getOnChainAndForwarderAddresses( + (bytes32 onChainArb1, address forwarderArb1) = getOnChainAndForwarderAddresses( arbChainSlug, counterId1, parallelCounterGateway ); - (address onChainArb2, address forwarderArb2) = getOnChainAndForwarderAddresses( + (bytes32 onChainArb2, address forwarderArb2) = getOnChainAndForwarderAddresses( arbChainSlug, counterId2, parallelCounterGateway ); - (address onChainOpt1, address forwarderOpt1) = getOnChainAndForwarderAddresses( + (bytes32 onChainOpt1, address forwarderOpt1) = getOnChainAndForwarderAddresses( optChainSlug, counterId1, parallelCounterGateway ); - (address onChainOpt2, address forwarderOpt2) = getOnChainAndForwarderAddresses( + (bytes32 onChainOpt2, address forwarderOpt2) = getOnChainAndForwarderAddresses( optChainSlug, counterId2, parallelCounterGateway diff --git a/test/apps/SuperToken.t.sol b/test/apps/SuperToken.t.sol index 9a5a4897..e03bbe18 100644 --- a/test/apps/SuperToken.t.sol +++ b/test/apps/SuperToken.t.sol @@ -101,14 +101,15 @@ contract SuperTokenTest is DeliveryHelperTest { function testContractDeployment() public { _deploy(arbChainSlug, IAppGateway(appContracts.superTokenApp), contractIds); - (address onChain, address forwarder) = getOnChainAndForwarderAddresses( + (bytes32 onChain, address forwarder) = getOnChainAndForwarderAddresses( arbChainSlug, appContracts.superToken, IAppGateway(appContracts.superTokenApp) ); + address onChainAddress = fromBytes32Format(onChain); assertEq( - SuperToken(onChain).name(), + SuperToken(onChainAddress).name(), "SUPER TOKEN", "OnChain SuperToken name should be SUPER TOKEN" ); @@ -122,7 +123,7 @@ contract SuperTokenTest is DeliveryHelperTest { onChain, "Forwarder SuperToken onChainAddress should be correct" ); - assertEq(SuperToken(onChain).owner(), owner, "SuperToken owner should be correct"); + assertEq(SuperToken(onChainAddress).owner(), owner, "SuperToken owner should be correct"); } /** @@ -145,20 +146,22 @@ contract SuperTokenTest is DeliveryHelperTest { function testTransfer() public { beforeTransfer(); - (address onChainArb, address forwarderArb) = getOnChainAndForwarderAddresses( + (bytes32 onChainArb, address forwarderArb) = getOnChainAndForwarderAddresses( arbChainSlug, appContracts.superToken, IAppGateway(appContracts.superTokenApp) ); + address onChainArbAddress = fromBytes32Format(onChainArb); - (address onChainOpt, address forwarderOpt) = getOnChainAndForwarderAddresses( + (bytes32 onChainOpt, address forwarderOpt) = getOnChainAndForwarderAddresses( optChainSlug, appContracts.superToken, IAppGateway(appContracts.superTokenApp) ); + address onChainOptAddress = fromBytes32Format(onChainOpt); - uint256 arbBalanceBefore = SuperToken(onChainArb).balanceOf(owner); - uint256 optBalanceBefore = SuperToken(onChainOpt).balanceOf(owner); + uint256 arbBalanceBefore = SuperToken(onChainArbAddress).balanceOf(owner); + uint256 optBalanceBefore = SuperToken(onChainOptAddress).balanceOf(owner); transferOrder = SuperTokenAppGateway.TransferOrder({ srcToken: forwarderArb, @@ -173,12 +176,12 @@ contract SuperTokenTest is DeliveryHelperTest { executeRequest(new bytes[](0)); assertEq( - SuperToken(onChainArb).balanceOf(owner), + SuperToken(onChainArbAddress).balanceOf(owner), arbBalanceBefore - srcAmount, "Arb balance should be decreased by srcAmount" ); assertEq( - SuperToken(onChainOpt).balanceOf(owner), + SuperToken(onChainOptAddress).balanceOf(owner), optBalanceBefore + srcAmount, "Opt balance should be increased by srcAmount" ); diff --git a/test/apps/app-gateways/counter/CounterAppGateway.sol b/test/apps/app-gateways/counter/CounterAppGateway.sol index eecc2c79..52b28b68 100644 --- a/test/apps/app-gateways/counter/CounterAppGateway.sol +++ b/test/apps/app-gateways/counter/CounterAppGateway.sol @@ -6,6 +6,7 @@ import "../../../../contracts/evmx/interfaces/IForwarder.sol"; import "../../../../contracts/evmx/interfaces/IPromise.sol"; import "./Counter.sol"; import "./ICounter.sol"; +import {toBytes32Format} from "../../../../contracts/utils/common/Converters.sol"; contract CounterAppGateway is AppGatewayBase, Ownable { bytes32 public counter = _createContractId("counter"); @@ -99,7 +100,7 @@ contract CounterAppGateway is AppGatewayBase, Ownable { // trigger from a chain function setIsValidPlug(uint32 chainSlug_, address plug_) public { - watcherPrecompileConfig().setIsValidPlug(chainSlug_, plug_, true); + watcherPrecompileConfig().setIsValidPlug(chainSlug_, toBytes32Format(plug_), true); } function increase(uint256 value_) external onlyWatcherPrecompile { diff --git a/test/mock/MockWatcherPrecompile.sol b/test/mock/MockWatcherPrecompile.sol index ee89876b..42fce8fa 100644 --- a/test/mock/MockWatcherPrecompile.sol +++ b/test/mock/MockWatcherPrecompile.sol @@ -5,10 +5,11 @@ import "../../contracts/evmx/interfaces/IAppGateway.sol"; import "../../contracts/evmx/interfaces/IWatcherPrecompile.sol"; import "../../contracts/evmx/interfaces/IPromise.sol"; -import {TimeoutRequest, TriggerParams, PlugConfig, ResolvedPromises, AppGatewayConfig} from "../../contracts/utils/common/Structs.sol"; +import {TimeoutRequest, TriggerParams, PlugConfigGeneric, ResolvedPromises, AppGatewayConfig} from "../../contracts/utils/common/Structs.sol"; import {QUERY, FINALIZE, SCHEDULE} from "../../contracts/utils/common/Constants.sol"; import {TimeoutDelayTooLarge, TimeoutAlreadyResolved, ResolvingTimeoutTooEarly, CallFailed, AppGatewayAlreadyCalled} from "../../contracts/utils/common/Errors.sol"; import "solady/utils/ERC1967Factory.sol"; +import {fromBytes32Format} from "../../contracts/utils/common/Converters.sol"; /// @title WatcherPrecompile /// @notice Contract that handles payload verification, execution and app configurations @@ -20,7 +21,7 @@ contract MockWatcherPrecompile { /// @dev timeoutId => TimeoutRequest struct mapping(bytes32 => TimeoutRequest) public timeoutRequests; - mapping(uint32 => mapping(address => PlugConfig)) internal _plugConfigs; + mapping(uint32 => mapping(bytes32 => PlugConfigGeneric)) internal _plugConfigs; /// @notice Error thrown when an invalid chain slug is provided error InvalidChainSlug(); @@ -159,17 +160,18 @@ contract MockWatcherPrecompile { /// @dev Reverts if chainSlug is 0 function encodePayloadId( uint32 chainSlug_, - address plug_, + bytes32 plug_, uint256 counter_ ) internal view returns (bytes32) { if (chainSlug_ == 0) revert InvalidChainSlug(); - (, address switchboard) = getPlugConfigs(chainSlug_, plug_); + (, bytes32 switchboard) = getPlugConfigs(chainSlug_, plug_); // Encode payload ID by bit-shifting and combining: // chainSlug (32 bits) | switchboard address (160 bits) | counter (64 bits) + address switchboardAsAddress = fromBytes32Format(switchboard); return bytes32( - (uint256(chainSlug_) << 224) | (uint256(uint160(switchboard)) << 64) | counter_ + (uint256(chainSlug_) << 224) | (uint256(uint160(switchboardAsAddress)) << 64) | counter_ ); } @@ -185,8 +187,8 @@ contract MockWatcherPrecompile { /// @dev Returns zero addresses if configuration doesn't exist function getPlugConfigs( uint32 chainSlug_, - address plug_ - ) public view returns (bytes32, address) { + bytes32 plug_ + ) public view returns (bytes32, bytes32) { return ( _plugConfigs[chainSlug_][plug_].appGatewayId, _plugConfigs[chainSlug_][plug_].switchboard