Skip to content

Commit

Permalink
Merge pull request #250 from SocketDotTech/fix/hash-chain-capacitor
Browse files Browse the repository at this point in the history
fix: hash chain capacitor
  • Loading branch information
ameeshaagrawal committed Jun 22, 2023
2 parents 9dd87c4 + 10a0ada commit 1a4f19d
Show file tree
Hide file tree
Showing 33 changed files with 2,929 additions and 637 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ src/types
typechain-types/

.env
.DS_Store
.DS_Store

.gas-snapshot/
scripts/deploy/gasEstimate.ts
4 changes: 2 additions & 2 deletions contracts/CapacitorFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ contract CapacitorFactory is ICapacitorFactory, AccessControl {
function deploy(
uint256 capacitorType_,
uint32 /** siblingChainSlug */,
uint256 /** maxPacketLength */
uint256 maxPacketLength_
) external override returns (ICapacitor, IDecapacitor) {
// sets the capacitor factory owner
address owner = this.owner();
Expand All @@ -54,7 +54,7 @@ contract CapacitorFactory is ICapacitorFactory, AccessControl {
if (capacitorType_ == HASH_CHAIN_CAPACITOR) {
return (
// msg.sender is socket address
new HashChainCapacitor(msg.sender, owner),
new HashChainCapacitor(msg.sender, owner, maxPacketLength_),
new HashChainDecapacitor(owner)
);
}
Expand Down
159 changes: 139 additions & 20 deletions contracts/ExecutionManager.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.7;

import "./interfaces/IExecutionManager.sol";
import "./interfaces/ISignatureVerifier.sol";
import "./libraries/RescueFundsLib.sol";
Expand All @@ -17,6 +16,7 @@ import {FEES_UPDATE_SIG_IDENTIFIER, RELATIVE_NATIVE_TOKEN_PRICE_UPDATE_SIG_IDENT
*/
contract ExecutionManager is IExecutionManager, AccessControlExtended {
ISignatureVerifier public immutable signatureVerifier__;
uint32 public immutable chainSlug;

/**
* @notice Emitted when the executionFees is updated
Expand All @@ -39,14 +39,24 @@ contract ExecutionManager is IExecutionManager, AccessControlExtended {
uint256 msgValueMinThresholdSet
);

uint32 public immutable chainSlug;
struct TotalTransmissionAndExecutionFees {
uint128 totalTransmissionFees;
uint128 totalExecutionFees;
}

mapping(uint32 => TotalTransmissionAndExecutionFees)
public totalTransmissionExecutionFees;

mapping(address => mapping(uint32 => uint128)) public totalSwitchboardFees;

// transmitter => nextNonce
mapping(address => uint256) public nextNonce;

// remoteChainSlug => executionFees
mapping(uint32 => uint256) public executionFees;

mapping(address => mapping(uint32 => uint128)) transmissionMinFees;

// destSlug => relativeNativePrice (stores (destnativeTokenPriceUSD*(1e18)/srcNativeTokenPriceUSD))
mapping(uint32 => uint256) public relativeNativeTokenPrice;

Expand All @@ -63,6 +73,7 @@ contract ExecutionManager is IExecutionManager, AccessControlExtended {
error MsgValueTooHigh();
error PayloadTooLarge();
error InsufficientMsgValue();
error InsufficientFees();

/**
* @dev Constructor for ExecutionManager contract
Expand Down Expand Up @@ -101,35 +112,130 @@ contract ExecutionManager is IExecutionManager, AccessControlExtended {
/**
* @dev Function to be used for on-chain fee distribution later
*/
function updateExecutionFees(address, uint256, bytes32) external override {}
function updateExecutionFees(address, uint128, bytes32) external override {}

/**
* @notice Function for paying fees for cross-chain transaction execution
* @param msgGasLimit_ Gas limit for the transaction
* @param siblingChainSlug_ Sibling chain identifier
*/
function payFees(
function updateTransmissionMinFees(
uint32 remoteChainSlug_,
uint128 fees_
) external override {
transmissionMinFees[msg.sender][remoteChainSlug_] = fees_;
}

function payAndCheckFees(
uint256 msgGasLimit_,
uint32 siblingChainSlug_
) external payable override {}
uint256 payloadSize_,
bytes32 executionParams_,
uint32 siblingChainSlug_,
uint128 switchboardFees_,
uint128 verificationFees_,
address transmitManager_,
address switchboard_,
uint256 maxPacketLength_
)
external
payable
override
returns (uint128 executionFee, uint128 transmissionFees)
{
transmissionFees =
transmissionMinFees[transmitManager_][siblingChainSlug_] /
uint128(maxPacketLength_);

uint128 minMsgExecutionFees = uint128(
_getMinFees(
msgGasLimit_,
payloadSize_,
executionParams_,
siblingChainSlug_
)
);
uint128 minExecutionFees = minMsgExecutionFees + verificationFees_;
if (msg.value < transmissionFees + switchboardFees_ + minExecutionFees)
revert InsufficientFees();

executionFee;

// any extra fee is considered as executionFee
// Have to recheck overflow/underflow conditions here
executionFee = uint128(
msg.value - uint256(transmissionFees) - uint256(switchboardFees_)
);

TotalTransmissionAndExecutionFees
memory currentTotalFees = totalTransmissionExecutionFees[
siblingChainSlug_
];
totalTransmissionExecutionFees[
siblingChainSlug_
] = TotalTransmissionAndExecutionFees({
totalTransmissionFees: currentTotalFees.totalTransmissionFees +
transmissionFees,
totalExecutionFees: currentTotalFees.totalExecutionFees +
executionFee
});
totalSwitchboardFees[switchboard_][
siblingChainSlug_
] += switchboardFees_;
}

/**
* @notice Function for getting the minimum fees required for executing a cross-chain transaction
* @dev This function is called at source to calculate the execution cost.
* @param siblingChainSlug_ Sibling chain identifier
* @param payloadSize_ byte length of payload. Currently only used to check max length, later on will be used for fees calculation.
* @param extraParams_ Can be used for providing extra information. Currently used for msgValue
* @return Minimum fees required for executing the transaction
* @param executionParams_ Can be used for providing extra information. Currently used for msgValue
* @return minExecutionFee : Minimum fees required for executing the transaction
*/
function getMinFees(
uint256,
uint256 gasLimit_,
uint256 payloadSize_,
bytes32 extraParams_,
bytes32 executionParams_,
uint32 siblingChainSlug_
) external view override returns (uint256) {
) external view override returns (uint128 minExecutionFee) {
minExecutionFee = uint128(
_getMinFees(
gasLimit_,
payloadSize_,
executionParams_,
siblingChainSlug_
)
);
}

function getExecutionTransmissionMinFees(
uint256 msgGasLimit_,
uint256 payloadSize_,
bytes32 executionParams_,
uint32 siblingChainSlug_,
address transmitManager_
)
external
view
override
returns (uint128 minExecutionFee, uint128 transmissionFees)
{
minExecutionFee = uint128(
_getMinFees(
msgGasLimit_,
payloadSize_,
executionParams_,
siblingChainSlug_
)
);
transmissionFees = transmissionMinFees[transmitManager_][
siblingChainSlug_
];
}

function _getMinFees(
uint256 gasLimit_,
uint256 payloadSize_,
bytes32 executionParams_,
uint32 siblingChainSlug_
) internal view returns (uint256) {
if (payloadSize_ > 3000) revert PayloadTooLarge();

uint256 params = uint256(extraParams_);
uint256 params = uint256(executionParams_);
uint8 paramType = uint8(params >> 248);

if (paramType == 0) return executionFees[siblingChainSlug_];
Expand All @@ -148,10 +254,10 @@ contract ExecutionManager is IExecutionManager, AccessControlExtended {
}

function verifyParams(
bytes32 extraParams_,
bytes32 executionParams_,
uint256 msgValue_
) external pure override {
uint256 params = uint256(extraParams_);
uint256 params = uint256(executionParams_);
uint8 paramType = uint8(params >> 248);

if (paramType == 0) return;
Expand All @@ -164,7 +270,7 @@ contract ExecutionManager is IExecutionManager, AccessControlExtended {
function setExecutionFees(
uint256 nonce_,
uint32 dstChainSlug_,
uint256 executionFees_,
uint128 executionFees_,
bytes calldata signature_
) external override {
address feesUpdater = signatureVerifier__.recoverSigner(
Expand Down Expand Up @@ -282,6 +388,19 @@ contract ExecutionManager is IExecutionManager, AccessControlExtended {
FeesHelper.withdrawFees(account_);
}

function withdrawSwitchboardFees(
uint32 siblingChainSlug_,
uint128 amount_
) external override {
require(
totalSwitchboardFees[msg.sender][siblingChainSlug_] >= amount_,
"Insufficient Fees"
);
totalSwitchboardFees[msg.sender][siblingChainSlug_] -= amount_;
(bool success, ) = msg.sender.call{value: amount_}("");
require(success, "withdraw switchboard fee failed");
}

/**
* @notice Rescues funds from a contract that has lost access to them.
* @param token_ The address of the token contract.
Expand Down
37 changes: 23 additions & 14 deletions contracts/TransmitManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
pragma solidity 0.8.7;

import "./interfaces/ITransmitManager.sol";
import "./interfaces/IExecutionManager.sol";
import "./interfaces/ISignatureVerifier.sol";

import "./utils/AccessControlExtended.sol";
import "./libraries/RescueFundsLib.sol";
import "./libraries/FeesHelper.sol";
Expand All @@ -17,6 +17,7 @@ import {FEES_UPDATE_SIG_IDENTIFIER} from "./utils/SigIdentifiers.sol";
* @dev This contract inherits AccessControlExtended which manages access control
*/
contract TransmitManager is ITransmitManager, AccessControlExtended {
IExecutionManager public executionManager__;
ISignatureVerifier public signatureVerifier__;

uint32 public immutable chainSlug;
Expand All @@ -25,7 +26,7 @@ contract TransmitManager is ITransmitManager, AccessControlExtended {
mapping(address => uint256) public nextNonce;

// remoteChainSlug => transmissionFees
mapping(uint32 => uint256) public transmissionFees;
// mapping(uint32 => uint128) public transmissionFees;

error InsufficientTransmitFees();
error InvalidNonce();
Expand All @@ -35,6 +36,7 @@ contract TransmitManager is ITransmitManager, AccessControlExtended {
* @param signatureVerifier The address of the new signature verifier contract
*/
event SignatureVerifierSet(address signatureVerifier);
event ExecutionManagerSet(address executionManager);

/**
* @notice Emitted when the transmissionFees is updated
Expand All @@ -51,11 +53,13 @@ contract TransmitManager is ITransmitManager, AccessControlExtended {
*/
constructor(
ISignatureVerifier signatureVerifier_,
address executionManager_,
address owner_,
uint32 chainSlug_
) AccessControlExtended(owner_) {
chainSlug = chainSlug_;
signatureVerifier__ = signatureVerifier_;
executionManager__ = IExecutionManager(executionManager_);
}

/**
Expand Down Expand Up @@ -89,20 +93,10 @@ contract TransmitManager is ITransmitManager, AccessControlExtended {
*/
function payFees(uint32 siblingChainSlug_) external payable override {}

/**
* @notice calculates fees for the given sibling slug
* @param siblingChainSlug_ sibling id
*/
function getMinFees(
uint32 siblingChainSlug_
) external view override returns (uint256) {
return transmissionFees[siblingChainSlug_];
}

function setTransmissionFees(
uint256 nonce_,
uint32 dstChainSlug_,
uint256 transmissionFees_,
uint128 transmissionFees_,
bytes calldata signature_
) external override {
address feesUpdater = signatureVerifier__.recoverSigner(
Expand All @@ -123,7 +117,11 @@ contract TransmitManager is ITransmitManager, AccessControlExtended {

if (nonce_ != nextNonce[feesUpdater]++) revert InvalidNonce();

transmissionFees[dstChainSlug_] = transmissionFees_;
// transmissionFees[dstChainSlug_] = transmissionFees_;
executionManager__.updateTransmissionMinFees(
dstChainSlug_,
transmissionFees_
);
emit TransmissionFeesSet(dstChainSlug_, transmissionFees_);
}

Expand All @@ -146,6 +144,17 @@ contract TransmitManager is ITransmitManager, AccessControlExtended {
emit SignatureVerifierSet(signatureVerifier_);
}

/**
* @notice updates signatureVerifier_
* @param executionManager_ address of Signature Verifier
*/
function setExecutionManager(
address executionManager_
) external onlyRole(GOVERNANCE_ROLE) {
executionManager__ = IExecutionManager(executionManager_);
emit ExecutionManagerSet(executionManager_);
}

/**
* @notice Rescues funds from a contract that has lost access to them.
* @param token_ The address of the token contract.
Expand Down
Loading

0 comments on commit 1a4f19d

Please sign in to comment.