Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts/evmx/watcher/precompiles/WritePrecompile.sol
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ contract WritePrecompile is WritePrecompileStorage, Initializable, Ownable, Watc
// create digest
DigestParams memory digestParams_ = DigestParams(
configurations__().sockets(transaction.chainSlug),
transmitter_,
toBytes32Format(transmitter_),
payloadParams.payloadId,
deadline,
payloadParams.callType,
Expand Down
48 changes: 27 additions & 21 deletions contracts/protocol/Socket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,39 +83,45 @@ contract Socket is SocketUtils {

// validate the execution status
_validateExecutionStatus(payloadId);
address transmitter = transmissionParams_.transmitterSignature.length > 0
? _recoverSigner(
keccak256(abi.encode(address(this), payloadId)),
transmissionParams_.transmitterSignature
)
: address(0);

// create the digest
// transmitter, payloadId, appGateway, executeParams_ and there contents are validated using digest verification from switchboard
bytes32 digest = _createDigest(
transmitter,
payloadId,
plugConfig.appGatewayId,
executeParams_
);
payloadIdToDigest[payloadId] = digest;

// verify the digest
_verify(digest, payloadId, plugConfig.switchboardId);
_verify(payloadId, plugConfig, executeParams_, transmissionParams_.transmitterProof);

return _execute(payloadId, executeParams_, transmissionParams_);
}

////////////////////////////////////////////////////////
////////////////// INTERNAL FUNCS //////////////////////
////////////////////////////////////////////////////////
function _verify(bytes32 digest_, bytes32 payloadId_, uint64 switchboardId_) internal view {
if (isValidSwitchboard[switchboardId_] != SwitchboardStatus.REGISTERED)
function _verify(
bytes32 payloadId_,
PlugConfigEvm memory plugConfig_,
ExecuteParams calldata executeParams_,
bytes calldata transmitterProof_
) internal {
if (isValidSwitchboard[plugConfig_.switchboardId] != SwitchboardStatus.REGISTERED)
revert InvalidSwitchboard();

address transmitter = ISwitchboard(switchboardAddresses[plugConfig_.switchboardId])
.getTransmitter(msg.sender, payloadId_, transmitterProof_);

// create the digest
// transmitter, payloadId, appGateway, executeParams_ and there contents are validated using digest verification from switchboard
bytes32 digest = _createDigest(
transmitter,
payloadId_,
plugConfig_.appGatewayId,
executeParams_
);
payloadIdToDigest[payloadId_] = digest;

// NOTE: is the the first un-trusted call in the system, another one is Plug.call
if (!ISwitchboard(switchboardAddresses[switchboardId_]).allowPayload(digest_, payloadId_))
revert VerificationFailed();
if (
!ISwitchboard(switchboardAddresses[plugConfig_.switchboardId]).allowPayload(
digest,
payloadId_
)
) revert VerificationFailed();
}

/**
Expand Down
8 changes: 4 additions & 4 deletions contracts/protocol/SocketBatcher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,23 @@ contract SocketBatcher is ISocketBatcher, Ownable {
* @param executeParams_ The execution parameters
* @param digest_ The digest of the payload
* @param proof_ The proof of the payload
* @param transmitterSignature_ The signature of the transmitter
* @param transmitterProof_ The signature of the transmitter
* @return The return data after execution
*/
function attestAndExecute(
ExecuteParams calldata executeParams_,
address switchboard_,
bytes32 digest_,
bytes calldata proof_,
bytes calldata transmitterSignature_,
bytes calldata transmitterProof_,
address refundAddress_
) external payable returns (bool, bytes memory) {
IFastSwitchboard(switchboard_).attest(digest_, proof_);
return
socket__.execute{value: msg.value}(
executeParams_,
TransmissionParams({
transmitterSignature: transmitterSignature_,
transmitterProof: transmitterProof_,
socketFees: 0,
extraData: executeParams_.extraData,
refundAddress: refundAddress_
Expand All @@ -80,7 +80,7 @@ contract SocketBatcher is ISocketBatcher, Ownable {
(bool success, bytes memory returnData) = socket__.execute{value: msg.value}(
execParams_.executeParams,
TransmissionParams({
transmitterSignature: execParams_.transmitterSignature,
transmitterProof: execParams_.transmitterSignature,
socketFees: 0,
extraData: execParams_.executeParams.extraData,
refundAddress: execParams_.refundAddress
Expand Down
2 changes: 1 addition & 1 deletion contracts/protocol/SocketUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ abstract contract SocketUtils is SocketConfig {
keccak256(
abi.encodePacked(
toBytes32Format(address(this)),
transmitter_,
toBytes32Format(transmitter_),
payloadId_,
executeParams_.deadline,
executeParams_.callType,
Expand Down
14 changes: 14 additions & 0 deletions contracts/protocol/interfaces/ISwitchboard.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,18 @@ interface ISwitchboard {
bytes calldata payload_,
bytes calldata overrides_
) external payable;

/**
* @notice Gets the transmitter for a given payload
* @notice Switchboard are required to implement this function to allow for the verification of the transmitters
* @param sender_ The sender of the payload
* @param payloadId_ The payload ID
* @param transmitterSignature_ The transmitter signature
* @return The transmitter address
*/
function getTransmitter(
address sender_,
bytes32 payloadId_,
bytes calldata transmitterSignature_
) external view returns (address);
}
2 changes: 1 addition & 1 deletion contracts/protocol/switchboard/MessageSwitchboard.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ contract MessageSwitchboard is SwitchboardBase {

digestParams = DigestParams({
socket: siblingSockets[dstChainSlug_],
transmitter: address(0),
transmitter: bytes32(0),
payloadId: payloadId,
deadline: block.timestamp + 3600,
callType: WRITE,
Expand Down
13 changes: 13 additions & 0 deletions contracts/protocol/switchboard/SwitchboardBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ abstract contract SwitchboardBase is ISwitchboard, AccessControl {
switchboardId = socket__.registerSwitchboard();
}

function getTransmitter(
address sender_,
bytes32 payloadId_,
bytes calldata transmitterSignature_
) external view returns (address transmitter) {
transmitter = transmitterSignature_.length > 0
? _recoverSigner(
keccak256(abi.encode(address(socket__), payloadId_)),
transmitterSignature_
)
: address(0);
}

/// @notice Recovers the signer from the signature
/// @param digest_ The digest of the payload
/// @param signature_ The signature of the watcher
Expand Down
4 changes: 2 additions & 2 deletions contracts/utils/common/Structs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct TransmissionParams {
uint256 socketFees;
address refundAddress;
bytes extraData;
bytes transmitterSignature;
bytes transmitterProof;
}

struct WatcherMultiCallParams {
Expand Down Expand Up @@ -130,7 +130,7 @@ struct UserCredits {
// digest:
struct DigestParams {
bytes32 socket;
address transmitter;
bytes32 transmitter;
bytes32 payloadId;
uint256 deadline;
bytes4 callType;
Expand Down
6 changes: 3 additions & 3 deletions test/SetupTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ contract WatcherSetup is AuctionSetup {
);
digestParams = DigestParams(
toBytes32Format(address(getSocketConfig(transaction.chainSlug).socket)),
transmitterEOA,
toBytes32Format(transmitterEOA),
payloadParams.payloadId,
payloadParams.deadline,
payloadParams.callType,
Expand Down Expand Up @@ -1396,7 +1396,7 @@ contract MessageSwitchboardSetup is DeploySetup {
bytes memory extraData = abi.encode(srcChainSlug_, toBytes32Format(srcPlug_));
digestParams = DigestParams({
socket: toBytes32Format(dstSocket_),
transmitter: address(0),
transmitter: bytes32(0),
payloadId: payloadId_,
deadline: block.timestamp + 3600,
callType: WRITE,
Expand Down Expand Up @@ -1449,7 +1449,7 @@ contract MessageSwitchboardSetup is DeploySetup {
socketFees: 0,
refundAddress: socketOwner,
extraData: bytes(""),
transmitterSignature: bytes("")
transmitterProof: bytes("")
});

optConfig.socket.execute(executeParams, transmissionParams);
Expand Down
2 changes: 1 addition & 1 deletion test/SocketFeeManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ contract SocketFeeManagerTest is AppGatewayBaseSetup {
});

TransmissionParams memory transmissionParams = TransmissionParams({
transmitterSignature: bytes(""),
transmitterProof: bytes(""),
socketFees: socketFees,
extraData: bytes(""),
refundAddress: transmitterEOA
Expand Down
8 changes: 8 additions & 0 deletions test/mock/MockFastSwitchboard.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,12 @@ contract MockFastSwitchboard is ISwitchboard {
bytes calldata payload_,
bytes calldata overrides_
) external payable override {}

function getTransmitter(
address sender_,
bytes32 payloadId_,
bytes calldata transmitterSignature_
) external view returns (address) {
return sender_;
}
}