diff --git a/.gitignore b/.gitignore index 99e108e6..ee1c88c5 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,5 @@ deployments/local_verification.json testScript.sh CLAUDE.md + +.idea/ diff --git a/Errors.md b/Errors.md index 77179268..d90a2cb6 100644 --- a/Errors.md +++ b/Errors.md @@ -32,6 +32,12 @@ | `InvalidDepositAmount()` | `0xfe9ba5cd` | | `TokenNotWhitelisted(address)` | `0xea3bff2e` | +## evmx/watcher/Configurations.sol + +| Error | Signature | +| ----------------------------------------- | ------------ | +| `InvalidSwitchboardTest(bytes32,bytes32)` | `0x702f36a1` | + ## evmx/watcher/RequestHandler.sol | Error | Signature | @@ -81,6 +87,12 @@ | ------------------- | ------------ | | `NoPermit(bytes32)` | `0x962f6333` | +## utils/common/Converters.sol + +| Error | Signature | +| -------------------------- | ------------ | +| `NotAnEvmAddress(bytes32)` | `0x33b960d0` | + ## utils/common/Errors.sol | Error | Signature | diff --git a/EventTopics.md b/EventTopics.md index c94cd569..7daf3e8c 100644 --- a/EventTopics.md +++ b/EventTopics.md @@ -21,7 +21,7 @@ | Event | Arguments | Topic | | ---------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| `AppGatewayCallRequested` | `(triggerId: bytes32, appGatewayId: bytes32, switchboard: address, plug: address, overrides: bytes, payload: bytes)` | `0x5c88d65ab8ba22a57e582bd8ddfa9801cc0ca6be6cb3182baaedc705a612419e` | +| `AppGatewayCallRequested` | `(triggerId: bytes32, appGatewayId: bytes32, switchboard: bytes32, plug: bytes32, overrides: bytes, payload: bytes)` | `0xf83cee1d13047d8a1785495ac352da7c9ac5725641f76506899def19750c7696` | | `ExecutionFailed` | `(payloadId: bytes32, exceededMaxCopy: bool, returnData: bytes)` | `0x385334bc68a32c4d164625189adc7633e6074eb1b837fb4d11d768245151e4ce` | | `ExecutionSuccess` | `(payloadId: bytes32, exceededMaxCopy: bool, returnData: bytes)` | `0x324d63a433b21a12b90e79cd2ba736b2a5238be6165e03b750fa4a7d5193d5d9` | | `OwnershipHandoverCanceled` | `(pendingOwner: address)` | `0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92` | @@ -65,7 +65,7 @@ | `CreditsUnwrapped` | `(consumeFrom: address, amount: uint256)` | `0xdcc9473b722b4c953617ab373840b365298a520bc7f20ce94fa7314f4a857774` | | `CreditsWrapped` | `(consumeFrom: address, amount: uint256)` | `0x40246503613721eb4acf4020c6c56b6a16e5d08713316db0bea5210e8819c592` | | `Deposited` | `(chainSlug: uint32, token: address, depositTo: address, creditAmount: uint256, nativeAmount: uint256)` | `0x72aedd284699bbd7a987e6942b824cfd6c627e354cb5a0760ac5768acd473f4a` | -| `FeesPlugSet` | `(chainSlug: uint32, feesPlug: address)` | `0xa8c4be32b96cca895f1f0f4684e6b377b2c4513bc35eb57a13afb6b5efb2c0ce` | +| `FeesPlugSet` | `(chainSlug: uint32, feesPlug: bytes32)` | `0x677a00737c8099aa9e6c554104ca7941deb59125335cfb3d0d9f604f178db59c` | | `FeesPoolSet` | `(feesPool: address)` | `0xd07af3fd70b48ab3c077a8d45c3a288498d905d0e3d1e65bc171f6c2e890d8ef` | | `Initialized` | `(version: uint64)` | `0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2` | | `OwnershipHandoverCanceled` | `(pendingOwner: address)` | `0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92` | @@ -180,13 +180,13 @@ | Event | Arguments | Topic | | ---------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------- | | `Initialized` | `(version: uint64)` | `0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2` | -| `IsValidPlugSet` | `(appGateway: address, chainSlug: uint32, plug: address, isValid: bool)` | `0x61cccc7387868fc741379c7acd9dd346e0ca2e5c067dc5b156fbbc55b1c2fcf5` | +| `IsValidPlugSet` | `(appGateway: address, chainSlug: uint32, plug: bytes32, isValid: bool)` | `0xd7a90efd60960a8435ef282822190655f6bd2ffa14bb350dc23d6f6956056d7e` | | `OwnershipHandoverCanceled` | `(pendingOwner: address)` | `0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92` | | `OwnershipHandoverRequested` | `(pendingOwner: address)` | `0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d` | | `OwnershipTransferred` | `(oldOwner: address, newOwner: address)` | `0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0` | -| `PlugAdded` | `(appGatewayId: bytes32, chainSlug: uint32, plug: address)` | `0x7b3e14230a721c4737d275f9a63b92c44cb657bcfddbe6fe9b4d9cd9bd8d4a95` | -| `SocketSet` | `(chainSlug: uint32, socket: address)` | `0x5b13a5470e66a2ec5e9b32af5f9e23fe304864892918c60fffd22509ca73ac97` | -| `SwitchboardSet` | `(chainSlug: uint32, sbType: bytes32, switchboard: address)` | `0x6273f161f4a795e66ef3585d9b4442ef3796b32337157fdfb420b5281e4cf2e3` | +| `PlugAdded` | `(appGatewayId: bytes32, chainSlug: uint32, plug: bytes32)` | `0x3734a2406c5c2f2556c82a0819c51e42a135dd102465cc9856594481ea2f1637` | +| `SocketSet` | `(chainSlug: uint32, socket: bytes32)` | `0x3200bf6ad2ab31b9220ed9d2f83089d7a1332f55aaa3825c57510743a315165b` | +| `SwitchboardSet` | `(chainSlug: uint32, sbType: bytes32, switchboard: bytes32)` | `0xcdfbfa261040f4dffb03c7d9493f74b575f2ae533bb43fd7b5d5b24ac9d804f4` | ## PromiseResolver @@ -214,6 +214,8 @@ | Event | Arguments | Topic | | ---------------------------- | ---------------------------------------- | -------------------------------------------------------------------- | +| `AppGatewayCallFailed` | `(triggerId: bytes32)` | `0xcaf8475fdade8465ea31672463949e6cf1797fdcdd11eeddbbaf857e1e5907b7` | +| `CalledAppGateway` | `(triggerId: bytes32)` | `0xf659ffb3875368f54fb4ab8f5412ac4518af79701a48076f7a58d4448e4bdd0b` | | `Initialized` | `(version: uint64)` | `0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2` | | `OwnershipHandoverCanceled` | `(pendingOwner: address)` | `0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92` | | `OwnershipHandoverRequested` | `(pendingOwner: address)` | `0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d` | @@ -239,7 +241,7 @@ | --------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------- | | `ExpiryTimeSet` | `(expiryTime: uint256)` | `0x07e837e13ad9a34715a6bd45f49bbf12de19f06df79cb0be12b3a7d7f2397fa9` | | `ReadFeesSet` | `(readFees: uint256)` | `0xc674cb6dde3a59f84dbf226832e606ffc54ac8a169e1568fc834c7813010f926` | -| `ReadRequested` | `(transaction: tuple, readAtBlockNumber: uint256, payloadId: bytes32)` | `0x42d9c65d4f6e45462ae6206adb3e388e046b7daa1dc8699d9380cac72ff5db0b` | +| `ReadRequested` | `(transaction: tuple, readAtBlockNumber: uint256, payloadId: bytes32)` | `0xbcad63ac625c0f3cb23b62b126567728fcf5950ca8e559150e764eced73e794a` | ## SchedulePrecompile @@ -257,7 +259,7 @@ | Event | Arguments | Topic | | ------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | | `ChainMaxMsgValueLimitsUpdated` | `(chainSlug: uint32, maxMsgValueLimit: uint256)` | `0x439087d094fe7dacbba3f0c67032041952d8bd58a891e15af10ced28fed0eb91` | -| `ContractFactoryPlugSet` | `(chainSlug: uint32, contractFactoryPlug: address)` | `0x85bfa413b9e5e225278f51af2ac872988e0a9374263b118d963c50945ea888bb` | +| `ContractFactoryPlugSet` | `(chainSlug: uint32, contractFactoryPlug: bytes32)` | `0xfad552a6feb82bef23201b8dce04b2460bff41b00f26fef3d791572cfdab49c2` | | `ExpiryTimeSet` | `(expiryTime: uint256)` | `0x07e837e13ad9a34715a6bd45f49bbf12de19f06df79cb0be12b3a7d7f2397fa9` | | `FeesSet` | `(writeFees: uint256)` | `0x3346af6da1932164d501f2ec28f8c5d686db5828a36b77f2da4332d89184fe7b` | | `Initialized` | `(version: uint64)` | `0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2` | diff --git a/FunctionSignatures.md b/FunctionSignatures.md index c5445dae..0b76cd2b 100644 --- a/FunctionSignatures.md +++ b/FunctionSignatures.md @@ -59,7 +59,7 @@ | `chainSlug` | `0xb349ba65` | | `completeOwnershipHandover` | `0xf04e283e` | | `connect` | `0xb3bde1aa` | -| `disableSwitchboard` | `0xe545b261` | +| `disableSwitchboard` | `0xc4d9a820` | | `enableSwitchboard` | `0xf97a498a` | | `execute` | `0xafa8b480` | | `getPlugConfig` | `0xf9778ee0` | @@ -151,7 +151,7 @@ | `requestOwnershipHandover` | `0x25692962` | | `rescueFunds` | `0x6ccae054` | | `sbType` | `0x745de344` | -| `setFeesPlug` | `0xeab75f36` | +| `setFeesPlug` | `0xd6a9a8b7` | | `setFeesPool` | `0xd6684588` | | `tokenOnChainBalances` | `0x3b27866d` | | `transferCredits` | `0xf1686c89` | @@ -224,8 +224,8 @@ | `forwarderBeacon` | `0x945709ae` | | `forwarderImplementation` | `0xe38d60a1` | | `getAsyncPromiseAddress` | `0x104f39b4` | -| `getForwarderAddress` | `0x48c0b3e0` | -| `getOrDeployForwarderContract` | `0x0aa178de` | +| `getForwarderAddress` | `0x9c038b01` | +| `getOrDeployForwarderContract` | `0xe9bf1edf` | | `initialize` | `0x485cc955` | | `owner` | `0x8da5cb5b` | | `ownershipHandoverExpiresAt` | `0xfee81cf4` | @@ -292,7 +292,7 @@ | `feesManager__` | `0x70568b58` | | `getChainSlug` | `0x0b8c6568` | | `getOnChainAddress` | `0x9da48789` | -| `initialize` | `0x647c576c` | +| `initialize` | `0x148841cb` | | `onChainAddress` | `0x8bd0b363` | | `rescueFunds` | `0x6ccae054` | | `watcher__` | `0x300bb063` | @@ -361,22 +361,22 @@ | ---------------------------- | ------------ | | `cancelOwnershipHandover` | `0x54d1f13d` | | `completeOwnershipHandover` | `0xf04e283e` | -| `getPlugConfigs` | `0x8a028c38` | +| `getPlugConfigs` | `0x25945c1a` | | `initialize` | `0x485cc955` | -| `isValidPlug` | `0xec8aef74` | +| `isValidPlug` | `0x00f9b9f4` | | `owner` | `0x8da5cb5b` | | `ownershipHandoverExpiresAt` | `0xfee81cf4` | | `renounceOwnership` | `0x715018a6` | | `requestOwnershipHandover` | `0x25692962` | | `rescueFunds` | `0x6ccae054` | -| `setAppGatewayConfigs` | `0xd137fcbb` | -| `setIsValidPlug` | `0xf41332b0` | -| `setSocket` | `0x075c40be` | -| `setSwitchboard` | `0x61706f1e` | +| `setAppGatewayConfigs` | `0xebfb22cd` | +| `setIsValidPlug` | `0x4842c37a` | +| `setSocket` | `0x38d4de67` | +| `setSwitchboard` | `0x491eac1f` | | `sockets` | `0xb44a23ab` | | `switchboards` | `0xaa539546` | | `transferOwnership` | `0xf2fde38b` | -| `verifyConnections` | `0xa53b6fad` | +| `verifyConnections` | `0x36cb19fb` | | `watcher__` | `0x300bb063` | ## PromiseResolver @@ -420,7 +420,7 @@ | `rescueFunds` | `0x6ccae054` | | `setPrecompile` | `0x122e0042` | | `setRequestPayloadCountLimit` | `0x8526582b` | -| `submitRequest` | `0xbb299a2c` | +| `submitRequest` | `0xf91ba7cc` | | `transferOwnership` | `0xf2fde38b` | | `updateRequestAndProcessBatch` | `0x46464471` | | `watcher__` | `0x300bb063` | @@ -455,14 +455,14 @@ | `ownershipHandoverExpiresAt` | `0xfee81cf4` | | `payloadQueue` | `0x74f00ffb` | | `promiseResolver__` | `0xdee152be` | -| `queue` | `0xf03ca7f7` | -| `queueAndSubmit` | `0xf0fb9665` | +| `queue` | `0x65967f1a` | +| `queueAndSubmit` | `0x9d4c9df7` | | `renounceOwnership` | `0x715018a6` | | `requestHandler__` | `0x55184561` | | `requestOwnershipHandover` | `0x25692962` | | `rescueFunds` | `0xa58c6fc5` | | `setCoreContracts` | `0xefa891c4` | -| `setIsValidPlug` | `0x7fc82ff6` | +| `setIsValidPlug` | `0x06c0a40a` | | `setTriggerFees` | `0xaeb30511` | | `submitRequest` | `0x4890b5ef` | | `transferOwnership` | `0xf2fde38b` | @@ -506,7 +506,7 @@ | `resolvePayload` | `0xea92e825` | | `setExpiryTime` | `0x30fc4cff` | | `setFees` | `0x3d18678e` | -| `validateAndGetPrecompileData` | `0xab172aab` | +| `validateAndGetPrecompileData` | `0x997f5bef` | | `watcher__` | `0x300bb063` | ## SchedulePrecompile @@ -525,7 +525,7 @@ | `setMaxScheduleDelayInSeconds` | `0x12953318` | | `setScheduleCallbackFees` | `0xec8fd71e` | | `setScheduleFeesPerSecond` | `0x28e59e57` | -| `validateAndGetPrecompileData` | `0xab172aab` | +| `validateAndGetPrecompileData` | `0x997f5bef` | | `watcher__` | `0x300bb063` | ## WritePrecompile @@ -538,7 +538,7 @@ | `contractFactoryPlugs` | `0x35426631` | | `digestHashes` | `0xd1a862bf` | | `expiryTime` | `0x99bc0aea` | -| `getDigest` | `0xdd4bf97b` | +| `getDigest` | `0x91b6288b` | | `getPrecompileFees` | `0xb7a3d04c` | | `getPrevBatchDigestHash` | `0x372863a1` | | `handlePayload` | `0x1d5e1d98` | @@ -549,13 +549,13 @@ | `requestOwnershipHandover` | `0x25692962` | | `rescueFunds` | `0x6ccae054` | | `resolvePayload` | `0xea92e825` | -| `setContractFactoryPlugs` | `0xc067b6dd` | +| `setContractFactoryPlugs` | `0x8b198f5c` | | `setExpiryTime` | `0x30fc4cff` | | `setFees` | `0x3d18678e` | | `transferOwnership` | `0xf2fde38b` | | `updateChainMaxMsgValueLimits` | `0x6a7aa6ac` | | `uploadProof` | `0x81b48fcf` | -| `validateAndGetPrecompileData` | `0xab172aab` | +| `validateAndGetPrecompileData` | `0x997f5bef` | | `watcherProofs` | `0x3fa3166b` | | `watcher__` | `0x300bb063` | | `writeFees` | `0x5c664aeb` | diff --git a/contracts/evmx/base/AppGatewayBase.sol b/contracts/evmx/base/AppGatewayBase.sol index 5bcdb2db..f7e5f5ca 100644 --- a/contracts/evmx/base/AppGatewayBase.sol +++ b/contracts/evmx/base/AppGatewayBase.sol @@ -9,6 +9,7 @@ import "../interfaces/IPromise.sol"; import {InvalidPromise, AsyncModifierNotSet} from "../../utils/common/Errors.sol"; import {FAST, READ, WRITE, SCHEDULE} from "../../utils/common/Constants.sol"; import {IsPlug, QueueParams, Read, WriteFinality, Parallel} from "../../utils/common/Structs.sol"; +import {toBytes32Format} from "../../utils/common/Converters.sol"; /// @title AppGatewayBase /// @notice Abstract contract for the app gateway @@ -137,7 +138,7 @@ abstract contract AppGatewayBase is AddressResolverUtil, IAppGateway { function setAddress(bytes memory data_, bytes memory returnData_) external onlyPromises { (uint32 chainSlug, bytes32 contractId) = abi.decode(data_, (uint32, bytes32)); forwarderAddresses[contractId][chainSlug] = asyncDeployer__().getOrDeployForwarderContract( - abi.decode(returnData_, (address)), + toBytes32Format(abi.decode(returnData_, (address))), chainSlug ); } @@ -161,9 +162,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(0); } onChainAddress = IForwarder(forwarderAddresses[contractId_][chainSlug_]) @@ -216,7 +217,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(bool isValid, uint32 chainSlug_, bytes32 contractId_) internal { - address onchainAddress = getOnChainAddress(contractId_, chainSlug_); + bytes32 onchainAddress = getOnChainAddress(contractId_, chainSlug_); watcher__().setIsValidPlug(isValid, chainSlug_, onchainAddress); } diff --git a/contracts/evmx/fees/Credit.sol b/contracts/evmx/fees/Credit.sol index 4468d12f..cb822c04 100644 --- a/contracts/evmx/fees/Credit.sol +++ b/contracts/evmx/fees/Credit.sol @@ -14,6 +14,7 @@ import {AddressResolverUtil} from "../helpers/AddressResolverUtil.sol"; import {NonceUsed, InvalidAmount, InsufficientCreditsAvailable, InsufficientBalance, InvalidChainSlug, NotRequestHandler} from "../../utils/common/Errors.sol"; import {WRITE} from "../../utils/common/Constants.sol"; import "../../utils/RescueFundsLib.sol"; +import {toBytes32Format} from "../../utils/common/Converters.sol"; abstract contract FeesManagerStorage is IFeesManager { // slots [0-49] reserved for gap @@ -57,7 +58,7 @@ abstract contract FeesManagerStorage is IFeesManager { // slot 57 /// @notice Mapping to track fees plug for each chain slug /// @dev chainSlug => fees plug address - mapping(uint32 => address) public feesPlugs; + mapping(uint32 => bytes32) public feesPlugs; // slots [58-107] reserved for gap uint256[50] _gap_after; @@ -92,7 +93,7 @@ abstract contract Credit is FeesManagerStorage, Initializable, Ownable, AddressR event CreditsTransferred(address indexed from, address indexed to, uint256 amount); /// @notice Emitted when fees plug is set - event FeesPlugSet(uint32 indexed chainSlug, address indexed feesPlug); + event FeesPlugSet(uint32 indexed chainSlug, bytes32 indexed feesPlug); /// @notice Emitted when fees pool is set event FeesPoolSet(address indexed feesPool); @@ -100,7 +101,7 @@ abstract contract Credit is FeesManagerStorage, Initializable, Ownable, AddressR /// @notice Emitted when withdraw fails event WithdrawFailed(bytes32 indexed payloadId); - function setFeesPlug(uint32 chainSlug_, address feesPlug_) external onlyOwner { + function setFeesPlug(uint32 chainSlug_, bytes32 feesPlug_) external onlyOwner { feesPlugs[chainSlug_] = feesPlug_; emit FeesPlugSet(chainSlug_, feesPlug_); } @@ -295,8 +296,8 @@ abstract contract Credit is FeesManagerStorage, Initializable, Ownable, AddressR watcher__().queueAndSubmit(queueParams, maxFees_, address(0), consumeFrom_, bytes("")); } - function _getFeesPlugAddress(uint32 chainSlug_) internal view returns (address) { - if (feesPlugs[chainSlug_] == address(0)) revert InvalidChainSlug(); + function _getFeesPlugAddress(uint32 chainSlug_) internal view returns (bytes32) { + if (feesPlugs[chainSlug_] == bytes32(0)) revert InvalidChainSlug(); return feesPlugs[chainSlug_]; } diff --git a/contracts/evmx/helpers/AsyncDeployer.sol b/contracts/evmx/helpers/AsyncDeployer.sol index 735d3241..17053f3b 100644 --- a/contracts/evmx/helpers/AsyncDeployer.sol +++ b/contracts/evmx/helpers/AsyncDeployer.sol @@ -66,7 +66,7 @@ contract AsyncDeployer is AsyncDeployerStorage, Initializable, AddressResolverUt /// @param chainSlug_ The chain slug /// @return newForwarder The address of the deployed Forwarder proxy contract function getOrDeployForwarderContract( - address chainContractAddress_, + bytes32 chainContractAddress_, uint32 chainSlug_ ) public override returns (address newForwarder) { // predict address @@ -107,7 +107,7 @@ contract AsyncDeployer is AsyncDeployerStorage, Initializable, AddressResolverUt } function _createForwarderParams( - address chainContractAddress_, + bytes32 chainContractAddress_, uint32 chainSlug_ ) internal view returns (bytes32 salt, bytes memory initData) { bytes memory constructorArgs = abi.encode( @@ -168,7 +168,7 @@ contract AsyncDeployer is AsyncDeployerStorage, Initializable, AddressResolverUt /// @param chainSlug_ The chain slug /// @return The predicted address of the Forwarder proxy contract function getForwarderAddress( - address chainContractAddress_, + bytes32 chainContractAddress_, uint32 chainSlug_ ) public view override returns (address) { (bytes32 salt, ) = _createForwarderParams(chainContractAddress_, chainSlug_); diff --git a/contracts/evmx/helpers/DeployForwarder.sol b/contracts/evmx/helpers/DeployForwarder.sol index 86a46f3e..be2ab041 100644 --- a/contracts/evmx/helpers/DeployForwarder.sol +++ b/contracts/evmx/helpers/DeployForwarder.sol @@ -9,9 +9,9 @@ import {IDeployForwarder} from "../interfaces/IDeployForwarder.sol"; import {AsyncModifierNotSet} from "../../utils/common/Errors.sol"; import {QueueParams, OverrideParams, Transaction} from "../../utils/common/Structs.sol"; import {WRITE} from "../../utils/common/Constants.sol"; -import {encodeAppGatewayId} from "../../utils/common/IdUtils.sol"; import "../../utils/RescueFundsLib.sol"; import "./AddressResolverUtil.sol"; +import {toBytes32Format} from "../../utils/common/Converters.sol"; /// @title DeployForwarder /// @notice contract responsible for handling deployment requests @@ -64,7 +64,7 @@ contract DeployForwarder is IDeployForwarder, Initializable, AddressResolverUtil queueParams.switchboardType = deployerSwitchboardType; queueParams.transaction = Transaction({ chainSlug: chainSlug_, - target: address(0), + target: bytes32(0), payload: _createPayload( isPlug_, plugSwitchboardType, @@ -93,7 +93,7 @@ contract DeployForwarder is IDeployForwarder, Initializable, AddressResolverUtil IContractFactoryPlug.deployContract.selector, isPlug_, salt, - encodeAppGatewayId(appGateway_), + toBytes32Format(appGateway_), watcher__().configurations__().switchboards(chainSlug_, plugSwitchboardType_), payload_, initCallData_ diff --git a/contracts/evmx/helpers/Forwarder.sol b/contracts/evmx/helpers/Forwarder.sol index 8b778061..9c53ba22 100644 --- a/contracts/evmx/helpers/Forwarder.sol +++ b/contracts/evmx/helpers/Forwarder.sol @@ -9,6 +9,7 @@ import "../interfaces/IForwarder.sol"; import {QueueParams, OverrideParams, Transaction} from "../../utils/common/Structs.sol"; import {AsyncModifierNotSet, WatcherNotSet, InvalidOnChainAddress} from "../../utils/common/Errors.sol"; import "../../utils/RescueFundsLib.sol"; +import {toBytes32Format} from "../../utils/common/Converters.sol"; /// @title Forwarder Storage /// @notice Storage contract for the Forwarder contract that contains the state variables @@ -19,11 +20,16 @@ abstract contract ForwarderStorage is IForwarder { // slot 50 /// @notice chain slug on which the contract is deployed uint32 public chainSlug; + + /// @notice old on-chain address kep for storage compatibility - can be removed after redeployment + address internal oldOnChainAddress; + + // slot 51 /// @notice on-chain address associated with this forwarder - address public onChainAddress; + bytes32 public onChainAddress; - // slots [51-100] reserved for gap - uint256[50] _gap_after; + // slots [52-100] reserved for gap + uint256[49] _gap_after; // slots [101-150] 50 slots reserved for address resolver util } @@ -41,10 +47,10 @@ contract Forwarder is ForwarderStorage, Initializable, AddressResolverUtil { /// @param addressResolver_ address resolver contract function initialize( uint32 chainSlug_, - address onChainAddress_, + bytes32 onChainAddress_, address addressResolver_ ) public reinitializer(1) { - if (onChainAddress_ == address(0)) revert InvalidOnChainAddress(); + if (onChainAddress_ == bytes32(0)) revert InvalidOnChainAddress(); chainSlug = chainSlug_; onChainAddress = onChainAddress_; _setAddressResolver(addressResolver_); @@ -52,7 +58,10 @@ 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 override returns (address) { + function getOnChainAddress() public view override returns (bytes32) { + if (oldOnChainAddress != address(0)) { + return toBytes32Format(oldOnChainAddress); + } return onChainAddress; } @@ -94,7 +103,7 @@ contract Forwarder is ForwarderStorage, Initializable, AddressResolverUtil { queueParams.overrideParams = overrideParams; queueParams.transaction = Transaction({ chainSlug: chainSlug, - target: onChainAddress, + target: getOnChainAddress(), payload: msg.data }); queueParams.switchboardType = sbType; diff --git a/contracts/evmx/interfaces/IAppGateway.sol b/contracts/evmx/interfaces/IAppGateway.sol index 132e8c96..2321a8bc 100644 --- a/contracts/evmx/interfaces/IAppGateway.sol +++ b/contracts/evmx/interfaces/IAppGateway.sol @@ -35,7 +35,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/IAsyncDeployer.sol b/contracts/evmx/interfaces/IAsyncDeployer.sol index 9023db36..b0c8d14d 100644 --- a/contracts/evmx/interfaces/IAsyncDeployer.sol +++ b/contracts/evmx/interfaces/IAsyncDeployer.sol @@ -22,12 +22,12 @@ interface IAsyncDeployer { // Forwarder Management function getOrDeployForwarderContract( - address chainContractAddress_, + bytes32 chainContractAddress_, uint32 chainSlug_ ) external returns (address); function getForwarderAddress( - address chainContractAddress_, + bytes32 chainContractAddress_, uint32 chainSlug_ ) external view returns (address); diff --git a/contracts/evmx/interfaces/IConfigurations.sol b/contracts/evmx/interfaces/IConfigurations.sol index eb795a76..9d095679 100644 --- a/contracts/evmx/interfaces/IConfigurations.sol +++ b/contracts/evmx/interfaces/IConfigurations.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} from "../../utils/common/Structs.sol"; /// @title IConfigurations /// @notice Interface for the Watcher Precompile system that handles payload verification and execution @@ -10,7 +10,7 @@ interface IConfigurations { /// @notice Verifies connections between components function verifyConnections( uint32 chainSlug_, - address target_, + bytes32 target_, address appGateway_, bytes32 switchboardType_ ) external view; @@ -19,39 +19,39 @@ interface IConfigurations { function isValidPlug( address appGateway, uint32 chainSlug, - address plug + bytes32 plug ) external view returns (bool); /// @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 Maps chain slug to their associated socket /// @param chainSlug_ The chain slug /// @return The socket - function sockets(uint32 chainSlug_) external view returns (address); + function sockets(uint32 chainSlug_) external view returns (bytes32); /// @notice Returns the socket for a given chain slug /// @param chainSlug_ The chain slug /// @return The socket - function switchboards(uint32 chainSlug_, bytes32 sbType_) external view returns (address); + function switchboards(uint32 chainSlug_, bytes32 sbType_) external view returns (bytes32); /// @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( bool isValid_, uint32 chainSlug_, - address plug_, + bytes32 plug_, address appGateway_ ) external; function setAppGatewayConfigs(AppGatewayConfig[] calldata configs_) external; /// @notice Sets the socket for a chain slug - function setSocket(uint32 chainSlug_, address socket_) external; + function setSocket(uint32 chainSlug_, bytes32 socket_) external; } diff --git a/contracts/evmx/interfaces/IForwarder.sol b/contracts/evmx/interfaces/IForwarder.sol index b609fc31..cbc2546a 100644 --- a/contracts/evmx/interfaces/IForwarder.sol +++ b/contracts/evmx/interfaces/IForwarder.sol @@ -4,9 +4,9 @@ pragma solidity ^0.8.21; /// @title IForwarder /// @notice Interface for the Forwarder contract that allows contracts to call async promises interface IForwarder { - /// @notice Returns the on-chain address of the contract being referenced - /// @return The on-chain address - function getOnChainAddress() external view returns (address); + /// @notice Returns the on-chain address (as bytes32) of the contract being referenced + /// @return The on-chain address in bytes32 format + 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/IWatcher.sol b/contracts/evmx/interfaces/IWatcher.sol index e76161d7..7f127de9 100644 --- a/contracts/evmx/interfaces/IWatcher.sol +++ b/contracts/evmx/interfaces/IWatcher.sol @@ -45,7 +45,7 @@ interface IWatcher { function triggerFromChainSlug() external view returns (uint32); - function triggerFromPlug() external view returns (address); + function triggerFromPlug() external view returns (bytes32); function isAppGatewayCalled(bytes32 triggerId) external view returns (bool); @@ -87,7 +87,7 @@ interface IWatcher { function increaseFees(uint40 requestCount_, uint256 newFees_) external; - function setIsValidPlug(bool isValid_, uint32 chainSlug_, address onchainAddress_) external; + function setIsValidPlug(bool isValid_, uint32 chainSlug_, bytes32 onchainAddress_) external; function isWatcher(address account_) external view returns (bool); } diff --git a/contracts/evmx/watcher/Configurations.sol b/contracts/evmx/watcher/Configurations.sol index 2674f7fb..dc0b3694 100644 --- a/contracts/evmx/watcher/Configurations.sol +++ b/contracts/evmx/watcher/Configurations.sol @@ -4,10 +4,11 @@ pragma solidity ^0.8.21; import "solady/utils/Initializable.sol"; import "../interfaces/IConfigurations.sol"; import {WatcherBase} from "./WatcherBase.sol"; -import {encodeAppGatewayId} from "../../utils/common/IdUtils.sol"; import {InvalidGateway, InvalidSwitchboard} from "../../utils/common/Errors.sol"; import "solady/auth/Ownable.sol"; import "../../utils/RescueFundsLib.sol"; +import {toBytes32Format} from "../../utils/common/Converters.sol"; +import {PlugConfigGeneric} from "../../utils/common/Structs.sol"; abstract contract ConfigurationsStorage is IConfigurations { // slots [0-49] reserved for gap @@ -16,22 +17,22 @@ abstract contract ConfigurationsStorage is IConfigurations { // slot 50 /// @notice Maps network and plug to their configuration /// @dev chainSlug => plug => PlugConfig - mapping(uint32 => mapping(address => PlugConfig)) internal _plugConfigs; + mapping(uint32 => mapping(bytes32 => PlugConfigGeneric)) internal _plugConfigs; // slot 51 /// @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 52 /// @notice Maps chain slug to their associated socket /// @dev chainSlug => socket address - mapping(uint32 => address) public sockets; + mapping(uint32 => bytes32) public sockets; // slot 53 /// @notice Maps app gateway, chain slug, and plug to whether it is valid /// @dev appGateway => chainSlug => plug => isValid - mapping(address => mapping(uint32 => mapping(address => bool))) public isValidPlug; + mapping(address => mapping(uint32 => mapping(bytes32 => bool))) public isValidPlug; // slots [54-103] reserved for gap uint256[50] _gap_after; @@ -47,25 +48,25 @@ contract Configurations is ConfigurationsStorage, Initializable, Ownable, Watche /// @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 socket is set for a network /// @param chainSlug The identifier of the network /// @param socket The address of the socket - event SocketSet(uint32 chainSlug, address socket); + event SocketSet(uint32 chainSlug, bytes32 socket); /// @notice Emitted when a valid plug is set for an app gateway /// @param appGateway The address of the app gateway /// @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); constructor() { _disableInitializers(); // disable for implementation @@ -96,7 +97,7 @@ contract Configurations is ConfigurationsStorage, Initializable, Ownable, Watche /// @notice Sets the socket for a network /// @param chainSlug_ The identifier of the network /// @param socket_ The address of the socket - function setSocket(uint32 chainSlug_, address socket_) external onlyOwner { + function setSocket(uint32 chainSlug_, bytes32 socket_) external onlyOwner { sockets[chainSlug_] = socket_; emit SocketSet(chainSlug_, socket_); } @@ -108,7 +109,7 @@ contract Configurations is ConfigurationsStorage, Initializable, Ownable, Watche function setSwitchboard( uint32 chainSlug_, bytes32 sbType_, - address switchboard_ + bytes32 switchboard_ ) external onlyOwner { switchboards[chainSlug_][sbType_] = switchboard_; emit SwitchboardSet(chainSlug_, sbType_, switchboard_); @@ -123,7 +124,7 @@ contract Configurations is ConfigurationsStorage, Initializable, Ownable, Watche function setIsValidPlug( bool isValid_, uint32 chainSlug_, - address plug_, + bytes32 plug_, address appGateway_ ) external onlyWatcher { isValidPlug[appGateway_][chainSlug_][plug_] = isValid_; @@ -138,8 +139,8 @@ contract Configurations is ConfigurationsStorage, Initializable, Ownable, Watche /// @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 @@ -154,12 +155,12 @@ contract Configurations is ConfigurationsStorage, Initializable, Ownable, Watche /// @param switchboardType_ The type of switchboard function verifyConnections( uint32 chainSlug_, - address target_, + bytes32 target_, address appGateway_, bytes32 switchboardType_ ) external view { - (bytes32 appGatewayId, address switchboard) = getPlugConfigs(chainSlug_, target_); - if (appGatewayId != encodeAppGatewayId(appGateway_)) revert InvalidGateway(); + (bytes32 appGatewayId, bytes32 switchboard) = getPlugConfigs(chainSlug_, target_); + if (appGatewayId != toBytes32Format(appGateway_)) revert InvalidGateway(); if (switchboard != switchboards[chainSlug_][switchboardType_]) revert InvalidSwitchboard(); } diff --git a/contracts/evmx/watcher/RequestHandler.sol b/contracts/evmx/watcher/RequestHandler.sol index f11ca0bf..ad1a6b71 100644 --- a/contracts/evmx/watcher/RequestHandler.sol +++ b/contracts/evmx/watcher/RequestHandler.sol @@ -228,8 +228,8 @@ contract RequestHandler is RequestHandlerStorage, Initializable, Ownable, Addres } // get the switchboard address from the configurations - // returns address(0) for schedule precompile and reads if sb type not set - address switchboard = watcher__().configurations__().switchboards( + // returns bytes32(0) for schedule precompile and reads if sb type not set + bytes32 switchboard = watcher__().configurations__().switchboards( queuePayloadParam.transaction.chainSlug, queuePayloadParam.switchboardType ); diff --git a/contracts/evmx/watcher/Trigger.sol b/contracts/evmx/watcher/Trigger.sol index c72ff27b..72e7dfcd 100644 --- a/contracts/evmx/watcher/Trigger.sol +++ b/contracts/evmx/watcher/Trigger.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.21; import {LibCall} from "solady/utils/LibCall.sol"; import "./WatcherStorage.sol"; -import {decodeAppGatewayId} from "../../utils/common/IdUtils.sol"; +import {fromBytes32Format} from "../../utils/common/Converters.sol"; /// @title Trigger /// @notice Contract that handles trigger validation and execution logic @@ -29,7 +29,7 @@ abstract contract Trigger is WatcherStorage, AddressResolverUtil { function _callAppGateways(TriggerParams memory params_) internal { if (isAppGatewayCalled[params_.triggerId]) revert AppGatewayAlreadyCalled(); - address appGateway = decodeAppGatewayId(params_.appGatewayId); + address appGateway = fromBytes32Format(params_.appGatewayId); if (!configurations__.isValidPlug(appGateway, params_.chainSlug, params_.plug)) revert InvalidCallerTriggered(); @@ -52,6 +52,6 @@ abstract contract Trigger is WatcherStorage, AddressResolverUtil { } triggerFromChainSlug = 0; - triggerFromPlug = address(0); + triggerFromPlug = bytes32(0); } } diff --git a/contracts/evmx/watcher/Watcher.sol b/contracts/evmx/watcher/Watcher.sol index 7dbaa28b..b6714b92 100644 --- a/contracts/evmx/watcher/Watcher.sol +++ b/contracts/evmx/watcher/Watcher.sol @@ -153,7 +153,7 @@ contract Watcher is Trigger { return requestHandler__.getPayload(payloadId_); } - function setIsValidPlug(bool isValid_, uint32 chainSlug_, address plug_) external override { + function setIsValidPlug(bool isValid_, uint32 chainSlug_, bytes32 plug_) external override { configurations__.setIsValidPlug(isValid_, chainSlug_, plug_, msg.sender); } diff --git a/contracts/evmx/watcher/WatcherStorage.sol b/contracts/evmx/watcher/WatcherStorage.sol index 8c127eff..ff52d4e4 100644 --- a/contracts/evmx/watcher/WatcherStorage.sol +++ b/contracts/evmx/watcher/WatcherStorage.sol @@ -16,13 +16,11 @@ abstract contract WatcherStorage is IWatcher, Initializable, Ownable { // slots [0-49]: gap for future storage variables uint256[50] _gap_before; - // slot 50 (32 + 32 + 160) + // slot 50 (32 + 32) /// @notice The chain slug of the watcher precompile uint32 public evmxSlug; /// @notice stores temporary chainSlug of the trigger from a chain uint32 public override triggerFromChainSlug; - /// @notice stores temporary plug of the trigger from a chain - address public override triggerFromPlug; // slot 51 /// @notice Stores the trigger fees @@ -59,8 +57,12 @@ abstract contract WatcherStorage is IWatcher, Initializable, Ownable { /// @dev signatureNonce => isValid mapping(uint256 => bool) public isNonceUsed; - // slots [60-109]: gap for future storage variables - uint256[50] _gap_after; + // slot 60 + /// @notice stores temporary plug of the trigger from a chain + bytes32 public override triggerFromPlug; + + // slots [61-109]: gap for future storage variables + uint256[49] _gap_after; // slots [110-159] 50 slots reserved for address resolver util } diff --git a/contracts/evmx/watcher/precompiles/ReadPrecompile.sol b/contracts/evmx/watcher/precompiles/ReadPrecompile.sol index e8c7f2e8..175fb4d0 100644 --- a/contracts/evmx/watcher/precompiles/ReadPrecompile.sol +++ b/contracts/evmx/watcher/precompiles/ReadPrecompile.sol @@ -37,7 +37,7 @@ contract ReadPrecompile is IPrecompile, WatcherBase { QueueParams calldata queueParams_, address ) external view returns (bytes memory precompileData, uint256 estimatedFees) { - if (queueParams_.transaction.target == address(0)) revert InvalidTarget(); + if (queueParams_.transaction.target == bytes32(0)) revert InvalidTarget(); if (queueParams_.transaction.payload.length == 0) revert InvalidPayloadSize(); // For read precompile, encode the payload parameters diff --git a/contracts/evmx/watcher/precompiles/WritePrecompile.sol b/contracts/evmx/watcher/precompiles/WritePrecompile.sol index a36eaf4e..be56971f 100644 --- a/contracts/evmx/watcher/precompiles/WritePrecompile.sol +++ b/contracts/evmx/watcher/precompiles/WritePrecompile.sol @@ -5,11 +5,11 @@ import "solady/utils/Initializable.sol"; import "solady/auth/Ownable.sol"; import "../../interfaces/IPrecompile.sol"; -import {WRITE, PAYLOAD_SIZE_LIMIT} from "../../../utils/common/Constants.sol"; +import {WRITE, PAYLOAD_SIZE_LIMIT, CHAIN_SLUG_SOLANA_MAINNET, CHAIN_SLUG_SOLANA_DEVNET} from "../../../utils/common/Constants.sol"; import {InvalidIndex, MaxMsgValueLimitExceeded, InvalidPayloadSize} from "../../../utils/common/Errors.sol"; -import {encodeAppGatewayId} from "../../../utils/common/IdUtils.sol"; import "../../../utils/RescueFundsLib.sol"; import "../WatcherBase.sol"; +import {toBytes32Format} from "../../../utils/common/Converters.sol"; abstract contract WritePrecompileStorage is IPrecompile { // slots [0-49] reserved for gap @@ -37,21 +37,20 @@ abstract contract WritePrecompileStorage is IPrecompile { mapping(bytes32 => bytes32) public digestHashes; // slot 55 - mapping(uint32 => address) public contractFactoryPlugs; + mapping(uint32 => bytes32) public contractFactoryPlugs; // slots [56-105] reserved for gap uint256[50] _gap_after; // 1 slot reserved for watcher base } - /// @title WritePrecompile /// @notice Handles write precompile logic contract WritePrecompile is WritePrecompileStorage, Initializable, Ownable, WatcherBase { /// @notice Emitted when fees are set event FeesSet(uint256 writeFees); event ChainMaxMsgValueLimitsUpdated(uint32 chainSlug, uint256 maxMsgValueLimit); - event ContractFactoryPlugSet(uint32 chainSlug, address contractFactoryPlug); + event ContractFactoryPlugSet(uint32 chainSlug, bytes32 contractFactoryPlug); /// @notice Emitted when a proof upload request is made event WriteProofRequested( address transmitter, @@ -107,7 +106,7 @@ contract WritePrecompile is WritePrecompileStorage, Initializable, Ownable, Watc revert InvalidPayloadSize(); } - if (queueParams_.transaction.target == address(0)) { + if (queueParams_.transaction.target == bytes32(0)) { queueParams_.transaction.target = contractFactoryPlugs[ queueParams_.transaction.chainSlug ]; @@ -156,14 +155,15 @@ contract WritePrecompile is WritePrecompileStorage, Initializable, Ownable, Watc { ( address appGateway, - Transaction memory transaction, + Transaction memory transaction,– , uint256 gasLimit, uint256 value, - ) = abi.decode( + ) = + abi.decode( payloadParams.precompileData, - (address, Transaction, WriteFinality, uint256, uint256, address) + (address, Transaction, WriteFinality, uint256, uint256, bytes32) ); precompileData = payloadParams.precompileData; @@ -186,7 +186,7 @@ contract WritePrecompile is WritePrecompileStorage, Initializable, Ownable, Watc value, transaction.payload, transaction.target, - encodeAppGatewayId(appGateway), + toBytes32Format(appGateway), prevBatchDigestHash, bytes("") ); @@ -233,7 +233,7 @@ contract WritePrecompile is WritePrecompileStorage, Initializable, Ownable, Watc /// @dev This function creates a keccak256 hash of the payload parameters function getDigest(DigestParams memory params_) public pure returns (bytes32 digest) { digest = keccak256( - abi.encode( + abi.encodePacked( params_.socket, params_.transmitter, params_.payloadId, @@ -276,7 +276,7 @@ contract WritePrecompile is WritePrecompileStorage, Initializable, Ownable, Watc function setContractFactoryPlugs( uint32 chainSlug_, - address contractFactoryPlug_ + bytes32 contractFactoryPlug_ ) external onlyOwner { contractFactoryPlugs[chainSlug_] = contractFactoryPlug_; emit ContractFactoryPlugSet(chainSlug_, contractFactoryPlug_); diff --git a/contracts/protocol/Socket.sol b/contracts/protocol/Socket.sol index 09e06157..b5e8bb17 100644 --- a/contracts/protocol/Socket.sol +++ b/contracts/protocol/Socket.sol @@ -67,7 +67,7 @@ contract Socket is SocketUtils { // check if the call type is valid if (executeParams_.callType != WRITE) revert InvalidCallType(); - 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(); @@ -78,7 +78,7 @@ contract Socket is SocketUtils { executeParams_.requestCount, executeParams_.batchCount, executeParams_.payloadCount, - plugConfig.switchboard, + toBytes32Format(plugConfig.switchboard), chainSlug ); @@ -180,7 +180,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 @@ -191,8 +191,8 @@ contract Socket is SocketUtils { emit AppGatewayCallRequested( triggerId, plugConfig.appGatewayId, - plugConfig.switchboard, - plug_, + toBytes32Format(plugConfig.switchboard), + toBytes32Format(plug_), // gets the overrides from the plug IPlug(plug_).overrides(), msg.data diff --git a/contracts/protocol/SocketConfig.sol b/contracts/protocol/SocketConfig.sol index b492d225..32bafb17 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 {PlugConfig, SwitchboardStatus, ExecutionStatus} from "../utils/common/Structs.sol"; +import {PlugConfigEvm, SwitchboardStatus, ExecutionStatus} from "../utils/common/Structs.sol"; import "../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 @@ -79,7 +79,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_; @@ -103,7 +103,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/protocol/SocketUtils.sol b/contracts/protocol/SocketUtils.sol index 4f96ec81..46597144 100644 --- a/contracts/protocol/SocketUtils.sol +++ b/contracts/protocol/SocketUtils.sol @@ -5,6 +5,7 @@ import {ECDSA} from "solady/utils/ECDSA.sol"; import "../utils/RescueFundsLib.sol"; import "./SocketConfig.sol"; import {LibCall} from "solady/utils/LibCall.sol"; +import {toBytes32Format} from "../utils/common/Converters.sol"; /** * @title SocketUtils @@ -73,8 +74,8 @@ abstract contract SocketUtils is SocketConfig { ) internal view returns (bytes32) { return keccak256( - abi.encode( - address(this), + abi.encodePacked( + toBytes32Format(address(this)), transmitter_, payloadId_, executeParams_.deadline, @@ -82,7 +83,7 @@ abstract contract SocketUtils is SocketConfig { executeParams_.gasLimit, executeParams_.value, executeParams_.payload, - executeParams_.target, + toBytes32Format(executeParams_.target), appGatewayId_, executeParams_.prevBatchDigestHash, executeParams_.extraData diff --git a/contracts/protocol/interfaces/ISocket.sol b/contracts/protocol/interfaces/ISocket.sol index 80a8a25a..74dfe535 100644 --- a/contracts/protocol/interfaces/ISocket.sol +++ b/contracts/protocol/interfaces/ISocket.sol @@ -43,8 +43,8 @@ interface ISocket { event AppGatewayCallRequested( bytes32 triggerId, bytes32 appGatewayId, - address switchboard, - address plug, + bytes32 switchboard, + bytes32 plug, bytes overrides, bytes payload ); diff --git a/contracts/protocol/switchboard/FastSwitchboard.sol b/contracts/protocol/switchboard/FastSwitchboard.sol index ee0679a4..27d915fe 100644 --- a/contracts/protocol/switchboard/FastSwitchboard.sol +++ b/contracts/protocol/switchboard/FastSwitchboard.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.21; import "./SwitchboardBase.sol"; import {WATCHER_ROLE} from "../../utils/common/AccessRoles.sol"; +import {toBytes32Format} from "../../utils/common/Converters.sol"; /** * @title FastSwitchboard contract @@ -43,7 +44,7 @@ contract FastSwitchboard is SwitchboardBase { if (isAttested[digest_]) revert AlreadyAttested(); address watcher = _recoverSigner( - keccak256(abi.encode(address(this), chainSlug, digest_)), + keccak256(abi.encodePacked(toBytes32Format(address(this)), chainSlug, digest_)), proof_ ); if (!_hasRole(WATCHER_ROLE, watcher)) revert WatcherNotFound(); diff --git a/contracts/utils/common/Constants.sol b/contracts/utils/common/Constants.sol index 2afa6479..62b19797 100644 --- a/contracts/utils/common/Constants.sol +++ b/contracts/utils/common/Constants.sol @@ -16,3 +16,6 @@ bytes32 constant FAST = keccak256("FAST"); uint256 constant PAYLOAD_SIZE_LIMIT = 24_500; uint16 constant MAX_COPY_BYTES = 2048; // 2KB + +uint32 constant CHAIN_SLUG_SOLANA_MAINNET = 10000001; +uint32 constant CHAIN_SLUG_SOLANA_DEVNET = 10000002; 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/IdUtils.sol b/contracts/utils/common/IdUtils.sol index 899abc5e..6490ad04 100644 --- a/contracts/utils/common/IdUtils.sol +++ b/contracts/utils/common/IdUtils.sol @@ -1,14 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.22; -function encodeAppGatewayId(address appGateway_) pure returns (bytes32) { - return bytes32(uint256(uint160(appGateway_))); -} - -function decodeAppGatewayId(bytes32 appGatewayId_) 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 @@ -20,9 +12,11 @@ function createPayloadId( uint40 requestCount_, uint40 batchCount_, uint40 payloadCount_, - address switchboard_, + bytes32 switchboard_, uint32 chainSlug_ ) pure returns (bytes32) { return - keccak256(abi.encode(requestCount_, batchCount_, payloadCount_, chainSlug_, switchboard_)); + keccak256( + abi.encodePacked(requestCount_, batchCount_, payloadCount_, chainSlug_, switchboard_) + ); } diff --git a/contracts/utils/common/Structs.sol b/contracts/utils/common/Structs.sol index 80943216..b8b26830 100644 --- a/contracts/utils/common/Structs.sol +++ b/contracts/utils/common/Structs.sol @@ -51,19 +51,30 @@ struct AppGatewayApprovals { //// STRUCTS //// struct AppGatewayConfig { - PlugConfig plugConfig; - address plug; + PlugConfigGeneric plugConfig; + bytes32 plug; uint32 chainSlug; } // Plug config: -struct PlugConfig { +// struct PlugConfig { +// bytes32 appGatewayId; +// address switchboard; +// } +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; @@ -124,7 +135,7 @@ struct UserCredits { // digest: struct DigestParams { - address socket; + bytes32 socket; address transmitter; bytes32 payloadId; uint256 deadline; @@ -132,7 +143,7 @@ struct DigestParams { uint256 gasLimit; uint256 value; bytes payload; - address target; + bytes32 target; bytes32 appGatewayId; bytes32 prevBatchDigestHash; bytes extraData; @@ -149,10 +160,9 @@ struct OverrideParams { uint256 delayInSeconds; } -// payload struct Transaction { uint32 chainSlug; - address target; + bytes32 target; bytes payload; } @@ -199,3 +209,24 @@ struct RequestParams { uint256 writeCount; bytes onCompleteData; } + +struct SolanaInstruction { + SolanaInstructionData data; + SolanaInstructionDataDescription description; +} + +struct SolanaInstructionData { + bytes32 programId; + bytes32[] accounts; + bytes8 instructionDiscriminator; + // for now we assume the all functionArguments are simple types (uint256, address, bool, etc.) not complex types (struct, array, etc.) + bytes[] functionArguments; +} + +struct SolanaInstructionDataDescription { + // flags for accounts, we only need isWritable for now + // 0 bit - isWritable (0|1) + bytes1[] accountFlags; + // names for function argument types used later in data decoding in watcher and transmitter + string[] functionArgumentTypeNames; +} diff --git a/foundry.toml b/foundry.toml index 6d1a2709..4c30208e 100644 --- a/foundry.toml +++ b/foundry.toml @@ -10,27 +10,27 @@ evm_version = 'paris' via_ir = false [labels] -0x67790E222c41b0E787C278e757b7c40f03Fa5709 = "AddressResolver" -0x89C928379fED43B7117b852931e2968ce39C8380 = "AddressResolverImpl" -0x1C70bc3043667e884222B8835E0Ae554eb512810 = "AsyncDeployer" -0x09a762309c63a4e19cd3d822aA340Fe964Ba9C92 = "AsyncDeployerImpl" -0xC12aDF88dfc116CAF88816d150FE498843dABEEe = "AuctionManager" -0x55b76897b3BF6ED04188cbaa7DC21ae14b35D3eE = "AuctionManagerImpl" -0x377431bD1A3321C401542C8B1EC6E0c23E125042 = "Configurations" -0xDe5DedAe6e17f906D1269D5e84BEfB06F3926310 = "ConfigurationsImpl" -0xd48218b2DafF9063177b0c6Bae229ec6C5f086a9 = "DeployForwarder" -0x8e178161BB3B36a28C15DFBe3142afF8757B8993 = "DeployForwarderImpl" -0x870fCA8803bEFd119B1317AFB6794F97af7e515e = "ERC1967Factory" -0x761A9024D267006061ec943d02e3949678906f3E = "FeesManager" -0x29C583B64FD2d7b70f8F6253C2a28D60af364Cb5 = "FeesManagerImpl" +0x531b5626BD2514c746ae08D2D2BbAED6948C802F = "AddressResolver" +0x4Fe8DCD92026E29f8D8393611fA225c342E00db8 = "AddressResolverImpl" +0xACEBD9E6089Af301abE05d74f3a8d5A5a1A262f3 = "AsyncDeployer" +0x422214a85832DAAd3D8ABDf0cf67B47a8c889139 = "AsyncDeployerImpl" +0xC388B7c73321B1DE8d523061c6668EC38CfDA486 = "AuctionManager" +0x387d44F7CdcC8924Aa4B4a9b6Ea72Ed1059A041F = "AuctionManagerImpl" +0x9318Be24d10051ca03CC475b03eC6a844F95e724 = "Configurations" +0xBBC5Da309288Ada3C0704d7F2cA95a00DAc7aF81 = "ConfigurationsImpl" +0x8B89Aea83e86786310287118F78508E940bd4395 = "DeployForwarder" +0xf8bda7d44BACB038a7F9eA09301e75e640226717 = "DeployForwarderImpl" +0x003b65f7D0d91C994Db0048DA148571E7f038861 = "ERC1967Factory" +0x16132fa79CB1EE693B0a7d2c0C888870e5B0ef91 = "FeesManager" +0x82C8EAbEFb20E1a2798f121F80bDcf1e7eD6119D = "FeesManagerImpl" 0x9De353dD1131aB4e502590D3a1832652FA316268 = "FeesPool" -0x73b1B3dF6C71e0aa912f9d6933920D4461ae9718 = "PromiseResolver" -0x58f49313816c1876417EE53De8F5de047359fB2C = "ReadPrecompile" -0x63a6D7096b5a2F5c9Ce7D8632A7A2034A85b7F01 = "RequestHandler" -0x593f4844ceEA828bC6d9D78A0ef7Ce64F42190dC = "RequestHandlerImpl" -0xF77d2059a66026Efac11334D30372429553CAaC3 = "SchedulePrecompile" -0xe4D1B4B8c0eEE90ac1f5314e758446CBa201BBA8 = "Watcher" -0x7726e559A5129A9174f89F7E2029f7212B66dD13 = "WatcherImpl" -0xd8be408E271EEe9d3D0f28305bB9b6003589E1A9 = "WritePrecompile" -0xE24c4b0f67f566Fa558b3FE85f1780CD330f1F4D = "WritePrecompileImpl" -0x4Faa9C39f4E1C5be5f9c2e3F5AC8774da3b7B1C2 = "APP_GATEWAY" +0x478Dd0858d6857C2c950E6a08CAB2A96756a3721 = "PromiseResolver" +0x208E78F90713235c5638Fc55Aa15b27ec7CBae9e = "ReadPrecompile" +0xa5d02842BA8B48c5aA22919Cb71D8366252dB452 = "RequestHandler" +0x2e03FEDC25923F7684827bC8f0c8D8dD49a9Bb8A = "RequestHandlerImpl" +0x47eDE68C04f09db20331B85570150a7096c02D86 = "SchedulePrecompile" +0x1A1b863100202c72Db1e4b2aedA11E9381A25f8c = "Watcher" +0x0f2B8e35189F498067886e1093528e32418C1DCb = "WatcherImpl" +0x59F89D9092db218b1D287B93E7bbF754aCFaEE33 = "WritePrecompile" +0x28380539d14F2475881E0E4693593AB09Ba116D0 = "WritePrecompileImpl" +0x5b0a2656b79212f7Fa6FD77F9583290386860EC4 = "APP_GATEWAY" diff --git a/hardhat-scripts/deploy/3.configureChains.ts b/hardhat-scripts/deploy/3.configureChains.ts index 80b30f96..dc2948a3 100644 --- a/hardhat-scripts/deploy/3.configureChains.ts +++ b/hardhat-scripts/deploy/3.configureChains.ts @@ -15,6 +15,8 @@ import { getSocketSigner, getWatcherSigner, overrides, + toBytes32Format, + toBytes32FormatHexString, updateContractSettings, } from "../utils"; @@ -81,24 +83,36 @@ async function setOnchainContracts( const signer: Wallet = getWatcherSigner(); const chainAddresses = addresses[chain] as ChainAddressesObj; + const switchboard = toBytes32FormatHexString( + chainAddresses[Contracts.FastSwitchboard] + ); + const socket = toBytes32FormatHexString(chainAddresses[Contracts.Socket]); + const feesPlug = toBytes32FormatHexString( + chainAddresses[Contracts.FeesPlug]! + ); + const contractFactory = toBytes32FormatHexString( + chainAddresses[Contracts.ContractFactoryPlug] + ); + await updateContractSettings( EVMX_CHAIN_ID, Contracts.Configurations, "switchboards", [chain, FAST_SWITCHBOARD_TYPE], - chainAddresses[Contracts.FastSwitchboard], + switchboard, "setSwitchboard", - [chain, FAST_SWITCHBOARD_TYPE, chainAddresses[Contracts.FastSwitchboard]], + [chain, FAST_SWITCHBOARD_TYPE, toBytes32Format(switchboard)], signer ); + await updateContractSettings( EVMX_CHAIN_ID, Contracts.Configurations, "sockets", [chain], - chainAddresses[Contracts.Socket], + socket, "setSocket", - [chain, chainAddresses[Contracts.Socket]], + [chain, socket], signer ); @@ -108,9 +122,9 @@ async function setOnchainContracts( Contracts.FeesManager, "feesPlugs", [chain], - chainAddresses[Contracts.FeesPlug], + feesPlug, "setFeesPlug", - [chain, chainAddresses[Contracts.FeesPlug]], + [chain, toBytes32Format(feesPlug)], signer ); @@ -119,9 +133,9 @@ async function setOnchainContracts( Contracts.WritePrecompile, "contractFactoryPlugs", [chain], - chainAddresses[Contracts.ContractFactoryPlug], + contractFactory, "setContractFactoryPlugs", - [chain, chainAddresses[Contracts.ContractFactoryPlug]], + [chain, toBytes32Format(contractFactory)], signer ); } diff --git a/hardhat-scripts/deploy/6.connect.ts b/hardhat-scripts/deploy/6.connect.ts index e13d781c..5d427734 100644 --- a/hardhat-scripts/deploy/6.connect.ts +++ b/hardhat-scripts/deploy/6.connect.ts @@ -1,4 +1,4 @@ -import { Wallet } from "ethers"; +import { ethers, Wallet } from "ethers"; import { ChainAddressesObj, ChainSlug, Contracts } from "../../src"; import { chains, EVMX_CHAIN_ID, mode } from "../config"; import { AppGatewayConfig, DeploymentAddresses } from "../constants"; @@ -10,6 +10,7 @@ import { getInstance, getSocketSigner, overrides, + toBytes32FormatHexString, } from "../utils"; import { getWatcherSigner, sendWatcherMultiCallWithNonce } from "../utils/sign"; import { isConfigSetOnEVMx, isConfigSetOnSocket } from "../utils"; @@ -113,8 +114,11 @@ export const updateConfigEVMx = async () => { for (const plugContract of plugs) { const appGatewayId = getAppGatewayId(plugContract, addresses); - const switchboard = addr[Contracts.FastSwitchboard]; - checkIfAddressExists(switchboard, "Switchboard"); + const switchboardBytes32Hex = toBytes32FormatHexString( + addr[Contracts.FastSwitchboard] + ); + const plugBytes32Hex = toBytes32FormatHexString(addr[plugContract]); + // checkIfAddressExists(switchboard, "Switchboard"); checkIfAppGatewayIdExists(appGatewayId, "AppGatewayId"); if (!addr[plugContract]) { @@ -126,9 +130,9 @@ export const updateConfigEVMx = async () => { await isConfigSetOnEVMx( configurationsContract, chain, - addr[plugContract], + plugBytes32Hex, appGatewayId, - switchboard + switchboardBytes32Hex ) ) { console.log(`Config already set on ${chain} for ${plugContract}`); @@ -137,9 +141,9 @@ export const updateConfigEVMx = async () => { appConfigs.push({ plugConfig: { appGatewayId: appGatewayId, - switchboard: switchboard, + switchboard: switchboardBytes32Hex, }, - plug: addr[plugContract], + plug: plugBytes32Hex, chainSlug: chain, }); } diff --git a/hardhat-scripts/utils/address.ts b/hardhat-scripts/utils/address.ts index 4ac48774..254facbb 100644 --- a/hardhat-scripts/utils/address.ts +++ b/hardhat-scripts/utils/address.ts @@ -33,3 +33,29 @@ export const checkIfAddressExists = (address: string, name: string) => { } return address; }; + +// TODO: move this to socket-common +export function toBytes32FormatHexString(hexString: string): string { + // this means that the string is already in bytes32 format with or without 0x prefix + if (hexString.length == 64 || hexString.length == 66) { + return hexString; + } + // Remove the '0x' prefix from the input string if it's present + const cleanedHexString = hexString.startsWith("0x") + ? hexString.slice(2) + : hexString; + + const buffer = Buffer.alloc(32); + buffer.write(cleanedHexString, 32 - cleanedHexString.length / 2, "hex"); // each hex char is 2 bytes + + return "0x" + buffer.toString("hex"); +} + +export function toBytes32Format(hexString: string): number[] { + const hex32Format = toBytes32FormatHexString(hexString); + const cleanedHex32String = hex32Format.startsWith("0x") + ? hex32Format.slice(2) + : hex32Format; + + return Array.from(Buffer.from(cleanedHex32String, "hex")); +} diff --git a/hardhat-scripts/utils/appConfig.ts b/hardhat-scripts/utils/appConfig.ts index 40387b76..0172655f 100644 --- a/hardhat-scripts/utils/appConfig.ts +++ b/hardhat-scripts/utils/appConfig.ts @@ -1,4 +1,5 @@ import { Contract } from "ethers"; +import { toBytes32Format } from "./address"; export const isConfigSetOnSocket = async ( plug: Contract, @@ -21,7 +22,10 @@ export const isConfigSetOnEVMx = async ( appGatewayId: string, switchboard: string ) => { - const plugConfigRegistered = await watcher.getPlugConfigs(chain, plug); + const plugConfigRegistered = await watcher.getPlugConfigs( + chain, + toBytes32Format(plug) + ); return ( plugConfigRegistered[0].toLowerCase() === appGatewayId?.toLowerCase() && plugConfigRegistered[1].toLowerCase() === switchboard.toLowerCase() diff --git a/hardhat-scripts/verify/verify.ts b/hardhat-scripts/verify/verify.ts index 9f6871ba..eaec585c 100644 --- a/hardhat-scripts/verify/verify.ts +++ b/hardhat-scripts/verify/verify.ts @@ -67,7 +67,7 @@ export const main = async () => { } await storeUnVerifiedParams(unverifiedChainParams, chain, mode); - await new Promise(resolve => setTimeout(resolve, 1000)); + await new Promise((resolve) => setTimeout(resolve, 1000)); retryCount++; if (unverifiedChainParams.length == 0) break; } diff --git a/package.json b/package.json index c48d6209..0dfa34ef 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "publishConfig": { "access": "public" }, - "version": "1.1.22", + "version": "1.1.32", "description": "socket protocol", "scripts": { "build": "yarn abi && tsc --project lib.tsconfig.json", 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/src/cctp.ts b/src/cctp.ts new file mode 100644 index 00000000..c0436393 --- /dev/null +++ b/src/cctp.ts @@ -0,0 +1,34 @@ +import { ChainSlug } from "./chain-enums"; + +// CCTP +export const MESSAGE_TRANSMITTER: { + [chainSlug: number]: string; +} = { + [ChainSlug.SEPOLIA]: "0x7865fAfC2db2093669d92c0F33AeEF291086BEFD", + [ChainSlug.OPTIMISM_SEPOLIA]: "0x7865fAfC2db2093669d92c0F33AeEF291086BEFD", + [ChainSlug.ARBITRUM_SEPOLIA]: "0xaCF1ceeF35caAc005e15888dDb8A3515C41B4872", + [ChainSlug.BASE_SEPOLIA]: "0x7865fAfC2db2093669d92c0F33AeEF291086BEFD", + [ChainSlug.POLYGON_AMOY]: "0x7865fAfC2db2093669d92c0F33AeEF291086BEFD", + [ChainSlug.MAINNET]: "0x0a992d191DEeC32aFe36203Ad87D7d289a738F81", + [ChainSlug.AVALANCHE]: "0x8186359aF5F57FbB40c6b14A588d2A59C0C29880", + [ChainSlug.OPTIMISM]: "0x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8", + [ChainSlug.ARBITRUM]: "0xC30362313FBBA5cf9163F0bb16a0e01f01A896ca", + [ChainSlug.BASE]: "0xAD09780d193884d503182aD4588450C416D6F9D4", + [ChainSlug.POLYGON_MAINNET]: "0xF3be9355363857F3e001be68856A2f96b4C39Ba9", +}; + +export const CCTP_DOMAINS: { + [chainSlug: number]: number; +} = { + [ChainSlug.SEPOLIA]: 0, + [ChainSlug.OPTIMISM_SEPOLIA]: 2, + [ChainSlug.ARBITRUM_SEPOLIA]: 3, + [ChainSlug.BASE_SEPOLIA]: 6, + [ChainSlug.POLYGON_AMOY]: 7, + [ChainSlug.MAINNET]: 0, + [ChainSlug.AVALANCHE]: 1, + [ChainSlug.OPTIMISM]: 2, + [ChainSlug.ARBITRUM]: 3, + [ChainSlug.BASE]: 6, + [ChainSlug.POLYGON_MAINNET]: 7, +}; diff --git a/src/chain-enums/chainId.ts b/src/chain-enums/chainId.ts index 4c7cf31c..69a11947 100644 --- a/src/chain-enums/chainId.ts +++ b/src/chain-enums/chainId.ts @@ -57,4 +57,6 @@ export enum ChainId { ZERO_SEPOLIA = 4457845, INTEROP_ALPHA_0 = 420120000, INTEROP_ALPHA_1 = 420120001, + SOLANA_MAINNET = 10000001, + SOLANA_DEVNET = 10000002, } diff --git a/src/chain-enums/chainSlug.ts b/src/chain-enums/chainSlug.ts index 6dd18494..d62533f8 100644 --- a/src/chain-enums/chainSlug.ts +++ b/src/chain-enums/chainSlug.ts @@ -59,4 +59,6 @@ export enum ChainSlug { ZERO_SEPOLIA = ChainId.ZERO_SEPOLIA, INTEROP_ALPHA_0 = ChainId.INTEROP_ALPHA_0, INTEROP_ALPHA_1 = ChainId.INTEROP_ALPHA_1, + SOLANA_MAINNET = ChainId.SOLANA_MAINNET, + SOLANA_DEVNET = ChainId.SOLANA_DEVNET, } diff --git a/src/enums.ts b/src/enums.ts index f54d3ba8..a9bcceac 100644 --- a/src/enums.ts +++ b/src/enums.ts @@ -24,10 +24,15 @@ export enum Events { PromiseNotResolved = "PromiseNotResolved", MarkedRevert = "MarkedRevert", + // Configurations + PlugAdded = "PlugAdded", + // RequestHandler RequestSubmitted = "RequestSubmitted", RequestCancelled = "RequestCancelled", FeesIncreased = "FeesIncreased", + RequestSettled = "RequestSettled", + RequestCompletedWithErrors = "RequestCompletedWithErrors", // WritePrecompile WriteProofRequested = "WriteProofRequested", @@ -50,6 +55,7 @@ export enum Contracts { FeesPlug = "FeesPlug", ContractFactoryPlug = "ContractFactoryPlug", FastSwitchboard = "FastSwitchboard", + CCTPSwitchboard = "CCTPSwitchboard", SocketBatcher = "SocketBatcher", SocketFeeManager = "SocketFeeManager", AddressResolver = "AddressResolver", diff --git a/src/events.ts b/src/events.ts index 1d57f1aa..c70e5ffb 100644 --- a/src/events.ts +++ b/src/events.ts @@ -21,8 +21,12 @@ export const requestHandlerEvents = [ Events.RequestSubmitted, Events.FeesIncreased, Events.RequestCancelled, + Events.RequestSettled, + Events.RequestCompletedWithErrors, ]; +export const configurationsEvents = [Events.PlugAdded]; + export const writePrecompileEvents = [ Events.WriteProofRequested, Events.WriteProofUploaded, diff --git a/src/index.ts b/src/index.ts index 39a65132..e58e42d5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,3 +5,4 @@ export * from "./finality"; export * from "./types"; export * from "./constants"; export * from "./signer"; +export * from "./cctp"; diff --git a/src/types.ts b/src/types.ts index 1a047bcc..ba32e046 100644 --- a/src/types.ts +++ b/src/types.ts @@ -19,6 +19,7 @@ export type ChainAddressesObj = { Socket: string; SocketBatcher: string; FastSwitchboard: string; + CCTPSwitchboard: string; ContractFactoryPlug: string; SocketFeesManager?: string; FeesPlug?: string; diff --git a/test/FeesTest.t.sol b/test/FeesTest.t.sol index c60bd554..c94d0681 100644 --- a/test/FeesTest.t.sol +++ b/test/FeesTest.t.sol @@ -100,16 +100,13 @@ contract FeesTest is AppGatewayBaseSetup { ); hoax(watcherEOA); - feesManager.setFeesPlug(arbChainSlug, address(0)); + feesManager.setFeesPlug(arbChainSlug, bytes32(0)); AppGatewayConfig[] memory configs = new AppGatewayConfig[](1); configs[0] = AppGatewayConfig({ chainSlug: arbChainSlug, - plug: address(arbConfig.feesPlug), - plugConfig: PlugConfig({ - appGatewayId: encodeAppGatewayId(address(0)), - switchboard: address(0) - }) + plug: toBytes32Format(address(arbConfig.feesPlug)), + plugConfig: PlugConfigGeneric({appGatewayId: bytes32(0), switchboard: bytes32(0)}) }); watcherMultiCall( address(configurations), @@ -149,22 +146,22 @@ contract FeesTest is AppGatewayBaseSetup { arbConfig.feesPlug.grantRole(RESCUE_ROLE, address(socketOwner)); arbConfig.feesPlug.whitelistToken(address(arbConfig.testUSDC)); arbConfig.feesPlug.connectSocket( - encodeAppGatewayId(address(feesManager)), + toBytes32Format(address(feesManager)), address(arbConfig.socket), address(arbConfig.switchboard) ); vm.stopPrank(); hoax(watcherEOA); - feesManager.setFeesPlug(arbChainSlug, address(arbConfig.feesPlug)); + feesManager.setFeesPlug(arbChainSlug, toBytes32Format(address(arbConfig.feesPlug))); AppGatewayConfig[] memory configs = new AppGatewayConfig[](1); configs[0] = AppGatewayConfig({ chainSlug: arbChainSlug, - plug: address(arbConfig.feesPlug), - plugConfig: PlugConfig({ - appGatewayId: encodeAppGatewayId(address(feesManager)), - switchboard: address(arbConfig.switchboard) + plug: toBytes32Format(address(arbConfig.feesPlug)), + plugConfig: PlugConfigGeneric({ + appGatewayId: toBytes32Format(address(feesManager)), + switchboard: toBytes32Format(address(arbConfig.switchboard)) }) }); watcherMultiCall( diff --git a/test/ProxyMigration.t.sol b/test/ProxyMigration.t.sol index ad35df2a..d05b2897 100644 --- a/test/ProxyMigration.t.sol +++ b/test/ProxyMigration.t.sol @@ -169,7 +169,10 @@ contract MigrationTest is ProxyStorageAssertions { assertEq(newImplAddr, address(newImpl), "New implementation not set correctly"); // Deploy a new forwarder and verify it uses the correct beacon - address newForwarder = asyncDeployer.getOrDeployForwarderContract(address(0x123), 1); + address newForwarder = asyncDeployer.getOrDeployForwarderContract( + toBytes32Format(address(0x123)), + 1 + ); address beacon = getBeacon(newForwarder); assertEq( beacon, diff --git a/test/ProxyStorage.t.sol b/test/ProxyStorage.t.sol index 284b84cc..69720ca9 100644 --- a/test/ProxyStorage.t.sol +++ b/test/ProxyStorage.t.sol @@ -41,7 +41,7 @@ contract ProxyStorageAssertions is AppGatewayBaseSetup { // last hoax(watcherEOA); - feesManager.setFeesPlug(evmxSlug, address(addressResolver)); + feesManager.setFeesPlug(evmxSlug, toBytes32Format(address(addressResolver))); bytes32 mappingSlot = keccak256(abi.encode(uint256(evmxSlug), uint256(57))); slotValue = vm.load(address(feesManager), mappingSlot); assertEq( @@ -211,12 +211,21 @@ contract ProxyStorageAssertions is AppGatewayBaseSetup { } function assertForwarderSlot() internal { - address forwarder = asyncDeployer.getOrDeployForwarderContract(address(this), evmxSlug); + bytes32 chainContractAddress = toBytes32Format(address(this)); + address forwarder = asyncDeployer.getOrDeployForwarderContract( + chainContractAddress, + evmxSlug + ); + + console.log("forwarder: ", forwarder); // first bytes32 slotValue = vm.load(address(forwarder), bytes32(uint256(FIRST_SLOT))); assertEq(uint32(uint256(slotValue)), evmxSlug); + slotValue = vm.load(address(forwarder), bytes32(uint256(FIRST_SLOT + 1))); + assertEq(slotValue, IForwarder(forwarder).getOnChainAddress()); + assertAddressResolverUtilSlot(101, address(forwarder)); } diff --git a/test/SetupTest.t.sol b/test/SetupTest.t.sol index af8ab7f9..4f761381 100644 --- a/test/SetupTest.t.sol +++ b/test/SetupTest.t.sol @@ -169,34 +169,34 @@ contract DeploySetup is SetupStore { AppGatewayConfig[] memory configs = new AppGatewayConfig[](4); configs[0] = AppGatewayConfig({ chainSlug: arbChainSlug, - plug: address(arbConfig.feesPlug), - plugConfig: PlugConfig({ - appGatewayId: encodeAppGatewayId(address(feesManager)), - switchboard: address(arbConfig.switchboard) + plug: toBytes32Format(address(arbConfig.feesPlug)), + plugConfig: PlugConfigGeneric({ + appGatewayId: toBytes32Format(address(feesManager)), + switchboard: toBytes32Format(address(arbConfig.switchboard)) }) }); configs[1] = AppGatewayConfig({ chainSlug: optChainSlug, - plug: address(optConfig.feesPlug), - plugConfig: PlugConfig({ - appGatewayId: encodeAppGatewayId(address(feesManager)), - switchboard: address(optConfig.switchboard) + plug: toBytes32Format(address(optConfig.feesPlug)), + plugConfig: PlugConfigGeneric({ + appGatewayId: toBytes32Format(address(feesManager)), + switchboard: toBytes32Format(address(optConfig.switchboard)) }) }); configs[2] = AppGatewayConfig({ chainSlug: arbChainSlug, - plug: address(arbConfig.contractFactoryPlug), - plugConfig: PlugConfig({ - appGatewayId: encodeAppGatewayId(address(writePrecompile)), - switchboard: address(arbConfig.switchboard) + plug: toBytes32Format(address(arbConfig.contractFactoryPlug)), + plugConfig: PlugConfigGeneric({ + appGatewayId: toBytes32Format(address(writePrecompile)), + switchboard: toBytes32Format(address(arbConfig.switchboard)) }) }); configs[3] = AppGatewayConfig({ chainSlug: optChainSlug, - plug: address(optConfig.contractFactoryPlug), - plugConfig: PlugConfig({ - appGatewayId: encodeAppGatewayId(address(writePrecompile)), - switchboard: address(optConfig.switchboard) + plug: toBytes32Format(address(optConfig.contractFactoryPlug)), + plugConfig: PlugConfigGeneric({ + appGatewayId: toBytes32Format(address(writePrecompile)), + switchboard: toBytes32Format(address(optConfig.switchboard)) }) }); @@ -244,14 +244,14 @@ contract DeploySetup is SetupStore { feesPlug.grantRole(RESCUE_ROLE, address(socketOwner)); feesPlug.whitelistToken(address(socketConfig.testUSDC)); feesPlug.connectSocket( - encodeAppGatewayId(address(feesManager)), + toBytes32Format(address(feesManager)), address(socket), address(switchboard) ); contractFactoryPlug.grantRole(RESCUE_ROLE, address(socketOwner)); contractFactoryPlug.connectSocket( - encodeAppGatewayId(address(writePrecompile)), + toBytes32Format(address(writePrecompile)), address(socket), address(switchboard) ); @@ -259,15 +259,18 @@ contract DeploySetup is SetupStore { vm.stopPrank(); vm.startPrank(watcherEOA); - configurations.setSocket(chainSlug_, address(socket)); - configurations.setSwitchboard(chainSlug_, FAST, address(switchboard)); + configurations.setSocket(chainSlug_, toBytes32Format(address(socket))); + configurations.setSwitchboard(chainSlug_, FAST, toBytes32Format(address(switchboard))); // plugs - feesManager.setFeesPlug(chainSlug_, address(feesPlug)); + feesManager.setFeesPlug(chainSlug_, toBytes32Format(address(feesPlug))); // precompiles writePrecompile.updateChainMaxMsgValueLimits(chainSlug_, maxMsgValueLimit); - writePrecompile.setContractFactoryPlugs(chainSlug_, address(contractFactoryPlug)); + writePrecompile.setContractFactoryPlugs( + chainSlug_, + toBytes32Format(address(contractFactoryPlug)) + ); vm.stopPrank(); } @@ -770,7 +773,8 @@ contract WatcherSetup is AuctionSetup { ); bytes memory returnData; - (success, returnData) = transaction.target.call(transaction.payload); + address target = fromBytes32Format(transaction.target); + (success, returnData) = target.call(transaction.payload); promiseReturnData = PromiseReturnData({ exceededMaxCopy: false, payloadId: payloadParams.payloadId, @@ -785,7 +789,7 @@ contract WatcherSetup is AuctionSetup { ( uint32 chainSlug, - address switchboard, + bytes32 switchboard, bytes32 digest, DigestParams memory digestParams ) = _validateAndGetDigest(payloadParams); @@ -806,11 +810,12 @@ contract WatcherSetup is AuctionSetup { function _uploadProof( bytes32 payloadId, bytes32 digest, - address switchboard, + bytes32 switchboard, uint32 chainSlug ) internal returns (bytes memory proof) { proof = _createSignature( - keccak256(abi.encode(address(switchboard), chainSlug, digest)), + // create sigDigest which get signed by watcher + keccak256(abi.encodePacked(switchboard, chainSlug, digest)), watcherPrivateKey ); @@ -829,7 +834,7 @@ contract WatcherSetup is AuctionSetup { internal returns ( uint32 chainSlug, - address switchboard, + bytes32 switchboard, bytes32 digest, DigestParams memory digestParams ) @@ -840,10 +845,10 @@ contract WatcherSetup is AuctionSetup { , uint256 gasLimit, uint256 value, - address switchboard_ + bytes32 switchboard_ ) = abi.decode( payloadParams.precompileData, - (address, Transaction, WriteFinality, uint256, uint256, address) + (address, Transaction, WriteFinality, uint256, uint256, bytes32) ); chainSlug = transaction.chainSlug; @@ -854,7 +859,7 @@ contract WatcherSetup is AuctionSetup { payloadParams.batchCount ); digestParams = DigestParams( - address(getSocketConfig(transaction.chainSlug).socket), + toBytes32Format(address(getSocketConfig(transaction.chainSlug).socket)), transmitterEOA, payloadParams.payloadId, payloadParams.deadline, @@ -863,7 +868,7 @@ contract WatcherSetup is AuctionSetup { value, transaction.payload, transaction.target, - encodeAppGatewayId(appGateway), + toBytes32Format(appGateway), prevBatchDigestHash, bytes("") ); @@ -874,12 +879,13 @@ contract WatcherSetup is AuctionSetup { function _executeWrite( uint32 chainSlug, - address switchboard, + bytes32 switchboard, bytes32 digest, DigestParams memory digestParams, PayloadParams memory payloadParams, bytes memory watcherProof ) internal returns (bool success, PromiseReturnData memory promiseReturnData) { + // this is a signature for the socket batcher (only used for EVM) bytes memory transmitterSig = _createSignature( keccak256( abi.encode(address(getSocketConfig(chainSlug).socket), payloadParams.payloadId) @@ -894,14 +900,14 @@ contract WatcherSetup is AuctionSetup { gasLimit: digestParams.gasLimit, value: digestParams.value, payload: digestParams.payload, - target: digestParams.target, + target: fromBytes32Format(digestParams.target), requestCount: payloadParams.requestCount, batchCount: payloadParams.batchCount, payloadCount: payloadParams.payloadCount, prevBatchDigestHash: digestParams.prevBatchDigestHash, extraData: digestParams.extraData }), - switchboard, + fromBytes32Format(switchboard), digest, watcherProof, transmitterSig, @@ -945,14 +951,14 @@ contract WatcherSetup is AuctionSetup { 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_); configs[i] = AppGatewayConfig({ plug: plug, chainSlug: chainSlug_, - plugConfig: PlugConfig({ - appGatewayId: encodeAppGatewayId(address(appGateway_)), - switchboard: address(socketConfig.switchboard) + plugConfig: PlugConfigGeneric({ + appGatewayId: toBytes32Format(address(appGateway_)), + switchboard: toBytes32Format(address(socketConfig.switchboard)) }) }); } @@ -968,10 +974,10 @@ contract AppGatewayBaseSetup is WatcherSetup { uint32 chainSlug_, bytes32 contractId_, IAppGateway appGateway_ - ) internal view returns (address, address) { - address app = appGateway_.getOnChainAddress(contractId_, chainSlug_); + ) internal view returns (bytes32, address) { + bytes32 onChainContract = appGateway_.getOnChainAddress(contractId_, chainSlug_); address forwarder = appGateway_.forwarderAddresses(contractId_, chainSlug_); - return (app, forwarder); + return (onChainContract, forwarder); } // todo: add checks for request params and payload params created to match what is expected diff --git a/test/SocketFeeManager.t.sol b/test/SocketFeeManager.t.sol index 8809d11e..1fc6ce21 100644 --- a/test/SocketFeeManager.t.sol +++ b/test/SocketFeeManager.t.sol @@ -25,7 +25,7 @@ contract SocketFeeManagerTest is AppGatewayBaseSetup { counter = new Counter(); mockSwitchboard.registerSwitchboard(); - counter.initSocket(encodeAppGatewayId(gateway), address(socket), address(mockSwitchboard)); + counter.initSocket(toBytes32Format(gateway), address(socket), address(mockSwitchboard)); vm.prank(owner); socket.grantRole(GOVERNANCE_ROLE, address(owner)); diff --git a/test/TriggerTest.t.sol b/test/TriggerTest.t.sol index 4ed4f820..097c3ff0 100644 --- a/test/TriggerTest.t.sol +++ b/test/TriggerTest.t.sol @@ -13,8 +13,8 @@ contract TriggerTest is AppGatewayBaseSetup { event AppGatewayCallRequested( bytes32 triggerId, bytes32 appGatewayId, - address switchboard, - address plug, + bytes32 switchboard, + bytes32 plug, bytes overrides, bytes payload ); @@ -35,11 +35,12 @@ contract TriggerTest is AppGatewayBaseSetup { gateway.deployContracts(arbChainSlug); executeDeploy(gateway, arbChainSlug, contractIds); - (address counterAddress, ) = getOnChainAndForwarderAddresses( + (bytes32 counterBytes32, ) = getOnChainAndForwarderAddresses( arbChainSlug, counterId, gateway ); + address counterAddress = fromBytes32Format(counterBytes32); counter = Counter(counterAddress); gateway.setIsValidPlug(arbChainSlug, counterId); } @@ -59,9 +60,9 @@ contract TriggerTest is AppGatewayBaseSetup { vm.expectEmit(true, true, true, true); emit AppGatewayCallRequested( triggerId, - encodeAppGatewayId(address(gateway)), - address(arbConfig.switchboard), - address(counter), + toBytes32Format(address(gateway)), + toBytes32Format(address(arbConfig.switchboard)), + toBytes32Format(address(counter)), bytes(""), payload ); @@ -71,8 +72,8 @@ contract TriggerTest is AppGatewayBaseSetup { params[0] = TriggerParams({ triggerId: triggerId, chainSlug: arbChainSlug, - appGatewayId: encodeAppGatewayId(address(gateway)), - plug: address(counter), + appGatewayId: toBytes32Format(address(gateway)), + plug: toBytes32Format(address(counter)), payload: payload, overrides: bytes("") }); diff --git a/test/apps/Counter.t.sol b/test/apps/Counter.t.sol index e0949f07..3472fe0b 100644 --- a/test/apps/Counter.t.sol +++ b/test/apps/Counter.t.sol @@ -31,7 +31,7 @@ contract CounterTest is AppGatewayBaseSetup { function testCounterDeployment() external { deployCounterApp(arbChainSlug); - (address onChain, address forwarder) = getOnChainAndForwarderAddresses( + (bytes32 onChain, address forwarder) = getOnChainAndForwarderAddresses( arbChainSlug, counterId, counterGateway @@ -57,11 +57,12 @@ contract CounterTest is AppGatewayBaseSetup { function testCounterIncrement() external { deployCounterApp(arbChainSlug); - (address arbCounter, address arbCounterForwarder) = getOnChainAndForwarderAddresses( + (bytes32 arbCounterBytes32, address arbCounterForwarder) = getOnChainAndForwarderAddresses( arbChainSlug, counterId, counterGateway ); + address arbCounter = fromBytes32Format(arbCounterBytes32); uint256 arbCounterBefore = Counter(arbCounter).counter(); @@ -77,16 +78,18 @@ contract CounterTest is AppGatewayBaseSetup { deployCounterApp(arbChainSlug); deployCounterApp(optChainSlug); - (address arbCounter, address arbCounterForwarder) = getOnChainAndForwarderAddresses( + (bytes32 arbCounterBytes32, address arbCounterForwarder) = getOnChainAndForwarderAddresses( arbChainSlug, counterId, counterGateway ); - (address optCounter, address optCounterForwarder) = getOnChainAndForwarderAddresses( + address arbCounter = fromBytes32Format(arbCounterBytes32); + (bytes32 optCounterBytes32, address optCounterForwarder) = getOnChainAndForwarderAddresses( optChainSlug, counterId, counterGateway ); + address optCounter = fromBytes32Format(optCounterBytes32); uint256 arbCounterBefore = Counter(arbCounter).counter(); uint256 optCounterBefore = Counter(optCounter).counter(); diff --git a/test/apps/ParallelCounter.t.sol b/test/apps/ParallelCounter.t.sol index fda14b52..51763bb3 100644 --- a/test/apps/ParallelCounter.t.sol +++ b/test/apps/ParallelCounter.t.sol @@ -37,23 +37,25 @@ contract ParallelCounterTest is AppGatewayBaseSetup { chainSlugs[1] = optChainSlug; deployCounterApp(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 @@ -106,11 +108,12 @@ contract ParallelCounterTest is AppGatewayBaseSetup { chainSlugs[0] = arbChainSlug; deployCounterApp(chainSlugs); - (address arbCounter, address arbCounterForwarder) = getOnChainAndForwarderAddresses( + (bytes32 arbCounterBytes32, address arbCounterForwarder) = getOnChainAndForwarderAddresses( arbChainSlug, counterId1, parallelCounterGateway ); + address arbCounter = fromBytes32Format(arbCounterBytes32); uint256 arbCounterBefore = Counter(arbCounter).counter(); @@ -128,16 +131,19 @@ contract ParallelCounterTest is AppGatewayBaseSetup { chainSlugs[1] = optChainSlug; deployCounterApp(chainSlugs); - (address arbCounter, address arbCounterForwarder) = getOnChainAndForwarderAddresses( + (bytes32 arbCounterBytes32, address arbCounterForwarder) = getOnChainAndForwarderAddresses( arbChainSlug, counterId1, parallelCounterGateway ); - (address optCounter, address optCounterForwarder) = getOnChainAndForwarderAddresses( + address arbCounter = fromBytes32Format(arbCounterBytes32); + + (bytes32 optCounterBytes32, address optCounterForwarder) = getOnChainAndForwarderAddresses( optChainSlug, counterId1, parallelCounterGateway ); + address optCounter = fromBytes32Format(optCounterBytes32); uint256 arbCounterBefore = Counter(arbCounter).counter(); uint256 optCounterBefore = Counter(optCounter).counter(); diff --git a/test/apps/SuperToken.t.sol b/test/apps/SuperToken.t.sol index 0314b353..18a9ea24 100644 --- a/test/apps/SuperToken.t.sol +++ b/test/apps/SuperToken.t.sol @@ -99,11 +99,12 @@ contract SuperTokenTest is AppGatewayBaseSetup { function testContractDeployment() public { deploySuperToken(arbChainSlug); - (address onChain, address forwarder) = getOnChainAndForwarderAddresses( + (bytes32 onChainBytes32, address forwarder) = getOnChainAndForwarderAddresses( arbChainSlug, appContracts.superToken, IAppGateway(appContracts.superTokenApp) ); + address onChain = fromBytes32Format(onChainBytes32); assertEq( SuperToken(onChain).name(), @@ -119,7 +120,7 @@ contract SuperTokenTest is AppGatewayBaseSetup { assertEq( IForwarder(forwarder).getOnChainAddress(), - onChain, + onChainBytes32, "Forwarder SuperToken onChainAddress should be correct" ); assertEq(SuperToken(onChain).owner(), owner, "SuperToken owner should be correct"); @@ -137,17 +138,19 @@ contract SuperTokenTest is AppGatewayBaseSetup { deploySuperToken(arbChainSlug); deploySuperToken(optChainSlug); - (address onChainArb, address forwarderArb) = getOnChainAndForwarderAddresses( + (bytes32 onChainArbBytes32, address forwarderArb) = getOnChainAndForwarderAddresses( arbChainSlug, appContracts.superToken, IAppGateway(appContracts.superTokenApp) ); + address onChainArb = fromBytes32Format(onChainArbBytes32); - (address onChainOpt, address forwarderOpt) = getOnChainAndForwarderAddresses( + (bytes32 onChainOptBytes32, address forwarderOpt) = getOnChainAndForwarderAddresses( optChainSlug, appContracts.superToken, IAppGateway(appContracts.superTokenApp) ); + address onChainOpt = fromBytes32Format(onChainOptBytes32); uint256 arbBalanceBefore = SuperToken(onChainArb).balanceOf(owner); uint256 optBalanceBefore = SuperToken(onChainOpt).balanceOf(owner); diff --git a/test/mock/MockSocket.sol b/test/mock/MockSocket.sol index fbe737a8..adfcc841 100644 --- a/test/mock/MockSocket.sol +++ b/test/mock/MockSocket.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.21; import "../../contracts/utils/common/Errors.sol"; import "../../contracts/protocol/interfaces/ISocket.sol"; import "../../contracts/protocol/interfaces/ISwitchboard.sol"; +import {toBytes32Format} from "../../contracts/utils/common/Converters.sol"; /** * @title SocketDst @@ -14,7 +15,7 @@ import "../../contracts/protocol/interfaces/ISwitchboard.sol"; * It also includes functions for payload execution and verification */ contract MockSocket is ISocket { - struct PlugConfig { + struct PlugConfigEvm { // address of the sibling plug on the remote chain bytes32 appGatewayId; // switchboard instance for the plug connection @@ -22,12 +23,12 @@ contract MockSocket is ISocket { } // plug => (appGateway, switchboard__) - mapping(address => PlugConfig) internal _plugConfigs; + mapping(address => PlugConfigEvm) internal _plugConfigs; function getPlugConfig( address plugAddress_ ) external view returns (bytes32 appGatewayId, address switchboard__) { - PlugConfig memory _plugConfig = _plugConfigs[plugAddress_]; + PlugConfigEvm memory _plugConfig = _plugConfigs[plugAddress_]; return (_plugConfig.appGatewayId, address(_plugConfig.switchboard__)); } @@ -91,14 +92,14 @@ contract MockSocket is ISocket { bytes calldata payload, bytes calldata overrides ) external returns (bytes32 triggerId) { - PlugConfig memory plugConfig = _plugConfigs[msg.sender]; + PlugConfigEvm memory plugConfig = _plugConfigs[msg.sender]; // creates a unique ID for the message triggerId = _encodeTriggerId(plugConfig.appGatewayId); emit AppGatewayCallRequested( triggerId, plugConfig.appGatewayId, - address(plugConfig.switchboard__), - msg.sender, + toBytes32Format(address(plugConfig.switchboard__)), + toBytes32Format(msg.sender), overrides, payload ); diff --git a/test/mock/MockWatcherPrecompile.sol b/test/mock/MockWatcherPrecompile.sol index 7ee24975..6d66417c 100644 --- a/test/mock/MockWatcherPrecompile.sol +++ b/test/mock/MockWatcherPrecompile.sol @@ -56,7 +56,7 @@ contract MockWatcherPrecompile is Trigger { function setIsValidPlug( bool isValid_, uint32 chainSlug_, - address onchainAddress_ + bytes32 onchainAddress_ ) external override {} function isWatcher(address account_) external view override returns (bool) {}