diff --git a/solidity/contracts/libs/FraudMessage.sol b/solidity/contracts/libs/FraudMessage.sol index 021505f3a6..b900bade33 100644 --- a/solidity/contracts/libs/FraudMessage.sol +++ b/solidity/contracts/libs/FraudMessage.sol @@ -27,6 +27,13 @@ struct Attribution { } library FraudMessage { + uint8 public constant SIGNER_OFFSET = 0; + uint8 public constant MERKLE_TREE_OFFSET = 32; + uint8 public constant DIGEST_OFFSET = 64; + uint8 public constant FRAUD_TYPE_OFFSET = 96; + uint8 public constant TIMESTAMP_OFFSET = 97; + uint8 public constant MESSAGE_LENGTH = 103; + function encode( bytes32 signer, bytes32 merkleTree, @@ -34,18 +41,30 @@ library FraudMessage { Attribution memory attribution ) internal pure returns (bytes memory) { return - abi.encode( + abi.encodePacked( signer, merkleTree, digest, - attribution.fraudType, + uint8(attribution.fraudType), attribution.timestamp ); } function decode( - bytes memory _message + bytes calldata _message ) internal pure returns (bytes32, bytes32, bytes32, Attribution memory) { - return abi.decode(_message, (bytes32, bytes32, bytes32, Attribution)); + require(_message.length == MESSAGE_LENGTH, "Invalid message length"); + + bytes32 signer = bytes32(_message[SIGNER_OFFSET:MERKLE_TREE_OFFSET]); + bytes32 merkleTree = bytes32( + _message[MERKLE_TREE_OFFSET:DIGEST_OFFSET] + ); + bytes32 digest = bytes32(_message[DIGEST_OFFSET:FRAUD_TYPE_OFFSET]); + FraudType fraudType = FraudType(uint8(_message[FRAUD_TYPE_OFFSET])); + uint48 timestamp = uint48( + bytes6(_message[TIMESTAMP_OFFSET:MESSAGE_LENGTH]) + ); + + return (signer, merkleTree, digest, Attribution(fraudType, timestamp)); } } diff --git a/solidity/contracts/middleware/FraudProofRouter.sol b/solidity/contracts/middleware/FraudProofRouter.sol index 855187e1c6..54c3989f96 100644 --- a/solidity/contracts/middleware/FraudProofRouter.sol +++ b/solidity/contracts/middleware/FraudProofRouter.sol @@ -113,7 +113,7 @@ contract FraudProofRouter is GasRouter { bytes32, /*_sender*/ bytes calldata _message - ) internal override onlyMailbox { + ) internal override { ( bytes32 signer, bytes32 merkleTree, diff --git a/solidity/remappings.txt b/solidity/remappings.txt index 6fa7a15ad5..49ae22c339 100644 --- a/solidity/remappings.txt +++ b/solidity/remappings.txt @@ -1,7 +1,7 @@ -@arbitrum=./node_modules/@arbitrum -@eth-optimism=./node_modules/@eth-optimism -@layerzerolabs=./node_modules/@layerzerolabs -@openzeppelin=./node_modules/@openzeppelin +@arbitrum=../node_modules/@arbitrum +@eth-optimism=../node_modules/@eth-optimism +@layerzerolabs=../node_modules/@layerzerolabs +@openzeppelin=../node_modules/@openzeppelin ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ fx-portal/=lib/fx-portal/ diff --git a/solidity/test/FraudProofRouter.t.sol b/solidity/test/FraudProofRouter.t.sol index d7adfa439a..937bcd2809 100644 --- a/solidity/test/FraudProofRouter.t.sol +++ b/solidity/test/FraudProofRouter.t.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.0; import {Test} from "forge-std/Test.sol"; -import {FraudType, Attribution} from "../contracts/libs/FraudMessage.sol"; +import {FraudType} from "../contracts/libs/FraudMessage.sol"; import {TypeCasts} from "../contracts/libs/TypeCasts.sol"; import {TestAttributeCheckpointFraud} from "../contracts/test/TestAttributeCheckpointFraud.sol"; import {FraudProofRouter} from "../contracts/middleware/FraudProofRouter.sol"; @@ -63,16 +63,25 @@ contract FraudProofRouterTest is Test { new FraudProofRouter(address(localMailbox), address(0)); } - function test_sendFraudProof() public { - FraudType fraudType = FraudType.Whitelist; + function test_sendFraudProof( + address _signer, + bytes32 _digest, + bytes32 _merkleTree, + uint8 _fraudType, + uint48 _timestamp + ) public { + vm.assume(_fraudType <= uint8(FraudType.Root)); + vm.assume(_timestamp > 0); + vm.warp(_timestamp); + FraudType fraudTypeEnum = FraudType(_fraudType); - testAcf.mockSetAttribution(SIGNER, DIGEST, fraudType); + testAcf.mockSetAttribution(_signer, _digest, fraudTypeEnum); originFpr.sendFraudProof( DESTINATION_DOMAIN, - SIGNER, - TypeCasts.addressToBytes32(address(testMerkleHook)), - DIGEST + _signer, + _merkleTree, + _digest ); remoteMailbox.processNextInboundMessage(); @@ -80,12 +89,12 @@ contract FraudProofRouterTest is Test { (FraudType actualFraudType, uint48 actualTimestamp) = remoteFpr .fraudAttributions( LOCAL_DOMAIN, - SIGNER.addressToBytes32(), - address(testMerkleHook).addressToBytes32(), - DIGEST + _signer.addressToBytes32(), + _merkleTree, + _digest ); - assert(actualFraudType == fraudType); + assert(actualFraudType == fraudTypeEnum); assertEq(actualTimestamp, block.timestamp); } diff --git a/solidity/test/OlyTest.sol b/solidity/test/OlyTest.sol deleted file mode 100644 index b75e6e7b23..0000000000 --- a/solidity/test/OlyTest.sol +++ /dev/null @@ -1,7 +0,0 @@ -pragma solidity >=0.8.0; - -import {Test} from "forge-std/Test.sol"; - -abstract contract OlympixUnitTest is Test { - constructor(string memory name) {} -}