Skip to content
Open
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
11 changes: 4 additions & 7 deletions contracts/protocol/Socket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ contract Socket is SocketUtils {
// check if the call type is valid
if (executeParams_.callType != WRITE) revert InvalidCallType();

PlugConfigEvm memory plugConfig = _plugConfigs[executeParams_.target];
PlugConfigEvm storage plugConfig = _plugConfigs[executeParams_.target];
// check if the plug is disconnected
if (plugConfig.appGatewayId == bytes32(0)) revert PlugNotFound();

Expand All @@ -85,7 +85,6 @@ contract Socket is SocketUtils {

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

return _execute(payloadId, executeParams_, transmissionParams_);
}

Expand All @@ -101,6 +100,7 @@ contract Socket is SocketUtils {
if (isValidSwitchboard[plugConfig_.switchboardId] != SwitchboardStatus.REGISTERED)
revert InvalidSwitchboard();

// NOTE: the first un-trusted call in the system
address transmitter = ISwitchboard(switchboardAddresses[plugConfig_.switchboardId])
.getTransmitter(msg.sender, payloadId_, transmitterProof_);

Expand All @@ -114,7 +114,6 @@ contract Socket is SocketUtils {
);
payloadIdToDigest[payloadId_] = digest;

// NOTE: is the the first un-trusted call in the system, another one is Plug.call
if (
!ISwitchboard(switchboardAddresses[plugConfig_.switchboardId]).allowPayload(
digest,
Expand Down Expand Up @@ -158,9 +157,8 @@ contract Socket is SocketUtils {
} else {
payloadExecuted[payloadId_] = ExecutionStatus.Reverted;

address receiver = transmissionParams_.refundAddress == address(0)
? msg.sender
: transmissionParams_.refundAddress;
address receiver = transmissionParams_.refundAddress;
if (receiver == address(0)) receiver = msg.sender;
SafeTransferLib.forceSafeTransferETH(receiver, msg.value);
emit ExecutionFailed(payloadId_, exceededMaxCopy, returnData);
}
Expand Down Expand Up @@ -230,7 +228,6 @@ contract Socket is SocketUtils {

/// @notice Receive function that forwards all calls to Socket's callAppGateway
receive() external payable {
// todo: need a fn to increase trigger fees
revert("Socket does not accept ETH");
}
}
19 changes: 11 additions & 8 deletions contracts/protocol/SocketConfig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,25 @@ abstract contract SocketConfig is ISocket, AccessControl {
emit SwitchboardDisabled(switchboardId_);
}

// @notice function to enable a switchboard
// @notice function to enable a switchboard if disabled
// @dev only callable by governance role
function enableSwitchboard(uint64 switchboardId_) external onlyRole(GOVERNANCE_ROLE) {
isValidSwitchboard[switchboardId_] = SwitchboardStatus.REGISTERED;
emit SwitchboardEnabled(switchboardId_);
}

// @notice function to set the socket fee manager
// @dev only callable by governance role
// @param socketFeeManager_ address of the socket fee manager
function setSocketFeeManager(address socketFeeManager_) external onlyRole(GOVERNANCE_ROLE) {
emit SocketFeeManagerUpdated(address(socketFeeManager), socketFeeManager_);
socketFeeManager = ISocketFeeManager(socketFeeManager_);
emit SocketFeeManagerUpdated(address(socketFeeManager), socketFeeManager_);
Comment on lines +89 to +94
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Fix event parameter order.

The documentation improvements are good, but the event emission has incorrect parameter order. socketFeeManager is the new value, not the old one.

-        emit SocketFeeManagerUpdated(address(socketFeeManager), socketFeeManager_);
+        emit SocketFeeManagerUpdated(address(socketFeeManager), address(socketFeeManager_));

Wait, this needs verification of the event signature first.


🏁 Script executed:

#!/bin/bash
# Check the SocketFeeManagerUpdated event signature to verify parameter order
rg -A 3 "event SocketFeeManagerUpdated"

Length of output: 371


Fix event emission in setSocketFeeManager to use old and new manager addresses correctly

The current implementation emits the updated address for both oldSocketFeeManager and newSocketFeeManager. You must capture the old value before overwriting state and then emit the event with the correct parameters.

• File: contracts/protocol/SocketConfig.sol
• Location: setSocketFeeManager (around lines 89–94)

@@ contracts/protocol/SocketConfig.sol:89-94
-    function setSocketFeeManager(address socketFeeManager_) external onlyRole(GOVERNANCE_ROLE) {
-        socketFeeManager = ISocketFeeManager(socketFeeManager_);
-        emit SocketFeeManagerUpdated(address(socketFeeManager), socketFeeManager_);
+    function setSocketFeeManager(address socketFeeManager_) external onlyRole(GOVERNANCE_ROLE) {
+        address oldSocketFeeManager = address(socketFeeManager);
+        socketFeeManager = ISocketFeeManager(socketFeeManager_);
+        emit SocketFeeManagerUpdated(oldSocketFeeManager, socketFeeManager_);

This should ensure oldSocketFeeManager reflects the previous manager and newSocketFeeManager the newly assigned one.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// @notice function to set the socket fee manager
// @dev only callable by governance role
// @param socketFeeManager_ address of the socket fee manager
function setSocketFeeManager(address socketFeeManager_) external onlyRole(GOVERNANCE_ROLE) {
emit SocketFeeManagerUpdated(address(socketFeeManager), socketFeeManager_);
socketFeeManager = ISocketFeeManager(socketFeeManager_);
emit SocketFeeManagerUpdated(address(socketFeeManager), socketFeeManager_);
// @notice function to set the socket fee manager
// @dev only callable by governance role
// @param socketFeeManager_ address of the socket fee manager
function setSocketFeeManager(address socketFeeManager_) external onlyRole(GOVERNANCE_ROLE) {
// capture the previous manager before updating
address oldSocketFeeManager = address(socketFeeManager);
socketFeeManager = ISocketFeeManager(socketFeeManager_);
emit SocketFeeManagerUpdated(oldSocketFeeManager, socketFeeManager_);
}
🤖 Prompt for AI Agents
In contracts/protocol/SocketConfig.sol around lines 89 to 94, the
setSocketFeeManager function emits the SocketFeeManagerUpdated event using the
updated socketFeeManager address for both old and new values. To fix this, store
the current socketFeeManager address in a local variable before updating it,
then emit the event with the old address as the first argument and the new
address as the second argument.

}

/**
* @notice connects Plug to Socket and sets the config for given `siblingChainSlug_`
*/
// @notice function to connect a plug to socket
// @dev only callable by plug
// @param appGatewayId_ app gateway id
// @param switchboardId_ switchboard id
function connect(bytes32 appGatewayId_, uint64 switchboardId_) external override {
if (isValidSwitchboard[switchboardId_] != SwitchboardStatus.REGISTERED)
revert InvalidSwitchboard();
Expand All @@ -105,9 +109,8 @@ abstract contract SocketConfig is ISocket, AccessControl {
emit PlugConnected(msg.sender, appGatewayId_, switchboardId_);
}

/**
* @notice disconnects Plug from Socket
*/
// @notice function to disconnect a plug from socket
// @dev only callable by plug
function disconnect() external override {
PlugConfigEvm storage _plugConfig = _plugConfigs[msg.sender];
if (_plugConfig.appGatewayId == bytes32(0)) revert PlugNotConnected();
Expand Down
15 changes: 0 additions & 15 deletions contracts/protocol/SocketUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,6 @@ abstract contract SocketUtils is SocketConfig {
);
}

/**
* @notice recovers the signer from the signature
* @param digest_ The digest of the payload
* @param signature_ The signature of the payload
* @return signer The address of the signer
*/
function _recoverSigner(
bytes32 digest_,
bytes calldata signature_
) internal view returns (address signer) {
bytes32 digest = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", digest_));
// recovered signer is checked for the valid roles later
signer = ECDSA.recover(digest, signature_);
}

/**
* @notice Encodes the trigger ID with the chain slug, socket address and nonce
* @return The trigger ID
Expand Down
25 changes: 24 additions & 1 deletion contracts/utils/RescueFundsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ import "solady/utils/SafeTransferLib.sol";
import {ZeroAddress, InvalidTokenAddress} from "./common/Errors.sol";
import {ETH_ADDRESS} from "./common/Constants.sol";

interface IERC721 {
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}

interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

/**
* @title RescueFundsLib
* @dev A library that provides a function to rescue funds from a contract.
Expand All @@ -23,7 +36,17 @@ library RescueFundsLib {
SafeTransferLib.forceSafeTransferETH(rescueTo_, amount_);
} else {
if (token_.code.length == 0) revert InvalidTokenAddress();
SafeTransferLib.safeTransfer(token_, rescueTo_, amount_);

// Identify if a token is an NFT (ERC721) by checking if it supports the ERC721 interface
try IERC165(token_).supportsInterface(0x80ac58cd) returns (bool isERC721) {
if (isERC721)
IERC721(token_).safeTransferFrom(address(this), rescueTo_, amount_, "");
else {
SafeTransferLib.safeTransfer(token_, rescueTo_, amount_);
}
} catch {
SafeTransferLib.safeTransfer(token_, rescueTo_, amount_);
}
}
}
}
42 changes: 29 additions & 13 deletions test/SetupTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1130,21 +1130,45 @@ contract WatcherSetup is AuctionSetup {
) internal {
// Count valid plugs first. In some cases we might have contractIds such that oly a subset is
// deployed on a chain. for ex, vault on source, and supertoken on destination.
uint256 validPlugCount = 0;
uint256 validPlugCount = _countValidPlugs(appGateway_, contractIds_, chainSlug_);

// Create array with exact size needed
AppGatewayConfig[] memory configs = new AppGatewayConfig[](validPlugCount);
_populateConfigs(configs, appGateway_, contractIds_, chainSlug_);

// Only call watcher if we have valid configs
if (validPlugCount > 0) {
watcherMultiCall(
address(configurations),
abi.encodeWithSelector(Configurations.setAppGatewayConfigs.selector, configs)
);
}
}

function _countValidPlugs(
IAppGateway appGateway_,
bytes32[] memory contractIds_,
uint32 chainSlug_
) internal view returns (uint256 validCount) {
for (uint i = 0; i < contractIds_.length; i++) {
bytes32 plug = appGateway_.getOnChainAddress(contractIds_[i], chainSlug_);
if (plug != bytes32(0)) {
validPlugCount++;
validCount++;
}
}
}

// Create array with exact size needed
AppGatewayConfig[] memory configs = new AppGatewayConfig[](validPlugCount);
function _populateConfigs(
AppGatewayConfig[] memory configs,
IAppGateway appGateway_,
bytes32[] memory contractIds_,
uint32 chainSlug_
) internal view {
uint256 configIndex = 0;
uint64 switchboardId = configurations.switchboards(chainSlug_, appGateway_.sbType());

for (uint i = 0; i < contractIds_.length; i++) {
bytes32 plug = appGateway_.getOnChainAddress(contractIds_[i], chainSlug_);
uint64 switchboardId = configurations.switchboards(chainSlug_, appGateway_.sbType());
if (plug != bytes32(0)) {
configs[configIndex] = AppGatewayConfig({
plug: plug,
Expand All @@ -1157,14 +1181,6 @@ contract WatcherSetup is AuctionSetup {
configIndex++;
}
}

// Only call watcher if we have valid configs
if (validPlugCount > 0) {
watcherMultiCall(
address(configurations),
abi.encodeWithSelector(Configurations.setAppGatewayConfigs.selector, configs)
);
}
}
}

Expand Down
Loading