Merkle - The implementation does not enforce inclusion of leaf nodes.
A observation with the current Merkle tree implementation is that it may be possible to validate nodes other than leaves. This is done by providing `checkMembership` with a reference to a hash within the tree, rather than a leaf.\\n```\\n/\\*\\*\\n \\* @notice Checks that a leaf hash is contained in a root hash\\n \\* @param leaf Leaf hash to verify\\n \\* @param index Position of the leaf hash in the Merkle tree\\n \\* @param rootHash Root of the Merkle tree\\n \\* @param proof A Merkle proof demonstrating membership of the leaf hash\\n \\* @return True, if the leaf hash is in the Merkle tree; otherwise, False\\n\\*/\\nfunction checkMembership(bytes32 leaf, uint256 index, bytes32 rootHash, bytes memory proof)\\n    internal\\n    pure\\n    returns (bool)\\n{\\n    require(proof.length % 32 == 0, "Length of Merkle proof must be a multiple of 32");\\n\\n    bytes32 proofElement;\\n    bytes32 computedHash = leaf;\\n    uint256 j = index;\\n    // Note: We're skipping the first 32 bytes of `proof`, which holds the size of the dynamically sized `bytes`\\n    for (uint256 i = 32; i <= proof.length; i += 32) {\\n        // solhint-disable-next-line no-inline-assembly\\n        assembly {\\n            proofElement := mload(add(proof, i))\\n        }\\n        if (j % 2 == 0) {\\n            computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\\n        } else {\\n            computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\\n        }\\n        j = j / 2;\\n    }\\n\\n    return computedHash == rootHash;\\n}\\n```\\n\\nThe current implementation will validate the provided “leaf” and return `true`. This is a known problem of Merkle trees https://en.wikipedia.org/wiki/Merkle_tree#Second_preimage_attack.\\nProvide a hash from within the Merkle tree as the `leaf` argument. The index has to match the index of that node in regards to its current level in the tree. The `rootHash` has to be the correct Merkle tree `rootHash`. The proof has to skip the necessary number of levels because the nodes “underneath” the provided “leaf” will not be processed.
A remediation needs a fixed Merkle tree size as well as the addition of a byte prepended to each node in the tree. Another way would be to create a structure for the Merkle node and mark it as `leaf` or no `leaf`.\\nCorresponding issue in plasma-contracts repo: https://github.com/omisego/plasma-contracts/issues/425
```\\n/\\*\\*\\n \\* @notice Checks that a leaf hash is contained in a root hash\\n \\* @param leaf Leaf hash to verify\\n \\* @param index Position of the leaf hash in the Merkle tree\\n \\* @param rootHash Root of the Merkle tree\\n \\* @param proof A Merkle proof demonstrating membership of the leaf hash\\n \\* @return True, if the leaf hash is in the Merkle tree; otherwise, False\\n\\*/\\nfunction checkMembership(bytes32 leaf, uint256 index, bytes32 rootHash, bytes memory proof)\\n    internal\\n    pure\\n    returns (bool)\\n{\\n    require(proof.length % 32 == 0, "Length of Merkle proof must be a multiple of 32");\\n\\n    bytes32 proofElement;\\n    bytes32 computedHash = leaf;\\n    uint256 j = index;\\n    // Note: We're skipping the first 32 bytes of `proof`, which holds the size of the dynamically sized `bytes`\\n    for (uint256 i = 32; i <= proof.length; i += 32) {\\n        // solhint-disable-next-line no-inline-assembly\\n        assembly {\\n            proofElement := mload(add(proof, i))\\n        }\\n        if (j % 2 == 0) {\\n            computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\\n        } else {\\n            computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\\n        }\\n        j = j / 2;\\n    }\\n\\n    return computedHash == rootHash;\\n}\\n```\\n