diff --git a/.gitmodules b/.gitmodules
index 5af0c1acb0b7adbf3ce2a3c61823bb27f4545b4a..c220a03f9f6cd748ff2f5c7c1927a7add36dea6f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -10,9 +10,6 @@
 [submodule "packages/contracts-bedrock/lib/clones-with-immutable-args"]
 	path = packages/contracts-bedrock/lib/clones-with-immutable-args
 	url = https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args
-[submodule "packages/contracts-bedrock/lib/ds-test"]
-	path = packages/contracts-bedrock/lib/ds-test
-	url = https://github.com/dapphub/ds-test
 [submodule "packages/contracts-bedrock/lib/forge-std"]
 	path = packages/contracts-bedrock/lib/forge-std
 	url = https://github.com/foundry-rs/forge-std
diff --git a/op-bindings/bindings/weth9.go b/op-bindings/bindings/weth9.go
index 59bed20c89a61fcd78e845e730e873a1a693c3b1..c174d3a0a0b9849f0adc6544302b70823d00ca96 100644
--- a/op-bindings/bindings/weth9.go
+++ b/op-bindings/bindings/weth9.go
@@ -31,7 +31,7 @@ var (
 // WETH9MetaData contains all meta data concerning the WETH9 contract.
 var WETH9MetaData = &bind.MetaData{
 	ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
-	Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820e99c192477b0fd152c4048736f299c82338ac75b0e85ff6bfcba12ff17b4e06c64736f6c63430005110032",
+	Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a7231582067ace7518c12acba9306ac90d5b712c789ea3d50860ef4996a20921a3c1e61f764736f6c63430005110032",
 }
 
 // WETH9ABI is the input ABI used to generate the binding from.
diff --git a/op-bindings/bindings/weth9_more.go b/op-bindings/bindings/weth9_more.go
index 693b046b008f4c1bb0b83818709bb6249fa3b20b..40f30ca5a65e6b970c7b4cc6ba8c6498cf799499 100644
--- a/op-bindings/bindings/weth9_more.go
+++ b/op-bindings/bindings/weth9_more.go
@@ -13,7 +13,7 @@ const WETH9StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src
 
 var WETH9StorageLayout = new(solc.StorageLayout)
 
-var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820e99c192477b0fd152c4048736f299c82338ac75b0e85ff6bfcba12ff17b4e06c64736f6c63430005110032"
+var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a7231582067ace7518c12acba9306ac90d5b712c789ea3d50860ef4996a20921a3c1e61f764736f6c63430005110032"
 
 func init() {
 	if err := json.Unmarshal([]byte(WETH9StorageLayoutJSON), WETH9StorageLayout); err != nil {
diff --git a/op-challenger/fault/cannon/provider.go b/op-challenger/fault/cannon/provider.go
index 07f285ee59fee6dcb452886152e428c59dc18b30..7d1cc9be834b554bd3c982737b2a331bb6eb355f 100644
--- a/op-challenger/fault/cannon/provider.go
+++ b/op-challenger/fault/cannon/provider.go
@@ -53,7 +53,7 @@ type CannonTraceProvider struct {
 func NewTraceProvider(ctx context.Context, logger log.Logger, cfg *config.Config, l1Client bind.ContractCaller) (*CannonTraceProvider, error) {
 	l2Client, err := ethclient.DialContext(ctx, cfg.CannonL2)
 	if err != nil {
-		return nil, fmt.Errorf("dial l2 cleint %v: %w", cfg.CannonL2, err)
+		return nil, fmt.Errorf("dial l2 client %v: %w", cfg.CannonL2, err)
 	}
 	defer l2Client.Close() // Not needed after fetching the inputs
 	gameCaller, err := bindings.NewFaultDisputeGameCaller(cfg.GameAddress, l1Client)
diff --git a/op-e2e/e2eutils/challenger/helper.go b/op-e2e/e2eutils/challenger/helper.go
index 252cfe7be63c207966b9bdd18da055806f72a9bc..252f15c8c3c552f6d979cc1324243e4e7c2e9028 100644
--- a/op-e2e/e2eutils/challenger/helper.go
+++ b/op-e2e/e2eutils/challenger/helper.go
@@ -26,6 +26,22 @@ type Option func(config2 *config.Config)
 func NewChallenger(t *testing.T, ctx context.Context, l1Endpoint string, name string, options ...Option) *Helper {
 	log := testlog.Logger(t, log.LvlInfo).New("role", name)
 	log.Info("Creating challenger", "l1", l1Endpoint)
+	cfg := NewChallengerConfig(t, l1Endpoint, options...)
+
+	errCh := make(chan error, 1)
+	ctx, cancel := context.WithCancel(ctx)
+	go func() {
+		defer close(errCh)
+		errCh <- op_challenger.Main(ctx, log, cfg)
+	}()
+	return &Helper{
+		log:    log,
+		cancel: cancel,
+		errors: errCh,
+	}
+}
+
+func NewChallengerConfig(t *testing.T, l1Endpoint string, options ...Option) *config.Config {
 	txmgrCfg := txmgr.NewCLIConfig(l1Endpoint)
 	txmgrCfg.NumConfirmations = 1
 	txmgrCfg.ReceiptQueryInterval = 1 * time.Second
@@ -53,18 +69,7 @@ func NewChallenger(t *testing.T, ctx context.Context, l1Endpoint string, name st
 		_, err := os.Stat(cfg.CannonAbsolutePreState)
 		require.NoError(t, err, "cannon pre-state should be built. Make sure you've run make cannon-prestate")
 	}
-
-	errCh := make(chan error, 1)
-	ctx, cancel := context.WithCancel(ctx)
-	go func() {
-		defer close(errCh)
-		errCh <- op_challenger.Main(ctx, log, cfg)
-	}()
-	return &Helper{
-		log:    log,
-		cancel: cancel,
-		errors: errCh,
-	}
+	return cfg
 }
 
 func (h *Helper) Close() error {
diff --git a/op-e2e/e2eutils/disputegame/cannon_helper.go b/op-e2e/e2eutils/disputegame/cannon_helper.go
index f8ed3fdbb3df87119a9b20cf83c60ec81ee40e5f..0f03c248722bc1af784e2a4fef3f79e5fdfe7f6e 100644
--- a/op-e2e/e2eutils/disputegame/cannon_helper.go
+++ b/op-e2e/e2eutils/disputegame/cannon_helper.go
@@ -7,10 +7,13 @@ import (
 	"path/filepath"
 
 	"github.com/ethereum-optimism/optimism/op-challenger/config"
+	"github.com/ethereum-optimism/optimism/op-challenger/fault/cannon"
 	"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
 	"github.com/ethereum-optimism/optimism/op-node/rollup"
-	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum-optimism/optimism/op-node/testlog"
+	"github.com/ethereum/go-ethereum/accounts/abi/bind"
 	"github.com/ethereum/go-ethereum/core"
+	"github.com/ethereum/go-ethereum/log"
 )
 
 type CannonGameHelper struct {
@@ -18,31 +21,7 @@ type CannonGameHelper struct {
 }
 
 func (g *CannonGameHelper) StartChallenger(ctx context.Context, rollupCfg *rollup.Config, l2Genesis *core.Genesis, l1Endpoint string, l2Endpoint string, name string, options ...challenger.Option) *challenger.Helper {
-	opts := []challenger.Option{
-		func(c *config.Config) {
-			c.GameAddress = g.addr
-			c.TraceType = config.TraceTypeCannon
-			c.AgreeWithProposedOutput = false
-			c.CannonL2 = l2Endpoint
-			c.CannonBin = "../cannon/bin/cannon"
-			c.CannonDatadir = g.t.TempDir()
-			c.CannonServer = "../op-program/bin/op-program"
-			c.CannonAbsolutePreState = "../op-program/bin/prestate.json"
-			c.CannonSnapshotFreq = 10_000_000
-
-			genesisBytes, err := json.Marshal(l2Genesis)
-			g.require.NoError(err, "marshall l2 genesis config")
-			genesisFile := filepath.Join(c.CannonDatadir, "l2-genesis.json")
-			g.require.NoError(os.WriteFile(genesisFile, genesisBytes, 0644))
-			c.CannonL2GenesisPath = genesisFile
-
-			rollupBytes, err := json.Marshal(rollupCfg)
-			g.require.NoError(err, "marshall rollup config")
-			rollupFile := filepath.Join(c.CannonDatadir, "rollup.json")
-			g.require.NoError(os.WriteFile(rollupFile, rollupBytes, 0644))
-			c.CannonRollupConfigPath = rollupFile
-		},
-	}
+	opts := []challenger.Option{g.createConfigOption(rollupCfg, l2Genesis, l2Endpoint)}
 	opts = append(opts, options...)
 	c := challenger.NewChallenger(g.t, ctx, l1Endpoint, name, opts...)
 	g.t.Cleanup(func() {
@@ -51,6 +30,43 @@ func (g *CannonGameHelper) StartChallenger(ctx context.Context, rollupCfg *rollu
 	return c
 }
 
-func (g *FaultGameHelper) Address() common.Address {
-	return g.addr
+func (g *CannonGameHelper) CreateHonestActor(ctx context.Context, rollupCfg *rollup.Config, l2Genesis *core.Genesis, l1Client bind.ContractCaller, l1Endpoint string, l2Endpoint string, options ...challenger.Option) *HonestHelper {
+	opts := []challenger.Option{g.createConfigOption(rollupCfg, l2Genesis, l2Endpoint)}
+	opts = append(opts, options...)
+	cfg := challenger.NewChallengerConfig(g.t, l1Endpoint, opts...)
+	provider, err := cannon.NewTraceProvider(ctx, testlog.Logger(g.t, log.LvlTrace).New("role", "CorrectTrace"), cfg, l1Client)
+	g.require.NoError(err, "create cannon trace provider")
+
+	return &HonestHelper{
+		t:            g.t,
+		require:      g.require,
+		game:         &g.FaultGameHelper,
+		correctTrace: provider,
+	}
+}
+
+func (g *CannonGameHelper) createConfigOption(rollupCfg *rollup.Config, l2Genesis *core.Genesis, l2Endpoint string) challenger.Option {
+	return func(c *config.Config) {
+		c.GameAddress = g.addr
+		c.TraceType = config.TraceTypeCannon
+		c.AgreeWithProposedOutput = false
+		c.CannonL2 = l2Endpoint
+		c.CannonBin = "../cannon/bin/cannon"
+		c.CannonDatadir = g.t.TempDir()
+		c.CannonServer = "../op-program/bin/op-program"
+		c.CannonAbsolutePreState = "../op-program/bin/prestate.json"
+		c.CannonSnapshotFreq = 10_000_000
+
+		genesisBytes, err := json.Marshal(l2Genesis)
+		g.require.NoError(err, "marshall l2 genesis config")
+		genesisFile := filepath.Join(c.CannonDatadir, "l2-genesis.json")
+		g.require.NoError(os.WriteFile(genesisFile, genesisBytes, 0644))
+		c.CannonL2GenesisPath = genesisFile
+
+		rollupBytes, err := json.Marshal(rollupCfg)
+		g.require.NoError(err, "marshall rollup config")
+		rollupFile := filepath.Join(c.CannonDatadir, "rollup.json")
+		g.require.NoError(os.WriteFile(rollupFile, rollupBytes, 0644))
+		c.CannonRollupConfigPath = rollupFile
+	}
 }
diff --git a/op-e2e/e2eutils/disputegame/game_helper.go b/op-e2e/e2eutils/disputegame/game_helper.go
index e306597a86436b7a463509eacaf726d837906474..7dbe1864e7ad92c53bddbd6e80894eb198694c5a 100644
--- a/op-e2e/e2eutils/disputegame/game_helper.go
+++ b/op-e2e/e2eutils/disputegame/game_helper.go
@@ -82,6 +82,16 @@ func (g *FaultGameHelper) WaitForClaim(ctx context.Context, predicate func(claim
 	g.require.NoError(err)
 }
 
+// getClaim retrieves the claim data for a specific index.
+// Note that it is deliberately not exported as tests should use WaitForClaim to avoid race conditions.
+func (g *FaultGameHelper) getClaim(ctx context.Context, claimIdx int64) ContractClaim {
+	claimData, err := g.game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx))
+	if err != nil {
+		g.require.NoErrorf(err, "retrieve claim %v", claimIdx)
+	}
+	return claimData
+}
+
 func (g *FaultGameHelper) WaitForClaimAtMaxDepth(ctx context.Context, countered bool) {
 	maxDepth := g.MaxDepth(ctx)
 	g.WaitForClaim(ctx, func(claim ContractClaim) bool {
@@ -146,5 +156,5 @@ func (g *FaultGameHelper) LogGameData(ctx context.Context) {
 	}
 	status, err := g.game.Status(opts)
 	g.require.NoError(err, "Load game status")
-	g.t.Logf("Game %v:\n%v\nCurrent status: %v\n", g.addr, info, Status(status))
+	g.t.Logf("Game %v (%v):\n%v\n", g.addr, Status(status), info)
 }
diff --git a/op-e2e/e2eutils/disputegame/honest_helper.go b/op-e2e/e2eutils/disputegame/honest_helper.go
new file mode 100644
index 0000000000000000000000000000000000000000..4a815e54b265a77151a965685e203f7a3cf0bead
--- /dev/null
+++ b/op-e2e/e2eutils/disputegame/honest_helper.go
@@ -0,0 +1,44 @@
+package disputegame
+
+import (
+	"context"
+	"testing"
+	"time"
+
+	"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
+	"github.com/stretchr/testify/require"
+)
+
+type HonestHelper struct {
+	t            *testing.T
+	require      *require.Assertions
+	game         *FaultGameHelper
+	correctTrace types.TraceProvider
+}
+
+func (h *HonestHelper) Attack(ctx context.Context, claimIdx int64) {
+	ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
+	defer cancel()
+	claim := h.game.getClaim(ctx, claimIdx)
+	pos := types.NewPositionFromGIndex(claim.Position.Uint64())
+	attackPos := pos.Attack()
+	traceIdx := attackPos.TraceIndex(int(h.game.MaxDepth(ctx)))
+	h.t.Logf("Attacking at position %v using correct trace from index %v", attackPos.ToGIndex(), traceIdx)
+	value, err := h.correctTrace.Get(ctx, traceIdx)
+	h.require.NoErrorf(err, "Get correct claim at trace index %v", traceIdx)
+	h.t.Log("Performing attack")
+	h.game.Attack(ctx, claimIdx, value)
+	h.t.Log("Attack complete")
+}
+
+func (h *HonestHelper) Defend(ctx context.Context, claimIdx int64) {
+	ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
+	defer cancel()
+	claim := h.game.getClaim(ctx, claimIdx)
+	pos := types.NewPositionFromGIndex(claim.Position.Uint64())
+	defendPos := pos.Defend()
+	traceIdx := defendPos.TraceIndex(int(h.game.MaxDepth(ctx)))
+	value, err := h.correctTrace.Get(ctx, traceIdx)
+	h.game.require.NoErrorf(err, "Get correct claim at trace index %v", traceIdx)
+	h.game.Defend(ctx, claimIdx, value)
+}
diff --git a/op-e2e/faultproof_test.go b/op-e2e/faultproof_test.go
index 395b88977403e364361b492071052bf3ef86984b..26dba961fb937706dd4ab4177fa707c16548003d 100644
--- a/op-e2e/faultproof_test.go
+++ b/op-e2e/faultproof_test.go
@@ -206,6 +206,59 @@ func TestCannonDisputeGame(t *testing.T) {
 	}
 }
 
+func TestCannonDefendStep(t *testing.T) {
+	InitParallel(t)
+
+	ctx := context.Background()
+	sys, l1Client := startFaultDisputeSystem(t)
+	t.Cleanup(sys.Close)
+
+	disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client)
+	game := disputeGameFactory.StartCannonGame(ctx, common.Hash{0xaa})
+	require.NotNil(t, game)
+	game.LogGameData(ctx)
+
+	l1Endpoint := sys.NodeEndpoint("l1")
+	l2Endpoint := sys.NodeEndpoint("sequencer")
+	game.StartChallenger(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Endpoint, l2Endpoint, "Challenger", func(c *config.Config) {
+		c.AgreeWithProposedOutput = true // Agree with the proposed output, so disagree with the root claim
+		c.TxMgrConfig.PrivateKey = e2eutils.EncodePrivKeyToString(sys.cfg.Secrets.Alice)
+	})
+
+	correctTrace := game.CreateHonestActor(ctx, sys.RollupConfig, sys.L2GenesisCfg, l1Client, l1Endpoint, l2Endpoint, func(c *config.Config) {
+		c.TxMgrConfig.PrivateKey = e2eutils.EncodePrivKeyToString(sys.cfg.Secrets.Mallory)
+	})
+
+	maxDepth := game.MaxDepth(ctx)
+	for claimCount := int64(1); claimCount < maxDepth; {
+		game.LogGameData(ctx)
+		claimCount++
+		// Wait for the challenger to counter
+		game.WaitForClaimCount(ctx, claimCount)
+
+		// Post invalid claims for most steps to get down into the early part of the trace
+		if claimCount < 28 {
+			game.Attack(ctx, claimCount-1, common.Hash{byte(claimCount)})
+		} else {
+			// Post our own counter but using the correct hash in low levels to force a defense step
+			correctTrace.Attack(ctx, claimCount-1)
+		}
+		claimCount++
+		game.LogGameData(ctx)
+		game.WaitForClaimCount(ctx, claimCount)
+	}
+
+	game.LogGameData(ctx)
+	// Wait for the challenger to call step and counter our invalid claim
+	game.WaitForClaimAtMaxDepth(ctx, true)
+
+	sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx))
+	require.NoError(t, utils.WaitNextBlock(ctx, l1Client))
+
+	game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins)
+	game.LogGameData(ctx)
+}
+
 func startFaultDisputeSystem(t *testing.T) (*System, *ethclient.Client) {
 	cfg := DefaultSystemConfig(t)
 	delete(cfg.Nodes, "verifier")
diff --git a/ops-bedrock/Dockerfile.l1 b/ops-bedrock/Dockerfile.l1
index 48fb6776d63f231eca10b6afc7773d12c451892b..7e39574630ae473c6e38714229e08613c85a7e75 100644
--- a/ops-bedrock/Dockerfile.l1
+++ b/ops-bedrock/Dockerfile.l1
@@ -1,4 +1,4 @@
-FROM ethereum/client-go:v1.12.0
+FROM ethereum/client-go:v1.12.1
 
 RUN apk add --no-cache jq
 
diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot
index eec1ac3f7ec4459fb37a261f37a7cea28b080926..0d92e0bc18e820aea367212774e3142fdc584fbb 100644
--- a/packages/contracts-bedrock/.gas-snapshot
+++ b/packages/contracts-bedrock/.gas-snapshot
@@ -361,7 +361,7 @@ MIPS_Test:test_sra_succeeds() (gas: 121719)
 MIPS_Test:test_srav_succeeds() (gas: 121959)
 MIPS_Test:test_srl_succeeds() (gas: 121514)
 MIPS_Test:test_srlv_succeeds() (gas: 121707)
-MIPS_Test:test_step_abi_succeeds() (gas: 57871)
+MIPS_Test:test_step_abi_succeeds() (gas: 57876)
 MIPS_Test:test_sub_succeeds() (gas: 121674)
 MIPS_Test:test_subu_succeeds() (gas: 121682)
 MIPS_Test:test_sw_succeeds() (gas: 160050)
diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml
index e3ee1bd7edb0292378e46d81332b6f07353c7e1e..81c6262b1e68614462be554d5e98212d1a3ec928 100644
--- a/packages/contracts-bedrock/foundry.toml
+++ b/packages/contracts-bedrock/foundry.toml
@@ -11,7 +11,7 @@ remappings = [
   '@rari-capital/solmate/=lib/solmate',
   "@cwia/=lib/clones-with-immutable-args/src",
   'forge-std/=lib/forge-std/src',
-  'ds-test/=lib/ds-test/src'
+  'ds-test/=lib/forge-std/lib/ds-test/src'
 ]
 extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout']
 bytecode_hash = 'none'
diff --git a/packages/contracts-bedrock/lib/ds-test b/packages/contracts-bedrock/lib/ds-test
deleted file mode 160000
index c9ce3f25bde29fc5eb9901842bf02850dfd2d084..0000000000000000000000000000000000000000
--- a/packages/contracts-bedrock/lib/ds-test
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit c9ce3f25bde29fc5eb9901842bf02850dfd2d084
diff --git a/packages/contracts-bedrock/test/MIPS.t.sol b/packages/contracts-bedrock/test/MIPS.t.sol
index 204ba56d9a7e95225dd450d889dee35ef19b5c2e..ba19d03d8df8bd0613c2a4a505f934f9e5c6b4f3 100644
--- a/packages/contracts-bedrock/test/MIPS.t.sol
+++ b/packages/contracts-bedrock/test/MIPS.t.sol
@@ -39,7 +39,7 @@ contract MIPS_Test is CommonTest {
             hex"3c10bfff3610fff0341100013c08ffff3508fffd34090003010950202d420001ae020008ae11000403e000080000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618db8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
 
         bytes32 postState = mips.step(encodeState(state), proof);
-        assertTrue(postState != bytes32(0));
+        assertNotEq(postState, bytes32(0));
     }
 
     function test_add_succeeds() external {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 96116c17a155d48a6443ff2b178352b1b79cab17..8d442ef0104a995c5b1a1947b99a0824208c113a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -29,7 +29,7 @@ importers:
         version: 4.2.21
       '@types/chai-as-promised':
         specifier: ^7.1.4
-        version: 7.1.4
+        version: 7.1.5
       '@types/mocha':
         specifier: ^10.0.1
         version: 10.0.1
@@ -3746,8 +3746,8 @@ packages:
       '@types/node': 20.4.3
     dev: true
 
-  /@types/chai-as-promised@7.1.4:
-    resolution: {integrity: sha512-1y3L1cHePcIm5vXkh1DSGf/zQq5n5xDKG1fpCvf18+uOkpce0Z1ozNFPkyWsVswK7ntN1sZBw3oU6gmN+pDUcA==}
+  /@types/chai-as-promised@7.1.5:
+    resolution: {integrity: sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==}
     dependencies:
       '@types/chai': 4.3.5
     dev: true