Skip to content

Commit

Permalink
massive update
Browse files Browse the repository at this point in the history
  • Loading branch information
SecretSaturn committed Jan 2, 2024
1 parent 6e4447b commit 2ac8012
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 169 deletions.
2 changes: 1 addition & 1 deletion TNLS-Gateways/public-gateway/script/DeployScript.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ contract DeployScript is Script {

string memory route = "secret";
//address verificationAddress = vm.envAddress("SECRET_GATEWAY_ETH_ADDRESS");
address verificationAddress = 0xc1eE8F16231399d91667a49526914D0B27116130;
address verificationAddress = 0xb5F2Ef4a09acf294D2deDAE1fC84aDaF83ae49c5;

// Update the route with with masterVerificationKey signature
bytes32 routeHash = getRouteHash(route, verificationAddress);
Expand Down
155 changes: 61 additions & 94 deletions TNLS-Gateways/public-gateway/src/Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,8 @@ contract Gateway {
Structs
//////////////////////////////////////////////////////////////*/

struct Task {
address callback_address;
bytes4 callback_selector;
uint32 callback_gas_limit;
address user_address;
bool completed;
bytes32 payload_hash;
string source_network;
string routing_info;
}

struct ReducedTask {
bytes32 payload_hash;
address callback_address;
bytes4 callback_selector;
uint32 callback_gas_limit;
bytes31 payload_hash_reduced;
bool completed;
}

Expand All @@ -38,11 +24,14 @@ contract Gateway {

struct PostExecutionInfo {
bytes32 payload_hash;
bytes result;
bytes32 result_hash;
bytes result_signature;
bytes32 packet_hash;
bytes20 callback_address;
bytes4 callback_selector;
bytes4 callback_gas_limit;
bytes packet_signature;
bytes result_signature;
bytes result;
}

/*//////////////////////////////////////////////////////////////
Expand All @@ -58,7 +47,7 @@ contract Gateway {
/// @notice thrown when the signature is invalid
error InvalidSignature();

/// @notice Thrown when the ResultSignature is invalid
/// @notice Thrown when the recovered ResultHash or ResultSignature is invalid
error InvalidResultSignature();

/// @notice thrown when the PacketSignature is invalid
Expand Down Expand Up @@ -102,23 +91,17 @@ contract Gateway {
return ecrecover(_signedMessageHash, v, r, s);
}

/// @notice Hashes the encoded message hash
/// @param _messageHash the message hash
function getEthSignedMessageHash(bytes32 _messageHash) private pure returns (bytes32) {
/*
Signature is produced by signing a keccak256 hash with the following format:
"\x19Ethereum Signed Message\n" + len(msg) + msg
*/
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash));
}

/// @notice Get the encoded hash of the inputs for signing
/// @param _routeInput Route name
/// @param _verificationAddressInput Address corresponding to the route
function getRouteHash(string calldata _routeInput, address _verificationAddressInput) private pure returns (bytes32) {
return keccak256(abi.encode(_routeInput, _verificationAddressInput));
}

function sliceLastByte(bytes32 data) private pure returns (bytes31) {
return bytes31(data & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00);
}

/*//////////////////////////////////////////////////////////////
Events
//////////////////////////////////////////////////////////////*/
Expand All @@ -128,14 +111,8 @@ contract Gateway {
string source_network,
address user_address,
string routing_info,
string routing_code_hash,
bytes payload,
bytes32 payload_hash,
bytes payload_signature,
bytes user_key,
bytes user_pubkey,
string handle,
bytes12 nonce
ExecutionInfo info
);

event logCompletedTask(uint256 indexed task_id, bytes32 payload_hash, bytes32 result_hash);
Expand All @@ -147,7 +124,7 @@ contract Gateway {
Constructor
//////////////////////////////////////////////////////////////*/

address public immutable owner;
address private immutable owner;

constructor() {
owner = msg.sender;
Expand Down Expand Up @@ -175,19 +152,17 @@ contract Gateway {
//////////////////////////////////////////////////////////////*/

/// @dev mapping of chain name string to the verification address
mapping(string => address) public route;
mapping(string => address) private route;

/// @notice Updating the route
/// @param _route Route name
/// @param _verificationAddress Address corresponding to the route
/// @param _signature Signed hashed inputs(_route + _verificationAddress)
function updateRoute(string calldata _route, address _verificationAddress, bytes calldata _signature) external onlyOwner {
bytes32 routeHash = getRouteHash(_route, _verificationAddress);
bytes32 ethSignedMessageHash = getEthSignedMessageHash(routeHash);

bool verifySig = recoverSigner(ethSignedMessageHash, _signature) == masterVerificationAddress;
bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", routeHash));

if (!verifySig) {
if (recoverSigner(ethSignedMessageHash, _signature) != masterVerificationAddress) {
revert InvalidSignature();
}

Expand All @@ -201,37 +176,40 @@ contract Gateway {
uint256 private taskId = 1;

/// @dev Task ID ====> Task
mapping(uint256 => ReducedTask) public tasks;
mapping(uint256 => ReducedTask) private tasks;

/// @notice Pre-Execution
/// @param _task Task struct
/// @notice Send
/// @param _userAddress User address
/// @param _sourceNetwork Source network of msg
/// @param _routingInfo Routing info for computation
/// @param _payloadHash Payload hash
/// @param _info ExecutionInfo struct

function preExecution(Task memory _task, ExecutionInfo memory _info) private {
function send(
bytes32 _payloadHash,
address _userAddress,
string calldata _sourceNetwork,
string calldata _routingInfo,
ExecutionInfo calldata _info)
external {

// Payload hash signature verification

if (recoverSigner(_task.payload_hash, _info.payload_signature) != _task.user_address) {
if (recoverSigner(_payloadHash, _info.payload_signature) != _userAddress) {
revert InvalidSignature();
}

// persisting the task
tasks[taskId] = ReducedTask(_task.payload_hash, _task.callback_address, _task.callback_selector, _task.callback_gas_limit, false);
tasks[taskId] = ReducedTask(sliceLastByte(_payloadHash), false);

emit logNewTask(
taskId,
_task.source_network,
_task.user_address,
_task.routing_info,
_info.routing_code_hash,
_info.payload,
_task.payload_hash,
_info.payload_signature,
_info.user_key,
_info.user_pubkey,
_info.handle,
_info.nonce
);
_sourceNetwork,
_userAddress,
_routingInfo,
_payloadHash,
_info
);

taskId++;
}
Expand All @@ -246,69 +224,58 @@ contract Gateway {
/// @param _info PostExecutionInfo struct

function postExecution(uint256 _taskId, string calldata _sourceNetwork, PostExecutionInfo calldata _info) external {
// First, check if the task is already completed
ReducedTask memory task = tasks[_taskId];

ReducedTask storage task = tasks[_taskId];

// Check if the task is already completed
if (task.completed) {
revert TaskAlreadyCompleted();
}

address checkerAddress = route[_sourceNetwork];

// Payload hash verification from tasks struct
if (_info.payload_hash != task.payload_hash) {
if (sliceLastByte(_info.payload_hash) != task.payload_hash_reduced) {
revert InvalidPayloadHash();
}

address checkerAddress = route[_sourceNetwork];

// Result signature verification
if (recoverSigner(_info.result_hash, _info.result_signature) != checkerAddress) {
revert InvalidResultSignature();
}

// Concatenate data elements
bytes memory data = bytes.concat(
bytes(_sourceNetwork),
bytes32(_taskId),
bytes32(_info.payload_hash),
bytes(_info.result),
bytes32(_info.result_hash),
bytes(_info.result_signature[:64]), //we need to remove the last RecoveryID byte (65 bytes -> 64 bytes) because this wasn't included in the original signature (we added it later on)
bytes20(_info.callback_address),
bytes4(_info.callback_selector));

// Perform Keccak256 + sha256 hash
bytes32 packetHash = sha256(abi.encodePacked(keccak256(data)));

// Packet signature verification
if (recoverSigner(_info.packet_hash, _info.packet_signature) != checkerAddress) {
if ((_info.packet_hash != packetHash) || recoverSigner(_info.packet_hash, _info.packet_signature) != checkerAddress) {
revert InvalidPacketSignature();
}

tasks[_taskId].completed = true;
tasks[_taskId].payload_hash = bytes32(0);
task.completed = true;

emit logCompletedTask(_taskId, _info.payload_hash, _info.result_hash);

// Continue with the function execution

(bool val, ) = address(task.callback_address).call{gas: task.callback_gas_limit}(
abi.encodeWithSelector(task.callback_selector, _taskId, _info.result)
(bool val, ) = address(_info.callback_address).call{gas: uint32(_info.callback_gas_limit)}(
abi.encodeWithSelector(_info.callback_selector, _taskId, _info.result)
);
if (!val) {
revert CallbackError();
}
}

/// @param _userAddress User address
/// @param _sourceNetwork Source network of msg
/// @param _routingInfo Routing info for computation
/// @param _payloadHash Payload hash
/// @param _info ExecutionInfo struct
/// @param _callbackAddress Callback Address for Post-Execution
/// @param _callbackSelector Callback Selector for Post-Execution
/// @param _callbackGasLimit Callback Gas Limit for Post-Execution

function send(
address _userAddress,
string calldata _sourceNetwork,
string calldata _routingInfo,
bytes32 _payloadHash,
ExecutionInfo calldata _info,
address _callbackAddress,
bytes4 _callbackSelector,
uint32 _callbackGasLimit
)
external
{
preExecution(Task(_callbackAddress, _callbackSelector, _callbackGasLimit ,_userAddress, false, _payloadHash, _sourceNetwork, _routingInfo), _info);
}

/*//////////////////////////////////////////////////////////////
Callback
//////////////////////////////////////////////////////////////*/
Expand Down
43 changes: 8 additions & 35 deletions TNLS-Gateways/public-gateway/test/Contract.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,36 +62,6 @@ contract ContractTest is Test {

}

/// @notice Recover the signer from message hash with a missing recovery ID
/// @param _signedMessageHash the signed message hash
/// @param _signature The signature that needs to be verified

function checkSignerForMissingRecoveryID(bytes32 _signedMessageHash, bytes memory _signature, address _checkingAddress) private pure returns (bool) {
//recover signature

bytes32 r;
bytes32 s;

assembly {
// first 32 bytes, after the length prefix
r := mload(add(_signature, 32))
// second 32 bytes
s := mload(add(_signature, 64))
}

//calculate both ecrecover(_signedMessageHash, v, r, s) for v = 27 and v = 28, casted as uint8

if (ecrecover(_signedMessageHash, uint8(27), r, s) == _checkingAddress) {
return true;
}
else if (ecrecover(_signedMessageHash, uint8(28), r, s) == _checkingAddress) {
return true;
}
else {
return false;
}
}

/// @notice Hashes the encoded message hash
/// @param _messageHash the message hash
function getEthSignedMessageHash(bytes32 _messageHash) internal pure returns (bytes32) {
Expand Down Expand Up @@ -296,6 +266,7 @@ contract ContractTest is Test {
routing_code_hash: "some RoutingCodeHash",
handle: "some kinda handle",
nonce: "ssssssssssss",
payload_encrypted: true,
payload: payload,
payload_signature: getPayloadSignature(payload, 5)
});
Expand Down Expand Up @@ -340,6 +311,7 @@ contract ContractTest is Test {
routing_code_hash: "some RoutingCodeHash",
handle: "some kinda handle",
nonce: "ssssssssssss",
payload_encrypted: true,
payload: payload,
payload_signature: getPayloadSignature(payload, 7)
});
Expand Down Expand Up @@ -419,7 +391,7 @@ contract ContractTest is Test {
function test_PreExecutionSetupForExplicitCase() public {
// CALLBACK ADDRESS -----> vm.addr(7);

bytes4 callbackSelector = bytes4(abi.encodeWithSignature("callback(uint256 _taskId, bytes calldata _result)"));
bytes4 callbackSelector = bytes4(0xb2bcfb71);
string memory sourceNetwork = "ethereum";
address userAddress = 0x49F7552065228e5abF44e144cc750aEA4F711Dc3;

Expand All @@ -441,11 +413,12 @@ contract ContractTest is Test {
routing_code_hash: "some RoutingCodeHash",
handle: "some kinda handle",
nonce: "ssssssssssss",
payload_encrypted: true,
payload: payload,
payload_signature: payloadSignature
});

gateway.send(userAddress, sourceNetwork,routingInfo, payloadHash, assembledInfo, address(gateway), gateway.callback.selector, 300000 );
gateway.send(userAddress, sourceNetwork,routingInfo, payloadHash, assembledInfo, address(gateway), callbackSelector, 300000 );

(bytes32 tempPayloadHash,,,,) = gateway.tasks(1);
assertEq(tempPayloadHash, payloadHash);
Expand All @@ -454,7 +427,7 @@ contract ContractTest is Test {
assertEq(tempCallbackAddress, address(gateway));

(,,bytes4 tempCallbackSelector,,) = gateway.tasks(1);
assertEq(tempCallbackSelector, gateway.callback.selector);
assertEq(tempCallbackSelector, callbackSelector);

(,,,, bool tempCompleted) = gateway.tasks(1);
assertEq(tempCompleted, false);
Expand Down Expand Up @@ -497,12 +470,12 @@ contract ContractTest is Test {
bytes memory result = hex"7b226d795f76616c7565223a327d";
bytes32 resultHash = hex"faef40ffa988468a70a21929200a40f1c8ea9f56fcf79a206ef9713032c4e28b";
bytes memory resultSignature =
hex"faad4e82fe9a6a05ef2a4387fca5471fe3bc7b53e81a3c08d4a5514ac7c6fddf2a266cf1c638654c156612a1943dbaf278105f138c5be67ab1eca4253c57ca7f";
hex"faad4e82fe9a6a05ef2a4387fca5471fe3bc7b53e81a3c08d4a5514ac7c6fddf2a266cf1c638654c156612a1943dbaf278105f138c5be67ab1eca4253c57ca7f1b";

// packet
bytes32 packetHash = hex"923b23c023d0e5e66ac122d9804414f4f9cab06d7a6ce6c4b8c586a1fa57264c";
bytes memory packetSignature =
hex"2db95ebb82b81f8240d952e1c6edf021e098de63d32f1f0d3bbbb7daf0e9edbd3378fc42e31d1041467c76388a35078968f1f6f2eb781b5b83054a1d90ba41ff";
hex"2db95ebb82b81f8240d952e1c6edf021e098de63d32f1f0d3bbbb7daf0e9edbd3378fc42e31d1041467c76388a35078968f1f6f2eb781b5b83054a1d90ba41ff1c";

Gateway.PostExecutionInfo memory assembledInfo = Gateway.PostExecutionInfo({
payload_hash: payloadHash,
Expand Down
Binary file modified TNLS-Gateways/secret/contract.wasm.gz
Binary file not shown.
Loading

0 comments on commit 2ac8012

Please sign in to comment.