编译器
0.8.18+commit.87f61d96
文件 1 的 20:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 20:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 3 的 20:AssetForwarder.sol
pragma solidity 0.8.18;
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./ReentrancyGuard.sol";
import "./interfaces/IAssetForwarder.sol";
import "./interfaces/IWETH.sol";
import "./interfaces/ITokenMessenger.sol";
import "./interfaces/IMessageHandler.sol";
import "./MultiCaller.sol";
contract AssetForwarder is
AccessControl,
ReentrancyGuard,
Pausable,
IAssetForwarder,
MultiCaller
{
using SafeERC20 for IERC20;
IWETH public immutable wrappedNativeToken;
bytes32 public routerMiddlewareBase;
address public gatewayContract;
address public usdc;
ITokenMessenger public tokenMessenger;
uint256 public depositNonce;
mapping(bytes32 => DestDetails) public destDetails;
uint256 public constant MAX_TRANSFER_SIZE = 1e36;
bytes32 public constant RESOURCE_SETTER = keccak256("RESOURCE_SETTER");
bytes32 public constant PAUSER = keccak256("PAUSER");
mapping(bytes32 => bool) public executeRecord;
uint256 public MIN_GAS_THRESHHOLD;
uint256 public pauseStakeAmountMin;
uint256 public pauseStakeAmountMax;
uint256 public totalStakedAmount;
bool public isCommunityPauseEnabled = true;
address private constant NATIVE_ADDRESS =
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
event CommunityPaused(address indexed pauser, uint256 stakedAmount);
error MessageAlreadyExecuted();
error InvalidGateway();
error InvalidRequestSender();
error InvalidRefundData();
error InvalidAmount();
error AmountTooLarge();
error MessageExcecutionFailedWithLowGas();
error InvalidFee();
constructor(
address _wrappedNativeTokenAddress,
address _gatewayContract,
address _usdcAddress,
address _tokenMessenger,
bytes memory _routerMiddlewareBase,
uint _minGasThreshhold
) {
wrappedNativeToken = IWETH(_wrappedNativeTokenAddress);
tokenMessenger = ITokenMessenger(_tokenMessenger);
gatewayContract = _gatewayContract;
usdc = _usdcAddress;
routerMiddlewareBase = keccak256(_routerMiddlewareBase);
MIN_GAS_THRESHHOLD = _minGasThreshhold;
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(RESOURCE_SETTER, msg.sender);
_grantRole(PAUSER, msg.sender);
}
function update(
uint index,
address _gatewayContract,
bytes calldata _routerMiddlewareBase,
uint256 minPauseStakeAmount,
uint256 maxPauseStakeAmount
) public onlyRole(RESOURCE_SETTER) {
if (index == 1) {
gatewayContract = _gatewayContract;
} else if (index == 2) {
routerMiddlewareBase = keccak256(_routerMiddlewareBase);
} else if (index == 3) {
require(
minPauseStakeAmount <= maxPauseStakeAmount,
"minPauseStakeAmount must be less than or equal to maxPauseStakeAmount"
);
pauseStakeAmountMin = minPauseStakeAmount;
pauseStakeAmountMax = maxPauseStakeAmount;
}
}
function updateTokenMessenger(
address _tokenMessenger
) external onlyRole(RESOURCE_SETTER) {
tokenMessenger = ITokenMessenger(_tokenMessenger);
}
function pause() external onlyRole(PAUSER) whenNotPaused {
_pause();
}
function unpause() external onlyRole(PAUSER) whenPaused {
_unpause();
}
function isNative(address token) internal pure returns (bool) {
return token == NATIVE_ADDRESS;
}
function setDestDetails(
bytes32[] memory _destChainIdBytes,
DestDetails[] memory _destDetails
) public onlyRole(RESOURCE_SETTER) {
require(
_destChainIdBytes.length == _destDetails.length,
"invalid length"
);
for (uint256 idx = 0; idx < _destDetails.length; idx++) {
destDetails[_destChainIdBytes[idx]] = _destDetails[idx];
}
}
function iDepositUSDC(
uint256 partnerId,
bytes32 destChainIdBytes,
bytes32 recipient,
uint256 amount
) external payable nonReentrant whenNotPaused {
require(
destDetails[destChainIdBytes].isSet && usdc != address(0),
"usdc not supported either on src on dst chain"
);
if (msg.value != destDetails[destChainIdBytes].fee) revert InvalidFee();
if (amount > MAX_TRANSFER_SIZE) revert AmountTooLarge();
IERC20(usdc).safeTransferFrom(msg.sender, address(this), amount);
IERC20(usdc).safeIncreaseAllowance(address(tokenMessenger), amount);
uint64 nonce = tokenMessenger.depositForBurn(
amount,
destDetails[destChainIdBytes].domainId,
recipient,
usdc
);
emit iUSDCDeposited(
partnerId,
amount,
destChainIdBytes,
nonce,
usdc,
recipient,
msg.sender
);
}
function iDeposit(
DepositData memory depositData,
bytes memory destToken,
bytes memory recipient
) external payable nonReentrant whenNotPaused {
if (depositData.amount > MAX_TRANSFER_SIZE) revert AmountTooLarge();
if (isNative(depositData.srcToken)) {
if (depositData.amount != msg.value) revert InvalidAmount();
wrappedNativeToken.deposit{value: msg.value}();
depositData.srcToken = address(wrappedNativeToken);
} else {
IERC20(depositData.srcToken).safeTransferFrom(
msg.sender,
address(this),
depositData.amount
);
}
emit FundsDeposited(
depositData.partnerId,
depositData.amount,
depositData.destChainIdBytes,
depositData.destAmount,
++depositNonce,
depositData.srcToken,
depositData.refundRecipient,
recipient,
destToken
);
}
function iDepositInfoUpdate(
address srcToken,
uint256 feeAmount,
uint256 depositId,
bool initiatewithdrawal
) external payable nonReentrant whenNotPaused {
if (initiatewithdrawal) {
assert(msg.value == 0);
emit DepositInfoUpdate(
srcToken,
0,
depositId,
++depositNonce,
true,
msg.sender
);
return;
}
if (feeAmount > MAX_TRANSFER_SIZE) revert AmountTooLarge();
if (isNative(srcToken)) {
if (feeAmount != msg.value) revert InvalidAmount();
wrappedNativeToken.deposit{value: msg.value}();
srcToken = address(wrappedNativeToken);
} else {
IERC20(srcToken).safeTransferFrom(
msg.sender,
address(this),
feeAmount
);
}
emit DepositInfoUpdate(
srcToken,
feeAmount,
depositId,
++depositNonce,
false,
msg.sender
);
}
function iDepositMessage(
DepositData memory depositData,
bytes memory destToken,
bytes memory recipient,
bytes memory message
) external payable nonReentrant whenNotPaused {
if (depositData.amount > MAX_TRANSFER_SIZE) revert AmountTooLarge();
if (isNative(depositData.srcToken)) {
if (depositData.amount != msg.value) revert InvalidAmount();
wrappedNativeToken.deposit{value: msg.value}();
depositData.srcToken = address(wrappedNativeToken);
} else {
IERC20(depositData.srcToken).safeTransferFrom(
msg.sender,
address(this),
depositData.amount
);
}
emit FundsDepositedWithMessage(
depositData.partnerId,
depositData.amount,
depositData.destChainIdBytes,
depositData.destAmount,
++depositNonce,
depositData.srcToken,
recipient,
depositData.refundRecipient,
destToken,
message
);
}
function iRelay(
RelayData memory relayData
) external payable nonReentrant whenNotPaused {
if (relayData.amount > MAX_TRANSFER_SIZE) revert AmountTooLarge();
bytes32 messageHash = keccak256(
abi.encode(
relayData.amount,
relayData.srcChainId,
relayData.depositId,
relayData.destToken,
relayData.recipient,
address(this)
)
);
if (executeRecord[messageHash]) revert MessageAlreadyExecuted();
executeRecord[messageHash] = true;
if (isNative(relayData.destToken)) {
if (relayData.amount != msg.value) revert InvalidAmount();
payable(relayData.recipient).transfer(relayData.amount);
} else {
IERC20(relayData.destToken).safeTransferFrom(
msg.sender,
relayData.recipient,
relayData.amount
);
}
emit FundsPaid(messageHash, msg.sender, ++depositNonce);
}
function iRelayMessage(
RelayDataMessage memory relayData
) external payable nonReentrant whenNotPaused {
if (relayData.amount > MAX_TRANSFER_SIZE) revert AmountTooLarge();
bytes32 messageHash = keccak256(
abi.encode(
relayData.amount,
relayData.srcChainId,
relayData.depositId,
relayData.destToken,
relayData.recipient,
address(this),
relayData.message
)
);
if (executeRecord[messageHash]) revert MessageAlreadyExecuted();
executeRecord[messageHash] = true;
if (isNative(relayData.destToken)) {
if (relayData.amount != msg.value) revert InvalidAmount();
payable(relayData.recipient).transfer(relayData.amount);
} else {
IERC20(relayData.destToken).safeTransferFrom(
msg.sender,
relayData.recipient,
relayData.amount
);
}
bytes memory execData;
bool execFlag;
if (isContract(relayData.recipient) && relayData.message.length > 0) {
(execFlag, execData) = relayData.recipient.call(
abi.encodeWithSelector(
IMessageHandler.handleMessage.selector,
relayData.destToken,
relayData.amount,
relayData.message
)
);
if (!execFlag && gasleft() < MIN_GAS_THRESHHOLD)
revert MessageExcecutionFailedWithLowGas();
}
emit FundsPaidWithMessage(
messageHash,
msg.sender,
++depositNonce,
execFlag,
execData
);
}
function iReceive(
string calldata requestSender,
bytes memory packet,
string calldata
) external returns (bytes memory) {
if (msg.sender != address(gatewayContract)) revert InvalidGateway();
if (routerMiddlewareBase != keccak256(bytes(requestSender)))
revert InvalidRequestSender();
(
address recipient,
address[] memory tokens,
uint256[] memory amounts
) = abi.decode(packet, (address, address[], uint256[]));
uint256 count = tokens.length;
if (count != amounts.length) revert InvalidRefundData();
for (uint256 i = 0; i < count; i++) {
if (!isNative(tokens[i]))
IERC20(tokens[i]).safeTransfer(recipient, amounts[i]);
else payable(recipient).transfer(amounts[i]);
}
return "";
}
function isContract(address addr) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(addr)
}
return size > 0;
}
function rescue(
address token
) external onlyRole(DEFAULT_ADMIN_ROLE) nonReentrant {
if (isNative(token)) {
payable(msg.sender).transfer(address(this).balance);
} else {
IERC20(token).safeTransfer(
msg.sender,
IERC20(token).balanceOf(address(this))
);
}
}
function toggleCommunityPause() external onlyRole(DEFAULT_ADMIN_ROLE) {
isCommunityPauseEnabled = !isCommunityPauseEnabled;
}
function communityPause() external payable whenNotPaused {
require(isCommunityPauseEnabled, "Community pause is disabled");
require(
pauseStakeAmountMin != 0 && pauseStakeAmountMax != 0,
"Set Stake Amount Range"
);
require(
msg.value >= pauseStakeAmountMin &&
msg.value <= pauseStakeAmountMax,
"Stake amount out of range"
);
uint256 newTotalStakedAmount = totalStakedAmount + msg.value;
totalStakedAmount = newTotalStakedAmount;
_pause();
emit CommunityPaused(msg.sender, msg.value);
}
function withdrawStakeAmount() external onlyRole(DEFAULT_ADMIN_ROLE) {
require(
address(this).balance >= totalStakedAmount,
"Insufficient funds"
);
uint256 withdrawalAmount = totalStakedAmount;
totalStakedAmount = 0;
payable(msg.sender).transfer(withdrawalAmount);
}
}
文件 4 的 20:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 5 的 20:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 20:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 7 的 20:IAssetForwarder.sol
pragma solidity 0.8.18;
interface IAssetForwarder {
event FundsDeposited(
uint256 partnerId,
uint256 amount,
bytes32 destChainIdBytes,
uint256 destAmount,
uint256 depositId,
address srcToken,
address depositor,
bytes recipient,
bytes destToken
);
event iUSDCDeposited(
uint256 partnerId,
uint256 amount,
bytes32 destChainIdBytes,
uint256 usdcNonce,
address srcToken,
bytes32 recipient,
address depositor
);
event FundsDepositedWithMessage(
uint256 partnerId,
uint256 amount,
bytes32 destChainIdBytes,
uint256 destAmount,
uint256 depositId,
address srcToken,
bytes recipient,
address depositor,
bytes destToken,
bytes message
);
event FundsPaid(bytes32 messageHash, address forwarder, uint256 nonce);
event DepositInfoUpdate(
address srcToken,
uint256 feeAmount,
uint256 depositId,
uint256 eventNonce,
bool initiatewithdrawal,
address depositor
);
event FundsPaidWithMessage(
bytes32 messageHash,
address forwarder,
uint256 nonce,
bool execFlag,
bytes execData
);
struct DestDetails {
uint32 domainId;
uint256 fee;
bool isSet;
}
struct RelayData {
uint256 amount;
bytes32 srcChainId;
uint256 depositId;
address destToken;
address recipient;
}
struct RelayDataMessage {
uint256 amount;
bytes32 srcChainId;
uint256 depositId;
address destToken;
address recipient;
bytes message;
}
struct DepositData {
uint256 partnerId;
uint256 amount;
uint256 destAmount;
address srcToken;
address refundRecipient;
bytes32 destChainIdBytes;
}
function iDepositUSDC(
uint256 partnerId,
bytes32 destChainIdBytes,
bytes32 recipient,
uint256 amount
) external payable;
function iDeposit(
DepositData memory depositData,
bytes memory destToken,
bytes memory recipient
) external payable;
function iDepositInfoUpdate(
address srcToken,
uint256 feeAmount,
uint256 depositId,
bool initiatewithdrawal
) external payable;
function iDepositMessage(
DepositData memory depositData,
bytes memory destToken,
bytes memory recipient,
bytes memory message
) external payable;
function iRelay(RelayData memory relayData) external payable;
function iRelayMessage(RelayDataMessage memory relayData) external payable;
}
文件 8 的 20:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 9 的 20:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 10 的 20:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 11 的 20:IMessageHandler.sol
pragma solidity 0.8.18;
interface IMessageHandler {
function handleMessage(
address tokenSent,
uint256 amount,
bytes memory message
) external;
}
文件 12 的 20:ITokenMessenger.sol
pragma solidity 0.8.18;
interface ITokenMessenger {
function depositForBurn(
uint256 _amount,
uint32 _destinationDomain,
bytes32 _mintRecipient,
address _burnToken
) external returns (uint64);
function depositForBurnWithCaller(
uint256 _amount,
uint32 _destinationDomain,
bytes32 _mintRecipient,
address _burnToken,
bytes32 _destinationCaller
) external returns (uint64);
function replaceDepositForBurn(
bytes memory originalMessage,
bytes calldata originalAttestation,
bytes32 _destCaller,
bytes32 _mintRecipient
) external;
}
文件 13 的 20:IWETH.sol
pragma solidity 0.8.18;
interface IWETH {
function deposit() external payable;
function transfer(address to, uint256 value) external returns (bool);
function withdraw(uint256) external;
function transferFrom(
address src,
address dst,
uint256 wad
) external returns (bool);
function approve(address guy, uint256 wad) external returns (bool);
}
文件 14 的 20:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 15 的 20:MultiCaller.sol
pragma solidity ^0.8.0;
contract MultiCaller {
function multicall(bytes[] calldata data) external returns (bytes[] memory results) {
results = new bytes[](data.length);
for (uint256 i = 0; i < data.length; i++) {
(bool success, bytes memory result) = address(this).delegatecall(data[i]);
if (!success) {
if (result.length < 68) revert();
assembly {
result := add(result, 0x04)
}
revert(abi.decode(result, (string)));
}
results[i] = result;
}
}
}
文件 16 的 20:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 17 的 20:ReentrancyGuard.sol
pragma solidity 0.8.18;
contract ReentrancyGuard {
bool internal _notEntered;
constructor() {
_notEntered = true;
}
modifier nonReentrant() {
_preEntranceCheck();
_preEntranceSet();
_;
_postEntranceReset();
}
modifier nonReentrantView() {
_preEntranceCheck();
_;
}
function functionCallStackOriginatesFromOutsideThisContract()
internal
view
returns (bool)
{
return _notEntered;
}
function _preEntranceCheck() internal view {
require(_notEntered, "ReentrancyGuard: reentrant call");
}
function _preEntranceSet() internal {
_notEntered = false;
}
function _postEntranceReset() internal {
_notEntered = true;
}
}
文件 18 的 20:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 19 的 20:SignedMath.sol
pragma solidity ^0.8.0;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 20 的 20:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
{
"compilationTarget": {
"src/AssetForwarder.sol": "AssetForwarder"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 999999
},
"remappings": [
":@openzeppelin/=node_modules/@openzeppelin/",
":@routerprotocol/evm-gateway-contracts/=lib/router-gateway-contracts/evm/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/",
":fx-portal/=lib/contracts/contracts/"
]
}
[{"inputs":[{"internalType":"address","name":"_wrappedNativeTokenAddress","type":"address"},{"internalType":"address","name":"_gatewayContract","type":"address"},{"internalType":"address","name":"_usdcAddress","type":"address"},{"internalType":"address","name":"_tokenMessenger","type":"address"},{"internalType":"bytes","name":"_routerMiddlewareBase","type":"bytes"},{"internalType":"uint256","name":"_minGasThreshhold","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AmountTooLarge","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidFee","type":"error"},{"inputs":[],"name":"InvalidGateway","type":"error"},{"inputs":[],"name":"InvalidRefundData","type":"error"},{"inputs":[],"name":"InvalidRequestSender","type":"error"},{"inputs":[],"name":"MessageAlreadyExecuted","type":"error"},{"inputs":[],"name":"MessageExcecutionFailedWithLowGas","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pauser","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAmount","type":"uint256"}],"name":"CommunityPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"srcToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"eventNonce","type":"uint256"},{"indexed":false,"internalType":"bool","name":"initiatewithdrawal","type":"bool"},{"indexed":false,"internalType":"address","name":"depositor","type":"address"}],"name":"DepositInfoUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"partnerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"destAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositId","type":"uint256"},{"indexed":false,"internalType":"address","name":"srcToken","type":"address"},{"indexed":false,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"bytes","name":"recipient","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"destToken","type":"bytes"}],"name":"FundsDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"partnerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"destAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositId","type":"uint256"},{"indexed":false,"internalType":"address","name":"srcToken","type":"address"},{"indexed":false,"internalType":"bytes","name":"recipient","type":"bytes"},{"indexed":false,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"bytes","name":"destToken","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"FundsDepositedWithMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"forwarder","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"FundsPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"forwarder","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"bool","name":"execFlag","type":"bool"},{"indexed":false,"internalType":"bytes","name":"execData","type":"bytes"}],"name":"FundsPaidWithMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"partnerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"usdcNonce","type":"uint256"},{"indexed":false,"internalType":"address","name":"srcToken","type":"address"},{"indexed":false,"internalType":"bytes32","name":"recipient","type":"bytes32"},{"indexed":false,"internalType":"address","name":"depositor","type":"address"}],"name":"iUSDCDeposited","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TRANSFER_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_GAS_THRESHHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESOURCE_SETTER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"communityPause","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"depositNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"destDetails","outputs":[{"internalType":"uint32","name":"domainId","type":"uint32"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bool","name":"isSet","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"executeRecord","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gatewayContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"partnerId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"refundRecipient","type":"address"},{"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"}],"internalType":"struct IAssetForwarder.DepositData","name":"depositData","type":"tuple"},{"internalType":"bytes","name":"destToken","type":"bytes"},{"internalType":"bytes","name":"recipient","type":"bytes"}],"name":"iDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"depositId","type":"uint256"},{"internalType":"bool","name":"initiatewithdrawal","type":"bool"}],"name":"iDepositInfoUpdate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"partnerId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"refundRecipient","type":"address"},{"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"}],"internalType":"struct IAssetForwarder.DepositData","name":"depositData","type":"tuple"},{"internalType":"bytes","name":"destToken","type":"bytes"},{"internalType":"bytes","name":"recipient","type":"bytes"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"iDepositMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"partnerId","type":"uint256"},{"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"iDepositUSDC","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"requestSender","type":"string"},{"internalType":"bytes","name":"packet","type":"bytes"},{"internalType":"string","name":"","type":"string"}],"name":"iReceive","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"srcChainId","type":"bytes32"},{"internalType":"uint256","name":"depositId","type":"uint256"},{"internalType":"address","name":"destToken","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"internalType":"struct IAssetForwarder.RelayData","name":"relayData","type":"tuple"}],"name":"iRelay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"srcChainId","type":"bytes32"},{"internalType":"uint256","name":"depositId","type":"uint256"},{"internalType":"address","name":"destToken","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct IAssetForwarder.RelayDataMessage","name":"relayData","type":"tuple"}],"name":"iRelayMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"isCommunityPauseEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauseStakeAmountMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseStakeAmountMin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"routerMiddlewareBase","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_destChainIdBytes","type":"bytes32[]"},{"components":[{"internalType":"uint32","name":"domainId","type":"uint32"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bool","name":"isSet","type":"bool"}],"internalType":"struct IAssetForwarder.DestDetails[]","name":"_destDetails","type":"tuple[]"}],"name":"setDestDetails","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleCommunityPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenMessenger","outputs":[{"internalType":"contract ITokenMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"_gatewayContract","type":"address"},{"internalType":"bytes","name":"_routerMiddlewareBase","type":"bytes"},{"internalType":"uint256","name":"minPauseStakeAmount","type":"uint256"},{"internalType":"uint256","name":"maxPauseStakeAmount","type":"uint256"}],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenMessenger","type":"address"}],"name":"updateTokenMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawStakeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrappedNativeToken","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"}]