Skip to content
This repository has been archived by the owner on May 9, 2024. It is now read-only.

Commit

Permalink
Merge 2ab74c4 into 6fd3a7a
Browse files Browse the repository at this point in the history
  • Loading branch information
ansermino committed Apr 25, 2020
2 parents 6fd3a7a + 2ab74c4 commit 31d1924
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 41 deletions.
62 changes: 31 additions & 31 deletions contracts/handlers/GenericHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ contract GenericHandler is IGenericHandler {
struct DepositRecord {
uint8 _destinationChainID;
bytes32 _resourceID;
address _destinationRecipientAddress;
address _depositer;
bytes _metaData;
}
Expand Down Expand Up @@ -84,62 +83,64 @@ contract GenericHandler is IGenericHandler {
_setResource(resourceID, contractAddress, depositFunctionSig, executeFunctionSig);
}

// Data includes:
// - ResourceID (32bytes)
// - len(Data) (32 bytes)
// - Data (? bytes)
//
function deposit(
uint8 destinationChainID,
uint256 depositNonce,
address depositer,
bytes memory data
) public _onlyBridge {
address destinationRecipientAddress;
bytes32 resourceID;
bytes memory metaData;
bytes4 functionSignature;
bytes32 lenMetadata;
bytes memory metadata;

assembly {
// These are all fixed 32 bytes
// first 32 bytes of bytes is the length
destinationRecipientAddress := mload(add(data, 0x20))
resourceID := mload(add(data, 0x40))
// Load resource ID from data + 32
resourceID := mload(add(data, 0x20))
// Load length of metadata from data + 64
lenMetadata := mload(add(data, 0x40))
// Load free memory pointer
metadata := mload(0x40)

// metadata has variable length
// load free memory pointer to store metadata
metaData := mload(0x40)
// first 32 bytes of variable length in storage refer to length
let lenMeta := mload(add(0x60, data))
mstore(0x40, add(0x60, add(metaData, lenMeta)))
mstore(0x40, add(0x20, add(metadata, lenMetadata)))

// func sig (4) + destinationChainId (padded to 32) + depositNonce (32) + depositor (32) +
// bytes length (32) + resourceId (32) + length (32) = 0xC4

// in the calldata, metadata is stored @0xC4 after accounting for function signature, and 3 previous params
calldatacopy(
metaData, // copy to metaData
0xE4, // copy from calldata after data length declaration at 0xC4
sub(calldatasize(), 0xE4) // copy size (calldatasize - 0xC4)
metadata, // copy to metadata
0xC4, // copy from calldata after metadata length declaration @0xC4
sub(calldatasize(), 0xC4) // copy size (calldatasize - (0xC4 + the space metaData takes up))
)

functionSignature := mload(add(data, 0x40))
}

address contractAddress = _resourceIDToContractAddress[resourceID];
require(_contractWhitelist[contractAddress], "provided contractAddress is not whitelisted");

if (_contractAddressToDepositFunctionSignature[contractAddress] != bytes4(0) &&
_contractAddressToDepositFunctionSignature[contractAddress] == functionSignature) {
(bool success,) = contractAddress.call(metaData);
if (_contractAddressToDepositFunctionSignature[contractAddress] != bytes4(0)) {
(bool success,) = contractAddress.call(metadata);
require(success, "delegatecall to contractAddress failed");
}

_depositRecords[depositNonce] = DepositRecord(
destinationChainID,
resourceID,
destinationRecipientAddress,
depositer,
metaData
metadata
);
}

// Data contains:
// - Resource ID
// - len(metadata)
// - metadata
function executeDeposit(bytes memory data) public _onlyBridge {
bytes32 resourceID;
bytes memory metaData;
bytes4 functionSignature;
assembly {
// These are all fixed 32 bytes
// first 32 bytes of bytes is the length
Expand All @@ -158,16 +159,15 @@ contract GenericHandler is IGenericHandler {
0x64, // copy from calldata after data length declaration at 0x64
sub(calldatasize(), 0x64) // copy size (calldatasize - 0x64)
)

functionSignature := mload(add(data, 0x60))
}

address contractAddress = _resourceIDToContractAddress[resourceID];
require(_contractWhitelist[contractAddress], "provided contractAddress is not whitelisted");

if (_contractAddressToExecuteFunctionSignature[contractAddress] != bytes4(0) &&
_contractAddressToExecuteFunctionSignature[contractAddress] == functionSignature) {
(bool success,) = contractAddress.call(metaData);
bytes4 sig = _contractAddressToExecuteFunctionSignature[contractAddress];
if (sig != bytes4(0)) {
bytes memory callData = abi.encodePacked(sig, metaData);
(bool success,) = contractAddress.call(callData);
require(success, "delegatecall to contractAddress failed");
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/contractBridge/depositGeneric.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ contract('Bridge - [deposit - Generic]', async (accounts) => {
initialExecuteFunctionSignatures);

depositData = '0x' +
Ethers.utils.hexZeroPad(recipientAddress, 32).substr(2) + // recipientAddress (?? bytes)
initialResourceIDs[0].substr(2) +
Ethers.utils.hexZeroPad(Ethers.utils.hexlify(0), 32).substr(2) // len(metaData) (0 bytes)
Ethers.utils.hexZeroPad(Ethers.utils.hexlify(4), 32).substr(2) // len(metaData)
Ethers.utils.hexZeroPad(Ethers.utils.hexlify(0xdeadbeef), 4).substr(2) // metaData
});

it('Generic deposit can be made', async () => {
Expand Down
7 changes: 3 additions & 4 deletions test/handlers/generic/deposit.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ contract('GenericHandler - [deposit]', async (accounts) => {
initialExecuteFunctionSignatures);

depositData = '0x' +
Ethers.utils.hexZeroPad(recipientAddress, 32).substr(2) + // recipientAddress (?? bytes)
initialResourceIDs[0].substr(2) +
Ethers.utils.hexZeroPad(Ethers.utils.hexlify(0), 32).substr(2) // len(metaData) (0 bytes)
Ethers.utils.hexZeroPad(Ethers.utils.hexlify(4), 32).substr(2) + // len(metaData) (32 bytes)
Ethers.utils.hexZeroPad('0xdeadbeef', 4).substr(2) // metadata (4 bytes)
});

it('deposit can be made successfully', async () => {
Expand All @@ -67,9 +67,8 @@ contract('GenericHandler - [deposit]', async (accounts) => {
const expectedDepositRecord = {
_destinationChainID: chainID,
_resourceID: initialResourceIDs[0],
_destinationRecipientAddress: recipientAddress,
_depositer: depositerAddress,
_metaData: null
_metaData: '0xdeadbeef'
};

TruffleAssert.passes(await BridgeInstance.deposit(
Expand Down
6 changes: 2 additions & 4 deletions test/handlers/generic/executeDeposit.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ contract('GenericHandler - [deposit]', async (accounts) => {
const blankFunctionSig = '0x00000000';
const centrifugeAssetFuncSig = Ethers.utils.keccak256(Ethers.utils.hexlify(Ethers.utils.toUtf8Bytes('store(bytes32)'))).substr(0, 10);

let RelayerInstance;
let BridgeInstance;
let CentrifugeAssetInstance;
let initialResourceIDs;
Expand Down Expand Up @@ -56,15 +55,14 @@ contract('GenericHandler - [deposit]', async (accounts) => {
initialExecuteFunctionSignatures);

depositData = '0x' +
Ethers.utils.hexZeroPad(recipientAddress, 32).substr(2) + // recipientAddress (?? bytes)
initialResourceIDs[0].substr(2) +
Ethers.utils.hexZeroPad(Ethers.utils.hexlify(36), 32).substr(2) + // len(metaData) (36 bytes)
centrifugeAssetFuncSig.substr(2) + hashOfCentrifugeAsset.substr(2)
hashOfCentrifugeAsset.substr(2)

depositProposalData = '0x' +
initialResourceIDs[0].substr(2) +
Ethers.utils.hexZeroPad(Ethers.utils.hexlify(36), 32).substr(2) + // len(metaData) (36 bytes)
centrifugeAssetFuncSig.substr(2) + hashOfCentrifugeAsset.substr(2)
hashOfCentrifugeAsset.substr(2)
depositProposalDataHash = Ethers.utils.keccak256(GenericHandlerInstance.address + depositProposalData.substr(2));
});

Expand Down

0 comments on commit 31d1924

Please sign in to comment.