Skip to content
Merged

Fixes #182

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
4 changes: 4 additions & 0 deletions contracts/evmx/plugs/FeesPlug.sol
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ contract FeesPlug is IFeesPlug, PlugBase, AccessControl {
_connectSocket(appGatewayId_, socket_, switchboardId_);
}

function disconnectSocket() external onlyOwner {
socket__.disconnect();
}

/**
* @notice Rescues funds from the contract if they are locked by mistake. This contract does not
* theoretically need this function but it is added for safety.
Expand Down
39 changes: 26 additions & 13 deletions contracts/protocol/Socket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ contract Socket is SocketUtils {
// @notice mapping of payload id to execution status
mapping(bytes32 => bytes32) public payloadIdToDigest;

// @notice buffer to account for gas used by current contract execution
uint256 private constant GAS_LIMIT_BUFFER = 105;

////////////////////////////////////////////////////////
////////////////////// ERRORS //////////////////////////
////////////////////////////////////////////////////////
Expand Down Expand Up @@ -53,7 +50,9 @@ contract Socket is SocketUtils {
uint32 chainSlug_,
address owner_,
string memory version_
) SocketUtils(chainSlug_, owner_, version_) {}
) SocketUtils(chainSlug_, owner_, version_) {
gasLimitBuffer = 105;
}

/**
* @notice Executes a payload that has been delivered by transmitters and authenticated by switchboards
Expand Down Expand Up @@ -136,7 +135,7 @@ contract Socket is SocketUtils {
) internal returns (bool success, bytes memory returnData) {
// check if the gas limit is sufficient
// bump by 5% to account for gas used by current contract execution
if (gasleft() < (executeParams_.gasLimit * GAS_LIMIT_BUFFER) / 100) revert LowGasLimit();
if (gasleft() < (executeParams_.gasLimit * gasLimitBuffer) / 100) revert LowGasLimit();

// NOTE: external un-trusted call
bool exceededMaxCopy;
Expand Down Expand Up @@ -180,44 +179,58 @@ contract Socket is SocketUtils {
////////////////////////////////////////////////////////
////////////////////// Trigger //////////////////////
////////////////////////////////////////////////////////

/// @notice To trigger to a connected remote chain. Should only be called by a plug.
function triggerAppGateway(bytes calldata data_) external payable returns (bytes32 triggerId) {
triggerId = _triggerAppGateway(msg.sender, msg.value, data_);
}

/**
* @notice To trigger to a connected remote chain. Should only be called by a plug.
*/
function _triggerAppGateway(address plug_) internal returns (bytes32 triggerId) {
function _triggerAppGateway(
address plug_,
uint256 value_,
bytes calldata data_
) internal returns (bytes32 triggerId) {
PlugConfigEvm memory plugConfig = _plugConfigs[plug_];

// if no sibling plug is found for the given chain slug, revert
if (plugConfig.appGatewayId == bytes32(0)) revert PlugNotFound();
if (isValidSwitchboard[plugConfig.switchboardId] != SwitchboardStatus.REGISTERED)
revert InvalidSwitchboard();

bytes memory plugOverrides = IPlug(msg.sender).overrides();
bytes memory plugOverrides = IPlug(plug_).overrides();
triggerId = _encodeTriggerId();

// todo: need gas limit?
ISwitchboard(switchboardAddresses[plugConfig.switchboardId]).processTrigger{
value: msg.value
}(msg.sender, triggerId, msg.data, plugOverrides);
ISwitchboard(switchboardAddresses[plugConfig.switchboardId]).processTrigger{value: value_}(
plug_,
triggerId,
data_,
plugOverrides
);

emit AppGatewayCallRequested(
triggerId,
plugConfig.appGatewayId,
plugConfig.switchboardId,
toBytes32Format(plug_),
plugOverrides,
msg.data
data_
);
}

/// @notice Fallback function that forwards all calls to Socket's callAppGateway
/// @dev The calldata is passed as-is to the gateways
fallback(bytes calldata) external payable returns (bytes memory) {
// return the trigger id
return abi.encode(_triggerAppGateway(msg.sender));
return abi.encode(_triggerAppGateway(msg.sender, msg.value, msg.data));
}

/// @notice Receive function that forwards all calls to Socket's callAppGateway
receive() external payable {
// todo: handle receive
// todo: need a fn to increase trigger fees
revert("Socket does not accept ETH");
}
}
25 changes: 25 additions & 0 deletions contracts/protocol/SocketConfig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,21 @@ abstract contract SocketConfig is ISocket, AccessControl {
// @notice mapping of switchboard address to its id
mapping(address => uint64) public switchboardIds;

// @notice buffer to account for gas used by current contract execution
uint256 public gasLimitBuffer;

// @notice error triggered when a switchboard already exists
error SwitchboardExists();
// @notice error triggered when a plug is not connected
error PlugNotConnected();

// @notice event triggered when a new switchboard is added
event SwitchboardAdded(address switchboard, uint64 switchboardId);
// @notice event triggered when a switchboard is disabled
event SwitchboardDisabled(uint64 switchboardId);
// @notice event triggered when a switchboard is enabled
event SwitchboardEnabled(uint64 switchboardId);
// @notice event triggered when a socket fee manager is updated
event SocketFeeManagerUpdated(address oldSocketFeeManager, address newSocketFeeManager);

// @notice function to register a switchboard
Expand Down Expand Up @@ -99,6 +105,25 @@ abstract contract SocketConfig is ISocket, AccessControl {
emit PlugConnected(msg.sender, appGatewayId_, switchboardId_);
}

/**
* @notice disconnects Plug from Socket
*/
function disconnect() external override {
PlugConfigEvm storage _plugConfig = _plugConfigs[msg.sender];
if (_plugConfig.appGatewayId == bytes32(0)) revert PlugNotConnected();

_plugConfig.appGatewayId = bytes32(0);
_plugConfig.switchboardId = 0;
emit PlugDisconnected(msg.sender);
}

// @notice function to set the gas limit buffer for socket
// @dev only callable by governance role
// @param gasLimitBuffer_ gas limit buffer for socket
function setGasLimitBuffer(uint256 gasLimitBuffer_) external onlyRole(GOVERNANCE_ROLE) {
gasLimitBuffer = gasLimitBuffer_;
}

// @notice function to set the max copy bytes for socket
// @dev only callable by governance role
// @param maxCopyBytes_ max copy bytes for socket
Expand Down
3 changes: 1 addition & 2 deletions contracts/protocol/base/PlugBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ abstract contract PlugBase is IPlug {

/// @notice Disconnects the plug from the socket
function _disconnectSocket() internal {
(, uint64 switchboardId) = socket__.getPlugConfig(address(this));
socket__.connect(bytes32(0), switchboardId);
socket__.disconnect();
emit ConnectorPlugDisconnected();
}

Expand Down
11 changes: 11 additions & 0 deletions contracts/protocol/interfaces/ISocket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ interface ISocket {
*/
event PlugConnected(address plug, bytes32 appGatewayId, uint64 switchboardId);

/**
* @notice emits the config set by a plug for a remoteChainSlug
* @param plug address of plug on current chain
*/
event PlugDisconnected(address plug);

/**
* @notice emits the payload details when a new payload arrives at outbound
* @param triggerId trigger id
Expand Down Expand Up @@ -64,6 +70,11 @@ interface ISocket {
*/
function connect(bytes32 appGatewayId_, uint64 switchboardId_) external;

/**
* @notice disconnects Plug from Socket
*/
function disconnect() external;

/**
* @notice registers a switchboard for the socket
*/
Expand Down
6 changes: 2 additions & 4 deletions test/FeesTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,9 @@ contract FeesTest is AppGatewayBaseSetup {
}

function testDisconnectFeesPlug() public {
uint64 sbId = arbConfig.switchboard.switchboardId();

// disconnect old fees plug
hoax(socketOwner);
arbConfig.feesPlug.connectSocket(bytes32(0), address(arbConfig.socket), sbId);
arbConfig.feesPlug.disconnectSocket();

hoax(watcherEOA);
feesManager.setFeesPlug(arbChainSlug, bytes32(0));
Expand Down Expand Up @@ -133,7 +131,7 @@ contract FeesTest is AppGatewayBaseSetup {

// disconnect old fees plug
hoax(socketOwner);
oldFeesPlug.connectSocket(bytes32(0), address(arbConfig.socket), sbId);
oldFeesPlug.disconnectSocket();

// deploy new fees plug
arbConfig.feesPlug = new FeesPlug(address(arbConfig.socket), address(socketOwner));
Expand Down
2 changes: 2 additions & 0 deletions test/mock/MockSocket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ contract MockSocket is ISocket {

function connect(bytes32 appGatewayId_, uint64 switchboardId_) external override {}

function disconnect() external override {}

function registerSwitchboard() external override returns (uint64 switchboardId) {}

////////////////////////////////////////////////////////
Expand Down