Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- ConnectorPlug
- Optimization enabled
- true
- Compiler version
- v0.8.13+commit.abaa5c0e
- Optimization runs
- 999999
- EVM Version
- default
- Verified at
- 2024-10-23T11:38:20.047160Z
Constructor Arguments
0x0000000000000000000000001363aa6d41719736abf5f12ee850a01659b3ea080000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f0000000000000000000000000000000000000000000000000000000000aa37dc0000000000000000000000000000000000000000000000000000000000000000
Arg [0] (address) : 0x1363aa6d41719736abf5f12ee850a01659b3ea08
Arg [1] (address) : 0x5c4186d343eef952c9ed886e45f8243edf0a503f
Arg [2] (uint32) : 11155420
Arg [3] (bytes32) : 0000000000000000000000000000000000000000000000000000000000000000
contracts/ConnectorPlug.sol
// SPDX-License-Identifier: GPL-3.0-only // Sources flattened with hardhat v2.22.4 https://hardhat.org // File contracts/common/Errors.sol pragma solidity 0.8.13; error SiblingNotSupported(); error NotAuthorized(); error NotBridge(); error NotSocket(); error ConnectorUnavailable(); error InvalidPoolId(); error CannotTransferOrExecuteOnBridgeContracts(); error NoPendingData(); error MessageIdMisMatched(); error NotMessageBridge(); error InvalidSiblingChainSlug(); error InvalidTokenContract(); error InvalidExchangeRateContract(); error InvalidConnector(); error InvalidConnectorPoolId(); error ZeroAddressReceiver(); error ZeroAddress(); error ZeroAmount(); error DebtRatioTooHigh(); error NotEnoughAssets(); error VaultShutdown(); error InsufficientFunds(); error PermitDeadlineExpired(); error InvalidSigner(); error InsufficientMsgValue(); error InvalidOptionsLength(); // File contracts/interfaces/IBridge.sol pragma solidity ^0.8.3; interface IBridge { function bridge( address receiver_, uint256 amount_, uint256 msgGasLimit_, address connector_, bytes calldata extraData_, bytes calldata options_ ) external payable; function receiveInbound( uint32 siblingChainSlug_, bytes memory payload_ ) external payable; function retry(address connector_, bytes32 messageId_) external; } // File contracts/interfaces/IConnector.sol pragma solidity ^0.8.13; interface IConnector { function outbound( uint256 msgGasLimit_, bytes memory payload_, bytes memory options_ ) external payable returns (bytes32 messageId_); function siblingChainSlug() external view returns (uint32); function getMinFees( uint256 msgGasLimit_, uint256 payloadSize_ ) external view returns (uint256 totalFees); function getMessageId() external view returns (bytes32); } // File contracts/interfaces/IPlug.sol pragma solidity 0.8.13; /** * @title IPlug * @notice Interface for a plug contract that executes the message received from a source chain. */ interface IPlug { /** * @dev this should be only executable by socket * @notice executes the message received from source chain * @notice It is expected to have original sender checks in the destination plugs using payload * @param srcChainSlug_ chain slug of source * @param payload_ the data which is needed by plug at inbound call on remote */ function inbound( uint32 srcChainSlug_, bytes calldata payload_ ) external payable; } // File contracts/interfaces/ISocket.sol pragma solidity 0.8.13; /** * @title ISocket * @notice An interface for a cross-chain communication contract * @dev This interface provides methods for transmitting and executing messages between chains, * connecting a plug to a remote chain and setting up switchboards for the message transmission * This interface also emits events for important operations such as message transmission, execution status, * and plug connection */ interface ISocket { /** * @notice A struct containing fees required for message transmission and execution * @param transmissionFees fees needed for transmission * @param switchboardFees fees needed by switchboard * @param executionFee fees needed for execution */ struct Fees { uint128 transmissionFees; uint128 executionFee; uint128 switchboardFees; } /** * @title MessageDetails * @dev This struct defines the details of a message to be executed in a Decapacitor contract. */ struct MessageDetails { // A unique identifier for the message. bytes32 msgId; // The fee to be paid for executing the message. uint256 executionFee; // The maximum amount of gas that can be used to execute the message. uint256 minMsgGasLimit; // The extra params which provides msg value and additional info needed for message exec bytes32 executionParams; // The payload data to be executed in the message. bytes payload; } /** * @title ExecutionDetails * @dev This struct defines the execution details */ struct ExecutionDetails { // packet id bytes32 packetId; // proposal count uint256 proposalCount; // gas limit needed to execute inbound uint256 executionGasLimit; // proof data required by the Decapacitor contract to verify the message's authenticity bytes decapacitorProof; // signature of executor bytes signature; } /** * @notice emits the message details when a new message arrives at outbound * @param localChainSlug local chain slug * @param localPlug local plug address * @param dstChainSlug remote chain slug * @param dstPlug remote plug address * @param msgId message id packed with remoteChainSlug and nonce * @param minMsgGasLimit gas limit needed to execute the inbound at remote * @param payload the data which will be used by inbound at remote */ event MessageOutbound( uint32 localChainSlug, address localPlug, uint32 dstChainSlug, address dstPlug, bytes32 msgId, uint256 minMsgGasLimit, bytes32 executionParams, bytes32 transmissionParams, bytes payload, Fees fees ); /** * @notice emits the status of message after inbound call * @param msgId msg id which is executed */ event ExecutionSuccess(bytes32 msgId); /** * @notice emits the config set by a plug for a remoteChainSlug * @param plug address of plug on current chain * @param siblingChainSlug sibling chain slug * @param siblingPlug address of plug on sibling chain * @param inboundSwitchboard inbound switchboard (select from registered options) * @param outboundSwitchboard outbound switchboard (select from registered options) * @param capacitor capacitor selected based on outbound switchboard * @param decapacitor decapacitor selected based on inbound switchboard */ event PlugConnected( address plug, uint32 siblingChainSlug, address siblingPlug, address inboundSwitchboard, address outboundSwitchboard, address capacitor, address decapacitor ); /** * @notice registers a message * @dev Packs the message and includes it in a packet with capacitor * @param remoteChainSlug_ the remote chain slug * @param minMsgGasLimit_ the gas limit needed to execute the payload on remote * @param payload_ the data which is needed by plug at inbound call on remote */ function outbound( uint32 remoteChainSlug_, uint256 minMsgGasLimit_, bytes32 executionParams_, bytes32 transmissionParams_, bytes memory payload_ ) external payable returns (bytes32 msgId); /** * @notice executes a message * @param executionDetails_ the packet details, proof and signature needed for message execution * @param messageDetails_ the message details */ function execute( ISocket.ExecutionDetails calldata executionDetails_, ISocket.MessageDetails calldata messageDetails_ ) external payable; /** * @notice sets the config specific to the plug * @param siblingChainSlug_ the sibling chain slug * @param siblingPlug_ address of plug present at sibling chain to call inbound * @param inboundSwitchboard_ the address of switchboard to use for receiving messages * @param outboundSwitchboard_ the address of switchboard to use for sending messages */ function connect( uint32 siblingChainSlug_, address siblingPlug_, address inboundSwitchboard_, address outboundSwitchboard_ ) external; /** * @notice Retrieves the minimum fees required for a message with a specified gas limit and destination chain. * @param minMsgGasLimit_ The gas limit of the message. * @param remoteChainSlug_ The slug of the destination chain for the message. * @param plug_ The address of the plug through which the message is sent. * @return totalFees The minimum fees required for the specified message. */ function getMinFees( uint256 minMsgGasLimit_, uint256 payloadSize_, bytes32 executionParams_, bytes32 transmissionParams_, uint32 remoteChainSlug_, address plug_ ) external view returns (uint256 totalFees); /** * @notice returns chain slug * @return chainSlug current chain slug */ function chainSlug() external view returns (uint32 chainSlug); function globalMessageCount() external view returns (uint64); /** * @notice returns the config for given `plugAddress_` and `siblingChainSlug_` * @param siblingChainSlug_ the sibling chain slug * @param plugAddress_ address of plug present at current chain */ function getPlugConfig( address plugAddress_, uint32 siblingChainSlug_ ) external view returns ( address siblingPlug, address inboundSwitchboard__, address outboundSwitchboard__, address capacitor__, address decapacitor__ ); } // File contracts/common/Constants.sol pragma solidity 0.8.13; address constant ETH_ADDRESS = address( 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE ); bytes32 constant NORMAL_CONTROLLER = keccak256("NORMAL_CONTROLLER"); bytes32 constant FIAT_TOKEN_CONTROLLER = keccak256("FIAT_TOKEN_CONTROLLER"); bytes32 constant LIMIT_HOOK = keccak256("LIMIT_HOOK"); bytes32 constant LIMIT_EXECUTION_HOOK = keccak256("LIMIT_EXECUTION_HOOK"); bytes32 constant LIMIT_EXECUTION_YIELD_HOOK = keccak256( "LIMIT_EXECUTION_YIELD_HOOK" ); bytes32 constant LIMIT_EXECUTION_YIELD_TOKEN_HOOK = keccak256( "LIMIT_EXECUTION_YIELD_TOKEN_HOOK" ); bytes32 constant ERC20_VAULT = keccak256("ERC20_VAULT"); bytes32 constant NATIVE_VAULT = keccak256("NATIVE_VAULT"); // File lib/solmate/src/tokens/ERC20.sol pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } } // File lib/solmate/src/utils/SafeTransferLib.sol pragma solidity >=0.8.0; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument. mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } } // File contracts/libraries/RescueFundsLib.sol pragma solidity 0.8.13; /** * @title RescueFundsLib * @dev A library that provides a function to rescue funds from a contract. */ library RescueFundsLib { /** * @dev thrown when the given token address don't have any code */ error InvalidTokenAddress(); /** * @dev Rescues funds from a contract. * @param token_ The address of the token contract. * @param rescueTo_ The address of the user. * @param amount_ The amount of tokens to be rescued. */ function rescueFunds( address token_, address rescueTo_, uint256 amount_ ) internal { if (rescueTo_ == address(0)) revert ZeroAddress(); if (token_ == ETH_ADDRESS) { SafeTransferLib.safeTransferETH(rescueTo_, amount_); } else { if (token_.code.length == 0) revert InvalidTokenAddress(); SafeTransferLib.safeTransfer(ERC20(token_), rescueTo_, amount_); } } } // File contracts/utils/Ownable.sol pragma solidity 0.8.13; /** * @title Ownable * @dev The Ownable contract provides a simple way to manage ownership of a contract * and allows for ownership to be transferred to a nominated address. */ abstract contract Ownable { address private _owner; address private _nominee; event OwnerNominated(address indexed nominee); event OwnerClaimed(address indexed claimer); error OnlyOwner(); error OnlyNominee(); /** * @dev Sets the contract's owner to the address that is passed to the constructor. */ constructor(address owner_) { _claimOwner(owner_); } /** * @dev Modifier that restricts access to only the contract's owner. * Throws an error if the caller is not the owner. */ modifier onlyOwner() { if (msg.sender != _owner) revert OnlyOwner(); _; } /** * @dev Returns the current owner of the contract. */ function owner() external view returns (address) { return _owner; } /** * @dev Returns the current nominee for ownership of the contract. */ function nominee() external view returns (address) { return _nominee; } /** * @dev Allows the current owner to nominate a new owner for the contract. * Throws an error if the caller is not the owner. * Emits an `OwnerNominated` event with the address of the nominee. */ function nominateOwner(address nominee_) external { if (msg.sender != _owner) revert OnlyOwner(); _nominee = nominee_; emit OwnerNominated(_nominee); } /** * @dev Allows the nominated owner to claim ownership of the contract. * Throws an error if the caller is not the nominee. * Sets the nominated owner as the new owner of the contract. * Emits an `OwnerClaimed` event with the address of the new owner. */ function claimOwner() external { if (msg.sender != _nominee) revert OnlyNominee(); _claimOwner(msg.sender); } /** * @dev Internal function that sets the owner of the contract to the specified address * and sets the nominee to address(0). */ function _claimOwner(address claimer_) internal { _owner = claimer_; _nominee = address(0); emit OwnerClaimed(claimer_); } } // File contracts/utils/AccessControl.sol pragma solidity 0.8.13; /** * @title AccessControl * @dev This abstract contract implements access control mechanism based on roles. * Each role can have one or more addresses associated with it, which are granted * permission to execute functions with the onlyRole modifier. */ abstract contract AccessControl is Ownable { /** * @dev A mapping of roles to a mapping of addresses to boolean values indicating whether or not they have the role. */ mapping(bytes32 => mapping(address => bool)) private _permits; /** * @dev Emitted when a role is granted to an address. */ event RoleGranted(bytes32 indexed role, address indexed grantee); /** * @dev Emitted when a role is revoked from an address. */ event RoleRevoked(bytes32 indexed role, address indexed revokee); /** * @dev Error message thrown when an address does not have permission to execute a function with onlyRole modifier. */ error NoPermit(bytes32 role); /** * @dev Constructor that sets the owner of the contract. */ constructor(address owner_) Ownable(owner_) {} /** * @dev Modifier that restricts access to addresses having roles * Throws an error if the caller do not have permit */ modifier onlyRole(bytes32 role) { if (!_permits[role][msg.sender]) revert NoPermit(role); _; } /** * @dev Checks and reverts if an address do not have a specific role. * @param role_ The role to check. * @param address_ The address to check. */ function _checkRole(bytes32 role_, address address_) internal virtual { if (!_hasRole(role_, address_)) revert NoPermit(role_); } /** * @dev Grants a role to a given address. * @param role_ The role to grant. * @param grantee_ The address to grant the role to. * Emits a RoleGranted event. * Can only be called by the owner of the contract. */ function grantRole( bytes32 role_, address grantee_ ) external virtual onlyOwner { _grantRole(role_, grantee_); } /** * @dev Revokes a role from a given address. * @param role_ The role to revoke. * @param revokee_ The address to revoke the role from. * Emits a RoleRevoked event. * Can only be called by the owner of the contract. */ function revokeRole( bytes32 role_, address revokee_ ) external virtual onlyOwner { _revokeRole(role_, revokee_); } /** * @dev Internal function to grant a role to a given address. * @param role_ The role to grant. * @param grantee_ The address to grant the role to. * Emits a RoleGranted event. */ function _grantRole(bytes32 role_, address grantee_) internal { _permits[role_][grantee_] = true; emit RoleGranted(role_, grantee_); } /** * @dev Internal function to revoke a role from a given address. * @param role_ The role to revoke. * @param revokee_ The address to revoke the role from. * Emits a RoleRevoked event. */ function _revokeRole(bytes32 role_, address revokee_) internal { _permits[role_][revokee_] = false; emit RoleRevoked(role_, revokee_); } /** * @dev Checks whether an address has a specific role. * @param role_ The role to check. * @param address_ The address to check. * @return A boolean value indicating whether or not the address has the role. */ function hasRole( bytes32 role_, address address_ ) external view returns (bool) { return _hasRole(role_, address_); } function _hasRole( bytes32 role_, address address_ ) internal view returns (bool) { return _permits[role_][address_]; } } // File contracts/utils/RescueBase.sol pragma solidity 0.8.13; /** * @title Base contract for super token and vault * @notice It contains relevant execution payload storages. * @dev This contract implements Socket's IPlug to enable message bridging and IMessageBridge * to support any type of message bridge. */ abstract contract RescueBase is AccessControl { bytes32 constant RESCUE_ROLE = keccak256("RESCUE_ROLE"); /** * @notice Rescues funds from the contract if they are locked by mistake. * @param token_ The address of the token contract. * @param rescueTo_ The address where rescued tokens need to be sent. * @param amount_ The amount of tokens to be rescued. */ function rescueFunds( address token_, address rescueTo_, uint256 amount_ ) external onlyRole(RESCUE_ROLE) { RescueFundsLib.rescueFunds(token_, rescueTo_, amount_); } } // File contracts/ConnectorPlug.sol pragma solidity 0.8.13; contract ConnectorPlug is IConnector, IPlug, RescueBase { IBridge public immutable bridge__; ISocket public immutable socket__; uint32 public immutable siblingChainSlug; bytes32 public immutable transmissionParams; uint256 public messageIdPart; event ConnectorPlugDisconnected(); constructor( address bridge_, address socket_, uint32 siblingChainSlug_, bytes32 transmissionParams_ ) AccessControl(msg.sender) { bridge__ = IBridge(bridge_); socket__ = ISocket(socket_); siblingChainSlug = siblingChainSlug_; transmissionParams = transmissionParams_; _grantRole(RESCUE_ROLE, msg.sender); } function outbound( uint256 msgGasLimit_, bytes memory payload_, bytes memory options_ ) external payable override returns (bytes32 messageId_) { if (msg.sender != address(bridge__)) revert NotBridge(); if (options_.length == 0) { return socket__.outbound{value: msg.value}( siblingChainSlug, msgGasLimit_, bytes32(0), transmissionParams, payload_ ); } else { if (options_.length != 32) revert InvalidOptionsLength(); bytes32 executionParams = abi.decode(options_, (bytes32)); return socket__.outbound{value: msg.value}( siblingChainSlug, msgGasLimit_, executionParams, transmissionParams, payload_ ); } } function inbound( uint32 siblingChainSlug_, // cannot be connected for any other slug, immutable variable bytes calldata payload_ ) external payable override { if (msg.sender != address(socket__)) revert NotSocket(); bridge__.receiveInbound(siblingChainSlug_, payload_); } /** * @notice this function calculates the fees needed to send the message to Socket. * @param msgGasLimit_ min gas limit needed at destination chain to execute the message. */ function getMinFees( uint256 msgGasLimit_, uint256 payloadSize_ ) external view returns (uint256 totalFees) { return socket__.getMinFees( msgGasLimit_, payloadSize_, bytes32(0), bytes32(0), siblingChainSlug, address(this) ); } function connect( address siblingPlug_, address switchboard_ ) external onlyOwner { messageIdPart = (uint256(socket__.chainSlug()) << 224) | (uint256(uint160(siblingPlug_)) << 64); socket__.connect( siblingChainSlug, siblingPlug_, switchboard_, switchboard_ ); } function disconnect() external onlyOwner { messageIdPart = 0; ( , address inboundSwitchboard, address outboundSwitchboard, , ) = socket__.getPlugConfig(address(this), siblingChainSlug); socket__.connect( siblingChainSlug, address(0), inboundSwitchboard, outboundSwitchboard ); emit ConnectorPlugDisconnected(); } /** * @notice this function is used to calculate message id before sending outbound(). * @return messageId */ function getMessageId() external view returns (bytes32) { return bytes32(messageIdPart | (socket__.globalMessageCount())); } }
Compiler Settings
{"outputSelection":{"*":{"*":["*"]}},"optimizer":{"runs":999999,"enabled":true},"libraries":{}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"bridge_","internalType":"address"},{"type":"address","name":"socket_","internalType":"address"},{"type":"uint32","name":"siblingChainSlug_","internalType":"uint32"},{"type":"bytes32","name":"transmissionParams_","internalType":"bytes32"}]},{"type":"error","name":"InvalidOptionsLength","inputs":[]},{"type":"error","name":"InvalidTokenAddress","inputs":[]},{"type":"error","name":"NoPermit","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"error","name":"NotBridge","inputs":[]},{"type":"error","name":"NotSocket","inputs":[]},{"type":"error","name":"OnlyNominee","inputs":[]},{"type":"error","name":"OnlyOwner","inputs":[]},{"type":"error","name":"ZeroAddress","inputs":[]},{"type":"event","name":"ConnectorPlugDisconnected","inputs":[],"anonymous":false},{"type":"event","name":"OwnerClaimed","inputs":[{"type":"address","name":"claimer","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnerNominated","inputs":[{"type":"address","name":"nominee","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"grantee","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"revokee","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IBridge"}],"name":"bridge__","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"connect","inputs":[{"type":"address","name":"siblingPlug_","internalType":"address"},{"type":"address","name":"switchboard_","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disconnect","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getMessageId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"totalFees","internalType":"uint256"}],"name":"getMinFees","inputs":[{"type":"uint256","name":"msgGasLimit_","internalType":"uint256"},{"type":"uint256","name":"payloadSize_","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRole","inputs":[{"type":"bytes32","name":"role_","internalType":"bytes32"},{"type":"address","name":"grantee_","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasRole","inputs":[{"type":"bytes32","name":"role_","internalType":"bytes32"},{"type":"address","name":"address_","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"inbound","inputs":[{"type":"uint32","name":"siblingChainSlug_","internalType":"uint32"},{"type":"bytes","name":"payload_","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"messageIdPart","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"nominateOwner","inputs":[{"type":"address","name":"nominee_","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"nominee","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bytes32","name":"messageId_","internalType":"bytes32"}],"name":"outbound","inputs":[{"type":"uint256","name":"msgGasLimit_","internalType":"uint256"},{"type":"bytes","name":"payload_","internalType":"bytes"},{"type":"bytes","name":"options_","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueFunds","inputs":[{"type":"address","name":"token_","internalType":"address"},{"type":"address","name":"rescueTo_","internalType":"address"},{"type":"uint256","name":"amount_","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRole","inputs":[{"type":"bytes32","name":"role_","internalType":"bytes32"},{"type":"address","name":"revokee_","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"siblingChainSlug","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ISocket"}],"name":"socket__","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"transmissionParams","inputs":[]}]
Contract Creation Code
0x6101006040523480156200001257600080fd5b5060405162001ba738038062001ba7833981016040819052620000359162000167565b338062000042816200009c565b50506001600160a01b03808516608052831660a05263ffffffff821660c05260e0819052620000927fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f2925333620000ef565b50505050620001c3565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b60008281526002602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b80516001600160a01b03811681146200016257600080fd5b919050565b600080600080608085870312156200017e57600080fd5b62000189856200014a565b935062000199602086016200014a565b9250604085015163ffffffff81168114620001b357600080fd5b6060959095015193969295505050565b60805160a05160c05160e051611925620002826000396000818161032801528181610b1b0152610c4401526000818161035c0152818161055c015281816107d701528181610af401528181610c2101528181610ed20152610faa0152600081816103b801528181610495015281816105b1015281816108050152818161093301528181610ac501528181610be401528181610ce801528181610efb01526110030152600081816102e101528181610a280152610d7c01526119256000f3fe6080604052600436106101445760003560e01c806391d14854116100c0578063c41f1f6c11610074578063d547741f11610059578063d547741f146103da578063d9374bff146103fa578063e9975f881461040f57600080fd5b8063c41f1f6c14610393578063c6a261d2146103a657600080fd5b8063ac0710cb116100a5578063ac0710cb14610303578063b55ea0d514610316578063bf965e521461034a57600080fd5b806391d148541461029f578063aa128e8f146102cf57600080fd5b80635b94db27116101175780636ccae054116100fc5780636ccae0541461023f57806374fa24a61461025f5780638da5cb5b1461027457600080fd5b80635b94db27146101f1578063666758ca1461021157600080fd5b806320f99c0a14610149578063295058ef1461019a5780632f2ff15d146101bc5780633bd1adec146101dc575b600080fd5b34801561015557600080fd5b5060015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101a657600080fd5b506101ba6101b536600461146e565b610425565b005b3480156101c857600080fd5b506101ba6101d73660046114a7565b610611565b3480156101e857600080fd5b506101ba610670565b3480156101fd57600080fd5b506101ba61020c3660046114cc565b6106cc565b34801561021d57600080fd5b5061023161022c3660046114e9565b61078c565b604051908152602001610191565b34801561024b57600080fd5b506101ba61025a36600461150b565b61088c565b34801561026b57600080fd5b5061023161092f565b34801561028057600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610170565b3480156102ab57600080fd5b506102bf6102ba3660046114a7565b6109d6565b6040519015158152602001610191565b3480156102db57600080fd5b506101707f000000000000000000000000000000000000000000000000000000000000000081565b610231610311366004611626565b610a0e565b34801561032257600080fd5b506102317f000000000000000000000000000000000000000000000000000000000000000081565b34801561035657600080fd5b5061037e7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610191565b6101ba6103a13660046116a5565b610cd0565b3480156103b257600080fd5b506101707f000000000000000000000000000000000000000000000000000000000000000081565b3480156103e657600080fd5b506101ba6103f53660046114a7565b610dec565b34801561040657600080fd5b506101ba610e47565b34801561041b57600080fd5b5061023160035481565b60005473ffffffffffffffffffffffffffffffffffffffff163314610476576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408273ffffffffffffffffffffffffffffffffffffffff16901b60e07f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b349ba656040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610522919061172a565b63ffffffff90811690911b919091176003556040517f3b1be6780000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000909116600482015273ffffffffffffffffffffffffffffffffffffffff83811660248301528281166044830181905260648301527f00000000000000000000000000000000000000000000000000000000000000001690633b1be67890608401600060405180830381600087803b1580156105f557600080fd5b505af1158015610609573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610662576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61066c828261108f565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106c1576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106ca33611115565b565b60005473ffffffffffffffffffffffffffffffffffffffff16331461071d576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b6040517f9ae3f05a00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526000604482018190526064820181905263ffffffff7f00000000000000000000000000000000000000000000000000000000000000001660848301523060a4830152907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639ae3f05a9060c401602060405180830381865afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108859190611747565b9392505050565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff1661091e576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61092984848461118d565b50505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e992e0ff6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c09190611760565b67ffffffffffffffff166003541760001b905090565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16610885565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610a7f576040517f7fea9dc500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151600003610b8f576040517f3386774f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690633386774f903490610b45907f00000000000000000000000000000000000000000000000000000000000000009089906000907f0000000000000000000000000000000000000000000000000000000000000000908b9060040161178a565b60206040518083038185885af1158015610b63573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610b889190611747565b9050610885565b8151602014610bca576040517f8ad4437800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082806020019051810190610be09190611747565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633386774f347f000000000000000000000000000000000000000000000000000000000000000088857f00000000000000000000000000000000000000000000000000000000000000008a6040518763ffffffff1660e01b8152600401610c8495949392919061178a565b60206040518083038185885af1158015610ca2573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610cc79190611747565b95945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d3f576040517fc59f8f7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f873ea75500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063873ea75590610db590869086908690600401611820565b600060405180830381600087803b158015610dcf57600080fd5b505af1158015610de3573d6000803e3d6000fd5b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e3d576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61066c8282611282565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e98576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038190556040517f6f38f87000000000000000000000000000000000000000000000000000000000815230600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690636f38f8709060440160a060405180830381865afa158015610f57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7b919061187a565b50506040517f3b1be67800000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201526000602482015273ffffffffffffffffffffffffffffffffffffffff808416604483015280831660648301529295509093507f00000000000000000000000000000000000000000000000000000000000000009091169150633b1be67890608401600060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b50506040517fc2af098c82dba3c4b00be8bda596d62d13b98a87b42626fefa67e0bb0e198fdd925060009150a15050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff82166111da576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff841601611226576112218282611305565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b600003611277576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61122183838361137a565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af1905080611221576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c4544000000000000000000000000006044820152606401610915565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610929576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152606401610915565b73ffffffffffffffffffffffffffffffffffffffff8116811461146b57600080fd5b50565b6000806040838503121561148157600080fd5b823561148c81611449565b9150602083013561149c81611449565b809150509250929050565b600080604083850312156114ba57600080fd5b82359150602083013561149c81611449565b6000602082840312156114de57600080fd5b813561088581611449565b600080604083850312156114fc57600080fd5b50508035926020909101359150565b60008060006060848603121561152057600080fd5b833561152b81611449565b9250602084013561153b81611449565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261158c57600080fd5b813567ffffffffffffffff808211156115a7576115a761154c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156115ed576115ed61154c565b8160405283815286602085880101111561160657600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561163b57600080fd5b83359250602084013567ffffffffffffffff8082111561165a57600080fd5b6116668783880161157b565b9350604086013591508082111561167c57600080fd5b506116898682870161157b565b9150509250925092565b63ffffffff8116811461146b57600080fd5b6000806000604084860312156116ba57600080fd5b83356116c581611693565b9250602084013567ffffffffffffffff808211156116e257600080fd5b818601915086601f8301126116f657600080fd5b81358181111561170557600080fd5b87602082850101111561171757600080fd5b6020830194508093505050509250925092565b60006020828403121561173c57600080fd5b815161088581611693565b60006020828403121561175957600080fd5b5051919050565b60006020828403121561177257600080fd5b815167ffffffffffffffff8116811461088557600080fd5b63ffffffff8616815260006020868184015285604084015284606084015260a0608084015283518060a085015260005b818110156117d65785810183015185820160c0015282016117ba565b818111156117e857600060c083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160c001979650505050505050565b63ffffffff8416815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b600080600080600060a0868803121561189257600080fd5b855161189d81611449565b60208701519095506118ae81611449565b60408701519094506118bf81611449565b60608701519093506118d081611449565b60808701519092506118e181611449565b80915050929550929590935056fea2646970667358221220af3e9530d3f864c9c7be72fef48428fc7bba8ccb785f07e3237ecc436781801564736f6c634300080d00330000000000000000000000001363aa6d41719736abf5f12ee850a01659b3ea080000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f0000000000000000000000000000000000000000000000000000000000aa37dc0000000000000000000000000000000000000000000000000000000000000000
Deployed ByteCode
0x6080604052600436106101445760003560e01c806391d14854116100c0578063c41f1f6c11610074578063d547741f11610059578063d547741f146103da578063d9374bff146103fa578063e9975f881461040f57600080fd5b8063c41f1f6c14610393578063c6a261d2146103a657600080fd5b8063ac0710cb116100a5578063ac0710cb14610303578063b55ea0d514610316578063bf965e521461034a57600080fd5b806391d148541461029f578063aa128e8f146102cf57600080fd5b80635b94db27116101175780636ccae054116100fc5780636ccae0541461023f57806374fa24a61461025f5780638da5cb5b1461027457600080fd5b80635b94db27146101f1578063666758ca1461021157600080fd5b806320f99c0a14610149578063295058ef1461019a5780632f2ff15d146101bc5780633bd1adec146101dc575b600080fd5b34801561015557600080fd5b5060015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101a657600080fd5b506101ba6101b536600461146e565b610425565b005b3480156101c857600080fd5b506101ba6101d73660046114a7565b610611565b3480156101e857600080fd5b506101ba610670565b3480156101fd57600080fd5b506101ba61020c3660046114cc565b6106cc565b34801561021d57600080fd5b5061023161022c3660046114e9565b61078c565b604051908152602001610191565b34801561024b57600080fd5b506101ba61025a36600461150b565b61088c565b34801561026b57600080fd5b5061023161092f565b34801561028057600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610170565b3480156102ab57600080fd5b506102bf6102ba3660046114a7565b6109d6565b6040519015158152602001610191565b3480156102db57600080fd5b506101707f0000000000000000000000001363aa6d41719736abf5f12ee850a01659b3ea0881565b610231610311366004611626565b610a0e565b34801561032257600080fd5b506102317f000000000000000000000000000000000000000000000000000000000000000081565b34801561035657600080fd5b5061037e7f0000000000000000000000000000000000000000000000000000000000aa37dc81565b60405163ffffffff9091168152602001610191565b6101ba6103a13660046116a5565b610cd0565b3480156103b257600080fd5b506101707f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f81565b3480156103e657600080fd5b506101ba6103f53660046114a7565b610dec565b34801561040657600080fd5b506101ba610e47565b34801561041b57600080fd5b5061023160035481565b60005473ffffffffffffffffffffffffffffffffffffffff163314610476576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408273ffffffffffffffffffffffffffffffffffffffff16901b60e07f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f73ffffffffffffffffffffffffffffffffffffffff1663b349ba656040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610522919061172a565b63ffffffff90811690911b919091176003556040517f3b1be6780000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000aa37dc909116600482015273ffffffffffffffffffffffffffffffffffffffff83811660248301528281166044830181905260648301527f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f1690633b1be67890608401600060405180830381600087803b1580156105f557600080fd5b505af1158015610609573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610662576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61066c828261108f565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106c1576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106ca33611115565b565b60005473ffffffffffffffffffffffffffffffffffffffff16331461071d576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b6040517f9ae3f05a00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526000604482018190526064820181905263ffffffff7f0000000000000000000000000000000000000000000000000000000000aa37dc1660848301523060a4830152907f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f73ffffffffffffffffffffffffffffffffffffffff1690639ae3f05a9060c401602060405180830381865afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108859190611747565b9392505050565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff1661091e576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61092984848461118d565b50505050565b60007f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f73ffffffffffffffffffffffffffffffffffffffff1663e992e0ff6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c09190611760565b67ffffffffffffffff166003541760001b905090565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16610885565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000001363aa6d41719736abf5f12ee850a01659b3ea081614610a7f576040517f7fea9dc500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151600003610b8f576040517f3386774f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f1690633386774f903490610b45907f0000000000000000000000000000000000000000000000000000000000aa37dc9089906000907f0000000000000000000000000000000000000000000000000000000000000000908b9060040161178a565b60206040518083038185885af1158015610b63573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610b889190611747565b9050610885565b8151602014610bca576040517f8ad4437800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082806020019051810190610be09190611747565b90507f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f73ffffffffffffffffffffffffffffffffffffffff16633386774f347f0000000000000000000000000000000000000000000000000000000000aa37dc88857f00000000000000000000000000000000000000000000000000000000000000008a6040518763ffffffff1660e01b8152600401610c8495949392919061178a565b60206040518083038185885af1158015610ca2573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610cc79190611747565b95945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f1614610d3f576040517fc59f8f7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f873ea75500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000001363aa6d41719736abf5f12ee850a01659b3ea08169063873ea75590610db590869086908690600401611820565b600060405180830381600087803b158015610dcf57600080fd5b505af1158015610de3573d6000803e3d6000fd5b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e3d576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61066c8282611282565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e98576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060038190556040517f6f38f87000000000000000000000000000000000000000000000000000000000815230600482015263ffffffff7f0000000000000000000000000000000000000000000000000000000000aa37dc16602482015281907f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f73ffffffffffffffffffffffffffffffffffffffff1690636f38f8709060440160a060405180830381865afa158015610f57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7b919061187a565b50506040517f3b1be67800000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000aa37dc1660048201526000602482015273ffffffffffffffffffffffffffffffffffffffff808416604483015280831660648301529295509093507f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f9091169150633b1be67890608401600060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b50506040517fc2af098c82dba3c4b00be8bda596d62d13b98a87b42626fefa67e0bb0e198fdd925060009150a15050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff82166111da576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff841601611226576112218282611305565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b600003611277576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61122183838361137a565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af1905080611221576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c4544000000000000000000000000006044820152606401610915565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610929576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152606401610915565b73ffffffffffffffffffffffffffffffffffffffff8116811461146b57600080fd5b50565b6000806040838503121561148157600080fd5b823561148c81611449565b9150602083013561149c81611449565b809150509250929050565b600080604083850312156114ba57600080fd5b82359150602083013561149c81611449565b6000602082840312156114de57600080fd5b813561088581611449565b600080604083850312156114fc57600080fd5b50508035926020909101359150565b60008060006060848603121561152057600080fd5b833561152b81611449565b9250602084013561153b81611449565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261158c57600080fd5b813567ffffffffffffffff808211156115a7576115a761154c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156115ed576115ed61154c565b8160405283815286602085880101111561160657600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561163b57600080fd5b83359250602084013567ffffffffffffffff8082111561165a57600080fd5b6116668783880161157b565b9350604086013591508082111561167c57600080fd5b506116898682870161157b565b9150509250925092565b63ffffffff8116811461146b57600080fd5b6000806000604084860312156116ba57600080fd5b83356116c581611693565b9250602084013567ffffffffffffffff808211156116e257600080fd5b818601915086601f8301126116f657600080fd5b81358181111561170557600080fd5b87602082850101111561171757600080fd5b6020830194508093505050509250925092565b60006020828403121561173c57600080fd5b815161088581611693565b60006020828403121561175957600080fd5b5051919050565b60006020828403121561177257600080fd5b815167ffffffffffffffff8116811461088557600080fd5b63ffffffff8616815260006020868184015285604084015284606084015260a0608084015283518060a085015260005b818110156117d65785810183015185820160c0015282016117ba565b818111156117e857600060c083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160c001979650505050505050565b63ffffffff8416815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b600080600080600060a0868803121561189257600080fd5b855161189d81611449565b60208701519095506118ae81611449565b60408701519094506118bf81611449565b60608701519093506118d081611449565b60808701519092506118e181611449565b80915050929550929590935056fea2646970667358221220af3e9530d3f864c9c7be72fef48428fc7bba8ccb785f07e3237ecc436781801564736f6c634300080d0033