lay0_update

Created Diff never expires
42 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
110 lines
32 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
103 lines
// SPDX-License-Identifier: BUSL-1.1
// SPDX-License-Identifier: BUSL-1.1


pragma solidity 0.7.6;
pragma solidity 0.7.6;
pragma abicoder v2;
pragma abicoder v2;


import "./utility/LayerZeroPacket.sol";
import "./LayerZeroPacket.sol";
import "./utility/Buffer.sol";
import "./Buffer.sol";
import "./ILayerZeroValidationLibrary.sol";
import "./ILayerZeroValidationLibrary.sol";
import "./utility/UltraLightNodeEVMDecoder.sol";
import "./UltraLightNodeEVMDecoder.sol";


contract MPTValidator is ILayerZeroValidationLibrary {
contract MPTValidatorV2 is ILayerZeroValidationLibrary {
using RLPDecode for RLPDecode.RLPItem;
using RLPDecode for RLPDecode.RLPItem;
using RLPDecode for RLPDecode.Iterator;
using RLPDecode for RLPDecode.Iterator;
using Buffer for Buffer.buffer;
using Buffer for Buffer.buffer;
using SafeMath for uint;
using SafeMath for uint;


bytes32 public constant PACKET_SIGNATURE = 0xe8d23d927749ec8e512eb885679c2977d57068839d8cca1a85685dbbea0648f6;
bytes32 public constant PACKET_SIGNATURE = 0xe8d23d927749ec8e512eb885679c2977d57068839d8cca1a85685dbbea0648f6;


struct ULNLog{
struct ULNLog{
bytes32 contractAddress;
bytes32 contractAddress;
bytes32 topicZeroSig;
bytes32 topicZeroSig;
bytes data;
bytes data;
}
}


function validateProof(bytes32 _receiptsRoot, bytes calldata _transactionProof, uint _remoteAddressSize) external pure override returns (LayerZeroPacket.Packet memory packet) {
function validateProof(bytes32 _receiptsRoot, bytes calldata _transactionProof, uint _remoteAddressSize) external pure override returns (LayerZeroPacket.Packet memory packet) {
(uint16 remoteChainId, bytes[] memory proof, uint[] memory pointers, uint receiptIndex, uint logIndex) = abi.decode(_transactionProof, (uint16, bytes[], uint[], uint, uint));
(uint16 remoteChainId, bytes[] memory proof, uint[] memory receiptSlotIndex, uint logIndex) = abi.decode(_transactionProof, (uint16, bytes[], uint[], uint));


ULNLog memory log = _getVerifiedLog(_receiptsRoot, receiptIndex, logIndex, proof, pointers);
ULNLog memory log = _getVerifiedLog(_receiptsRoot, receiptSlotIndex, logIndex, proof);
require(log.topicZeroSig == PACKET_SIGNATURE, "LayerZero: packet not recognized"); //data
require(log.topicZeroSig == PACKET_SIGNATURE, "ProofLib: packet not recognized"); //data


return getPacket(log.data, remoteChainId, _remoteAddressSize, log.contractAddress);
return _getPacket(log.data, remoteChainId, _remoteAddressSize, log.contractAddress);
}
}


function _getVerifiedLog(bytes32 hashRoot, uint receiptSlotIndex, uint logIndex, bytes[] memory proof, uint[] memory pointers) internal pure returns(ULNLog memory) {
function _getVerifiedLog(bytes32 hashRoot, uint[] memory paths, uint logIndex, bytes[] memory proof) internal pure returns(ULNLog memory) {
// walk and assert the hash links of MPT
require(paths.length == proof.length, "ProofLib: invalid proof size");
uint pointer;

RLPDecode.RLPItem memory item;
bytes memory proofBytes;
bytes memory proofBytes;

for (uint i = 0; i < proof.length; i++) {
for (uint i = 0; i < proof.length; i++) {
proofBytes = proof[i];
proofBytes = proof[i];
require(hashRoot == keccak256(proofBytes), "LayerZero: invalid hashlink");
require(hashRoot == keccak256(proofBytes), "ProofLib: invalid hashlink");
if (i < pointers.length) {
item = RLPDecode.toRlpItem(proofBytes).safeGetItemByIndex(paths[i]);
pointer = pointers[i];
if (i < proof.length - 1) hashRoot = bytes32(item.toUint());
assembly { hashRoot := mload(add(add(proofBytes, pointer), 32)) }
}
}
}


// build the iterator for the proofBytes
// burning status + gasUsed + logBloom
RLPDecode.Iterator memory it = RLPDecode.toRlpItem(proofBytes).iterator();
RLPDecode.RLPItem memory logItem = item.typeOffset().safeGetItemByIndex(3);

RLPDecode.Iterator memory it = logItem.safeGetItemByIndex(logIndex).iterator();
// get the receipt item from either branch or leaf node
RLPDecode.RLPItem memory receiptItem = it.item.getItemByIndex(receiptSlotIndex);
// it = targetReceiptIter
it = receiptItem.typeOffset().iterator();
it.next(); // status
it.next(); // gasUsed
it.next(); // logBloom

// it = targetLogIter
it = it.next().getItemByIndex(logIndex).iterator();
ULNLog memory log;
ULNLog memory log;
log.contractAddress = bytes32(it.next().toUint());
log.contractAddress = bytes32(it.next().toUint());
log.topicZeroSig = bytes32(it.next().getItemByIndex(0).toUint());
log.topicZeroSig = bytes32(it.next().getItemByIndex(0).toUint());
log.data = it.next().toBytes();
log.data = it.next().toBytes();


return log;
return log;
}
}


// profiling and test
// profiling and test
function getVerifyLog(bytes32 hashRoot, uint receiptSlotIndex, uint logIndex, bytes[] memory proof, uint[] memory pointers) external pure returns(ULNLog memory){
function getVerifyLog(bytes32 hashRoot, uint[] memory receiptSlotIndex, uint logIndex, bytes[] memory proof) external pure returns(ULNLog memory){
return _getVerifiedLog(hashRoot, receiptSlotIndex, logIndex, proof, pointers);
return _getVerifiedLog(hashRoot, receiptSlotIndex, logIndex, proof);
}
}


function getPacket(
function getPacket(bytes memory data, uint16 srcChain, uint sizeOfSrcAddress, bytes32 ulnAddress) external pure returns(LayerZeroPacket.Packet memory) {
return _getPacket(data, srcChain, sizeOfSrcAddress, ulnAddress);
}

function _getPacket(
bytes memory data,
bytes memory data,
uint16 srcChain,
uint16 srcChain,
uint sizeOfSrcAddress,
uint sizeOfSrcAddress,
bytes32 ulnAddress
bytes32 ulnAddress
) internal pure returns (LayerZeroPacket.Packet memory) {
) internal pure returns (LayerZeroPacket.Packet memory) {
uint16 dstChainId;
uint16 dstChainId;
address dstAddress;
address dstAddress;
uint size;
uint size;
uint64 nonce;
uint64 nonce;


// The log consists of the destination chain id and then a bytes payload
// The log consists of the destination chain id and then a bytes payload
// 0--------------------------------------------31
// 0--------------------------------------------31
// 0 | destination chain id
// 0 | destination chain id
// 32 | defines bytes array
// 32 | defines bytes array
// 64 |
// 64 |
// 96 | bytes array size
// 96 | bytes array size
// 128 | payload
// 128 | payload
assembly {
assembly {
dstChainId := mload(add(data, 32))
dstChainId := mload(add(data, 32))
size := mload(add(data, 96)) /// size of the byte array
size := mload(add(data, 96)) /// size of the byte array
nonce := mload(add(data, 104)) // offset to convert to uint64 128 is index -24
nonce := mload(add(data, 104)) // offset to convert to uint64 128 is index -24
dstAddress := mload(add(data, sub(add(128, sizeOfSrcAddress), 4))) // offset to convert to address 12 -8
dstAddress := mload(add(data, sub(add(128, sizeOfSrcAddress), 4))) // offset to convert to address 12 -8
}
}


Buffer.buffer memory srcAddressBuffer;
Buffer.buffer memory srcAddressBuffer;
srcAddressBuffer.init(sizeOfSrcAddress);
srcAddressBuffer.init(sizeOfSrcAddress);
srcAddressBuffer.writeRawBytes(0, data, 136, sizeOfSrcAddress); // 128 + 8
srcAddressBuffer.writeRawBytes(0, data, 136, sizeOfSrcAddress); // 128 + 8


uint payloadSize = size.sub(20).sub(sizeOfSrcAddress);
uint payloadSize = size.sub(20).sub(sizeOfSrcAddress);
Buffer.buffer memory payloadBuffer;
Buffer.buffer memory payloadBuffer;
payloadBuffer.init(payloadSize);
payloadBuffer.init(payloadSize);
payloadBuffer.writeRawBytes(0, data, sizeOfSrcAddress.add(156), payloadSize); // 148 + 8
payloadBuffer.writeRawBytes(0, data, sizeOfSrcAddress.add(156), payloadSize); // 148 + 8
// LayerZeroPacket.Packet memory packet = LayerZeroPacket.Packet(srcChain, dstChainId, nonce, address(dstAddress), srcAddressBuffer.buf, ulnAddress, payloadBuffer.buf);
return LayerZeroPacket.Packet(srcChain, dstChainId, nonce, dstAddress, srcAddressBuffer.buf, ulnAddress, payloadBuffer.buf);
return LayerZeroPacket.Packet(srcChain, dstChainId, nonce, address(dstAddress), srcAddressBuffer.buf, ulnAddress, payloadBuffer.buf);
}
}
}
}