From 35565dda21c0c94dae649bf95b857fe8205f12f0 Mon Sep 17 00:00:00 2001 From: Ryan Collins Date: Wed, 24 Sep 2025 13:05:57 -0400 Subject: [PATCH 1/7] fix: match destinationSettler to counterpart --- contracts/src/7683/T1ERC7683.sol | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contracts/src/7683/T1ERC7683.sol b/contracts/src/7683/T1ERC7683.sol index 88284ed3..66d78c12 100644 --- a/contracts/src/7683/T1ERC7683.sol +++ b/contracts/src/7683/T1ERC7683.sol @@ -27,6 +27,8 @@ import { IT1XChainReader } from "../libraries/xChain/IT1XChainReader.sol"; contract T1ERC7683 is IT1ERC7683, T1Permit2, AccessControlUpgradeable, EIP712 { using SafeERC20 for IERC20; + error InvalidDestinationSettler(bytes32 provided, bytes32 expected); + /// @notice Role for pausing/unpausing open operations bytes32 public constant OPEN_PAUSER_ROLE = keccak256("OPEN_PAUSER_ROLE"); /// @notice Role for pausing/unpausing settlement operations @@ -246,6 +248,12 @@ contract T1ERC7683 is IT1ERC7683, T1Permit2, AccessControlUpgradeable, EIP712 { if (orderData.originDomain != localDomain) revert InvalidOriginDomain(orderData.originDomain); + // Ensure destinationSettler matches counterpart + bytes32 expectedSettler = TypeCasts.addressToBytes32(counterpart); + if (orderData.destinationSettler != expectedSettler) { + revert InvalidDestinationSettler(orderData.destinationSettler, expectedSettler); + } + // enforce fillDeadline into orderData orderData.fillDeadline = _fillDeadline; // enforce sender into orderData From 75d144b175adb93cdd19b6552321506c99c57a83 Mon Sep 17 00:00:00 2001 From: Ryan Collins Date: Thu, 25 Sep 2025 09:34:11 -0400 Subject: [PATCH 2/7] fix: remove comment --- contracts/src/7683/T1ERC7683.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/src/7683/T1ERC7683.sol b/contracts/src/7683/T1ERC7683.sol index 66d78c12..40b0a81d 100644 --- a/contracts/src/7683/T1ERC7683.sol +++ b/contracts/src/7683/T1ERC7683.sol @@ -248,7 +248,6 @@ contract T1ERC7683 is IT1ERC7683, T1Permit2, AccessControlUpgradeable, EIP712 { if (orderData.originDomain != localDomain) revert InvalidOriginDomain(orderData.originDomain); - // Ensure destinationSettler matches counterpart bytes32 expectedSettler = TypeCasts.addressToBytes32(counterpart); if (orderData.destinationSettler != expectedSettler) { revert InvalidDestinationSettler(orderData.destinationSettler, expectedSettler); From 543ddf1e87341d0a4a828edd799a8abebb169424 Mon Sep 17 00:00:00 2001 From: Ryan Collins Date: Thu, 25 Sep 2025 10:20:18 -0400 Subject: [PATCH 3/7] fix: orderId calculation due to divergent orderData fields --- contracts/src/7683/T1ERC7683.sol | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/contracts/src/7683/T1ERC7683.sol b/contracts/src/7683/T1ERC7683.sol index 40b0a81d..07b20c65 100644 --- a/contracts/src/7683/T1ERC7683.sol +++ b/contracts/src/7683/T1ERC7683.sol @@ -27,8 +27,15 @@ import { IT1XChainReader } from "../libraries/xChain/IT1XChainReader.sol"; contract T1ERC7683 is IT1ERC7683, T1Permit2, AccessControlUpgradeable, EIP712 { using SafeERC20 for IERC20; + /// @dev Thrown when the destinationSettler does not match the counterpart error InvalidDestinationSettler(bytes32 provided, bytes32 expected); + /// @dev Thrown when the input fill deadline does not match the stored fill deadline + error InvalidFillDeadline(uint32 provided, uint32 expected); + + /// @dev Thrown when the sender is unexpected + error InvalidSender(bytes32 provided, bytes32 expected); + /// @notice Role for pausing/unpausing open operations bytes32 public constant OPEN_PAUSER_ROLE = keccak256("OPEN_PAUSER_ROLE"); /// @notice Role for pausing/unpausing settlement operations @@ -253,10 +260,18 @@ contract T1ERC7683 is IT1ERC7683, T1Permit2, AccessControlUpgradeable, EIP712 { revert InvalidDestinationSettler(orderData.destinationSettler, expectedSettler); } - // enforce fillDeadline into orderData - orderData.fillDeadline = _fillDeadline; - // enforce sender into orderData - orderData.sender = TypeCasts.addressToBytes32(_sender); + if (orderData.fillDeadline != _fillDeadline) { + revert InvalidFillDeadline(orderData.fillDeadline, _fillDeadline); + } + + bytes32 expectedSender = TypeCasts.addressToBytes32(_sender); + if (orderData.sender != expectedSender) { + revert InvalidSender(orderData.sender, expectedSender); + } + + // No need to overwrite fields since they are validated to be correct + // orderData.fillDeadline = _fillDeadline; // Removed + // orderData.sender = TypeCasts.addressToBytes32(_sender); // Removed // this can be used by the filler to approve the tokens to be spent on destination Output[] memory maxSpent = new Output[](1); @@ -267,7 +282,7 @@ contract T1ERC7683 is IT1ERC7683, T1Permit2, AccessControlUpgradeable, EIP712 { chainId: orderData.destinationDomain }); - // this can be used by the filler know how much it can expect to receive + // this can be used by the filler to know how much it can expect to receive Output[] memory minReceived = new Output[](1); minReceived[0] = Output({ token: orderData.inputToken, @@ -276,7 +291,7 @@ contract T1ERC7683 is IT1ERC7683, T1Permit2, AccessControlUpgradeable, EIP712 { chainId: orderData.originDomain }); - // this can be user by the filler to know how to fill the order + // this can be used by the filler to know how to fill the order FillInstruction[] memory fillInstructions = new FillInstruction[](1); fillInstructions[0] = FillInstruction({ destinationChainId: orderData.destinationDomain, From 610f8b7ecdf22347abfc94228042c5b57e11e0c9 Mon Sep 17 00:00:00 2001 From: Ryan Collins Date: Thu, 25 Sep 2025 10:34:06 -0400 Subject: [PATCH 4/7] fix: remove redundant commetns --- contracts/src/7683/T1ERC7683.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/src/7683/T1ERC7683.sol b/contracts/src/7683/T1ERC7683.sol index 07b20c65..31447308 100644 --- a/contracts/src/7683/T1ERC7683.sol +++ b/contracts/src/7683/T1ERC7683.sol @@ -269,10 +269,6 @@ contract T1ERC7683 is IT1ERC7683, T1Permit2, AccessControlUpgradeable, EIP712 { revert InvalidSender(orderData.sender, expectedSender); } - // No need to overwrite fields since they are validated to be correct - // orderData.fillDeadline = _fillDeadline; // Removed - // orderData.sender = TypeCasts.addressToBytes32(_sender); // Removed - // this can be used by the filler to approve the tokens to be spent on destination Output[] memory maxSpent = new Output[](1); maxSpent[0] = Output({ From 1283f4ec3ba3c1e3d766fa93233e489eb3da6f81 Mon Sep 17 00:00:00 2001 From: Ryan Collins Date: Thu, 25 Sep 2025 10:44:41 -0400 Subject: [PATCH 5/7] fix: upgrade deploy scripts to set owner --- contracts/script/deploy/DeployArbT1XChainReader.s.sol | 3 +++ contracts/script/deploy/DeployBaseT1XChainReader.s.sol | 3 +++ 2 files changed, 6 insertions(+) diff --git a/contracts/script/deploy/DeployArbT1XChainReader.s.sol b/contracts/script/deploy/DeployArbT1XChainReader.s.sol index a451977d..9c6dc47a 100644 --- a/contracts/script/deploy/DeployArbT1XChainReader.s.sol +++ b/contracts/script/deploy/DeployArbT1XChainReader.s.sol @@ -12,6 +12,7 @@ import { T1XChainReader } from "../../src/libraries/xChain/T1XChainReader.sol"; contract DeployArbT1XChainReader is DeploymentUtils { address internal ARB_T1_PROXY_ADMIN_ADDR = vm.envAddress("ARB_T1_PROXY_ADMIN_ADDR"); address internal PROVER = vm.envAddress("ARB_SIGNER"); + address internal MANAGER_MULTISIG = vm.envAddress("MANAGER_MULTISIG_ADDR"); function run() external { selectMainnetOrSepoliaFork("arbitrum"); @@ -24,6 +25,8 @@ contract DeployArbT1XChainReader is DeploymentUtils { T1XChainReader impl = new T1XChainReader(PROVER); logAddress("ARB_T1_X_CHAIN_READ_IMPLEMENTATION_ADDR", address(impl)); + impl.initialize(MANAGER_MULTISIG); + TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(address(impl), address(proxyAdmin), new bytes(0)); logAddress("ARB_T1_X_CHAIN_READ_PROXY_ADDR", address(proxy)); diff --git a/contracts/script/deploy/DeployBaseT1XChainReader.s.sol b/contracts/script/deploy/DeployBaseT1XChainReader.s.sol index 5eecf06c..f3f7ca9c 100644 --- a/contracts/script/deploy/DeployBaseT1XChainReader.s.sol +++ b/contracts/script/deploy/DeployBaseT1XChainReader.s.sol @@ -12,6 +12,7 @@ import { T1XChainReader } from "../../src/libraries/xChain/T1XChainReader.sol"; contract DeployBaseT1XChainReader is DeploymentUtils { address internal BASE_T1_PROXY_ADMIN_ADDR = vm.envAddress("BASE_T1_PROXY_ADMIN_ADDR"); address internal PROVER = vm.envAddress("BASE_SIGNER"); + address internal MANAGER_MULTISIG = vm.envAddress("MANAGER_MULTISIG_ADDR"); function run() external { selectMainnetOrSepoliaFork("base"); @@ -23,6 +24,8 @@ contract DeployBaseT1XChainReader is DeploymentUtils { T1XChainReader impl = new T1XChainReader(PROVER); logAddress("BASE_T1_X_CHAIN_READ_IMPLEMENTATION_ADDR", address(impl)); + impl.initialize(MANAGER_MULTISIG); + TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(address(impl), address(proxyAdmin), new bytes(0)); logAddress("BASE_T1_X_CHAIN_READ_PROXY_ADDR", address(proxy)); From e5a6c2e4e04e612dd8dbe950dd58291c8d98f74a Mon Sep 17 00:00:00 2001 From: Ryan Collins Date: Thu, 25 Sep 2025 10:47:39 -0400 Subject: [PATCH 6/7] fix: update .env.template with new value --- contracts/.env.template | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/.env.template b/contracts/.env.template index e8388702..56be173d 100644 --- a/contracts/.env.template +++ b/contracts/.env.template @@ -102,6 +102,8 @@ BASE_SEPOLIA_USDT_ADDR=0x228eE6c1C297E2Eba0e95A71684B26f89385b4eC BASE_SEPOLIA_WETH_ADDR=0x4200000000000000000000000000000000000006 BASE_SEPOLIA_FILL_BOT_PRIVATE_KEY= +MANAGER_MULTISIG_ADDR= + #xYield XYIELD_GUARDIAN_ADDR= From 90992a18fdb935df3c25e1e8b0ba4dfb027ea853 Mon Sep 17 00:00:00 2001 From: Ryan Collins Date: Tue, 30 Sep 2025 18:35:04 +0200 Subject: [PATCH 7/7] fix: corrects address in PausableTest --- contracts/src/test/7683/PausableTest.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/src/test/7683/PausableTest.t.sol b/contracts/src/test/7683/PausableTest.t.sol index ffe1e683..dc98bfab 100644 --- a/contracts/src/test/7683/PausableTest.t.sol +++ b/contracts/src/test/7683/PausableTest.t.sol @@ -241,7 +241,7 @@ contract PausableTest is T1XChainReaderBaseTestSetup { senderNonce: 1, originDomain: origin, destinationDomain: destination, - destinationSettler: TypeCasts.addressToBytes32(counterpart), + destinationSettler: TypeCasts.addressToBytes32(address(l2T1ERC7683)), fillDeadline: deadline, closedAuction: false, data: ""