Source Code
Overview
GLMR Balance
GLMR Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 4423905 | 866 days ago | 1.89655166 GLMR | ||||
| 4423202 | 866 days ago | 1.46236565 GLMR | ||||
| 4423055 | 866 days ago | 31.25804875 GLMR | ||||
| 4422988 | 866 days ago | 1.17643127 GLMR | ||||
| 4422409 | 866 days ago | 30.64151329 GLMR | ||||
| 4422409 | 866 days ago | 15,350 GLMR | ||||
| 4422108 | 866 days ago | 6.12286677 GLMR | ||||
| 4421684 | 866 days ago | 1.42414109 GLMR | ||||
| 4421475 | 866 days ago | 7.98023579 GLMR | ||||
| 4421475 | 866 days ago | 6,100 GLMR | ||||
| 4421332 | 866 days ago | 42.65596619 GLMR | ||||
| 4421237 | 866 days ago | 18.58707868 GLMR | ||||
| 4421205 | 866 days ago | 3.84208019 GLMR | ||||
| 4421205 | 866 days ago | 425.12450523 GLMR | ||||
| 4420966 | 866 days ago | 1.25090879 GLMR | ||||
| 4420966 | 866 days ago | 950 GLMR | ||||
| 4420957 | 866 days ago | 0.93980565 GLMR | ||||
| 4420957 | 866 days ago | 5,300 GLMR | ||||
| 4420677 | 866 days ago | 13.04417871 GLMR | ||||
| 4420589 | 866 days ago | 0.9807921 GLMR | ||||
| 4420535 | 866 days ago | 15.37344938 GLMR | ||||
| 4419896 | 866 days ago | 2.71513059 GLMR | ||||
| 4419896 | 866 days ago | 1.05 GLMR | ||||
| 4419877 | 866 days ago | 2.45608211 GLMR | ||||
| 4419877 | 866 days ago | 1.05 GLMR |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
SquidRouter
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 99999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {ISquidRouter} from "../interfaces/ISquidRouter.sol";
import {ISquidMulticall} from "../interfaces/ISquidMulticall.sol";
import {AxelarForecallable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/executables/AxelarForecallable.sol";
import {IAxelarGasService} from "@axelar-network/axelar-cgp-solidity/contracts/interfaces/IAxelarGasService.sol";
import {IAxelarGateway} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol";
import {Upgradable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradables/Upgradable.sol";
import {RoledPausable} from "../libraries/RoledPausable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract SquidRouter is ISquidRouter, AxelarForecallable, Upgradable, RoledPausable {
IAxelarGasService private immutable gasService;
IAxelarGasService private immutable forecallGasService;
ISquidMulticall private immutable squidMulticall;
constructor(
address _gateway,
address _gasService,
address _forecallGasService,
address _multicall
) AxelarForecallable(_gateway) {
if (
_gateway == address(0) ||
_gasService == address(0) ||
_forecallGasService == address(0) ||
_multicall == address(0)
) revert ZeroAddressProvided();
gasService = IAxelarGasService(_gasService);
forecallGasService = IAxelarGasService(_forecallGasService);
squidMulticall = ISquidMulticall(_multicall);
}
function bridgeCall(
string calldata bridgedTokenSymbol,
uint256 amount,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasRefundRecipient,
bool enableExpress
) external payable whenNotPaused {
address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol);
_safeTransferFrom(bridgedTokenAddress, msg.sender, amount);
_bridgeCall(
bridgedTokenSymbol,
bridgedTokenAddress,
destinationChain,
destinationAddress,
payload,
gasRefundRecipient,
enableExpress
);
}
function callBridge(
address token,
uint256 amount,
ISquidMulticall.Call[] calldata calls,
string calldata bridgedTokenSymbol,
string calldata destinationChain,
string calldata destinationAddress
) external payable whenNotPaused {
fundAndRunMulticall(token, amount, calls);
address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol);
uint256 bridgedTokenAmount = IERC20(bridgedTokenAddress).balanceOf(address(this));
_approve(bridgedTokenAddress, address(gateway), bridgedTokenAmount);
gateway.sendToken(destinationChain, destinationAddress, bridgedTokenSymbol, bridgedTokenAmount);
}
function callBridgeCall(
address token,
uint256 amount,
ISquidMulticall.Call[] calldata calls,
string calldata bridgedTokenSymbol,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasRefundRecipient,
bool enableExpress
) external payable whenNotPaused {
fundAndRunMulticall(token, amount, calls);
address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol);
_bridgeCall(
bridgedTokenSymbol,
bridgedTokenAddress,
destinationChain,
destinationAddress,
payload,
gasRefundRecipient,
enableExpress
);
}
function contractId() external pure override returns (bytes32 id) {
id = keccak256("squid-router");
}
function fundAndRunMulticall(
address token,
uint256 amount,
ISquidMulticall.Call[] memory calls
) public payable whenNotPaused {
uint256 valueToSend;
if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {
valueToSend = amount;
} else {
_transferTokenToMulticall(token, amount);
}
squidMulticall.run{value: valueToSend}(calls);
}
function _executeWithToken(
string calldata,
string calldata,
bytes calldata payload,
string calldata bridgedTokenSymbol,
uint256
) internal override {
(ISquidMulticall.Call[] memory calls, address refundRecipient) = abi.decode(
payload,
(ISquidMulticall.Call[], address)
);
address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol);
uint256 contractBalance = IERC20(bridgedTokenAddress).balanceOf(address(this));
_approve(bridgedTokenAddress, address(squidMulticall), contractBalance);
try squidMulticall.run(calls) {
emit CrossMulticallExecuted(keccak256(payload));
} catch (bytes memory reason) {
// Refund tokens to refund recipient if swap fails
_safeTransfer(bridgedTokenAddress, refundRecipient, contractBalance);
emit CrossMulticallFailed(keccak256(payload), reason, refundRecipient);
}
}
function _bridgeCall(
string calldata bridgedTokenSymbol,
address bridgedTokenAddress,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasRefundRecipient,
bool enableExpress
) private {
uint256 bridgedTokenBalance = IERC20(bridgedTokenAddress).balanceOf(address(this));
if (address(this).balance > 0) {
IAxelarGasService executionService = enableExpress ? forecallGasService : gasService;
executionService.payNativeGasForContractCallWithToken{value: address(this).balance}(
address(this),
destinationChain,
destinationAddress,
payload,
bridgedTokenSymbol,
bridgedTokenBalance,
gasRefundRecipient
);
}
_approve(bridgedTokenAddress, address(gateway), bridgedTokenBalance);
gateway.callContractWithToken(
destinationChain,
destinationAddress,
payload,
bridgedTokenSymbol,
bridgedTokenBalance
);
}
function _approve(address token, address spender, uint256 amount) private {
uint256 allowance = IERC20(token).allowance(address(this), spender);
if (allowance < amount) {
if (allowance > 0) {
_approveCall(token, spender, 0);
}
_approveCall(token, spender, type(uint256).max);
}
}
function _approveCall(address token, address spender, uint256 amount) private {
// Unlimited approval is not security issue since the contract doesn't store tokens
(bool success, ) = token.call(abi.encodeWithSelector(IERC20.approve.selector, spender, amount));
if (!success) revert ApprovalFailed();
}
function _transferTokenToMulticall(address token, uint256 amount) private {
(bool success, bytes memory returnData) = token.call(
abi.encodeWithSelector(IERC20.transferFrom.selector, msg.sender, address(squidMulticall), amount)
);
bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));
if (!transferred || token.code.length == 0) revert TransferFailed();
}
function _setup(bytes calldata data) internal override {
address _pauser = abi.decode(data, (address));
if (_pauser == address(0)) revert ZeroAddressProvided();
_setPauser(_pauser);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import './IUpgradable.sol';
// This should be owned by the microservice that is paying for gas.
interface IAxelarGasService is IUpgradable {
error NothingReceived();
error TransferFailed();
error InvalidAddress();
error NotCollector();
error InvalidAmounts();
event GasPaidForContractCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event GasPaidForContractCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForContractCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForContractCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
uint256 gasFeeAmount,
address refundAddress
);
event GasAdded(bytes32 indexed txHash, uint256 indexed logIndex, address gasToken, uint256 gasFeeAmount, address refundAddress);
event NativeGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress);
// This is called on the source chain before calling the gateway to execute a remote contract.
function payGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
// This is called on the source chain before calling the gateway to execute a remote contract.
function payGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
// This is called on the source chain before calling the gateway to execute a remote contract.
function payNativeGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address refundAddress
) external payable;
// This is called on the source chain before calling the gateway to execute a remote contract.
function payNativeGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address refundAddress
) external payable;
function addGas(
bytes32 txHash,
uint256 txIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
function addNativeGas(
bytes32 txHash,
uint256 logIndex,
address refundAddress
) external payable;
function collectFees(
address payable receiver,
address[] calldata tokens,
uint256[] calldata amounts
) external;
function refund(
address payable receiver,
address token,
uint256 amount
) external;
function gasCollector() external returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
// General interface for upgradable contracts
interface IUpgradable {
error NotOwner();
error InvalidOwner();
error InvalidCodeHash();
error InvalidImplementation();
error SetupFailed();
error NotProxy();
event Upgraded(address indexed newImplementation);
event OwnershipTransferred(address indexed newOwner);
// Get current owner
function owner() external view returns (address);
function contractId() external pure returns (bytes32);
function implementation() external view returns (address);
function upgrade(
address newImplementation,
bytes32 newImplementationCodeHash,
bytes calldata params
) external;
function setup(bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';
import { IERC20 } from '../interfaces/IERC20.sol';
import { IAxelarForecallable } from '../interfaces/IAxelarForecallable.sol';
contract AxelarForecallable is IAxelarForecallable {
IAxelarGateway public immutable gateway;
//keccak256('forecallers');
uint256 public constant FORECALLERS_SALT = 0xdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f;
constructor(address gateway_) {
if (gateway_ == address(0)) revert InvalidAddress();
gateway = IAxelarGateway(gateway_);
}
function getForecaller(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) public view override returns (address forecaller) {
bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, FORECALLERS_SALT));
// solhint-disable-next-line no-inline-assembly
assembly {
forecaller := sload(pos)
}
}
function _setForecaller(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
address forecaller
) internal {
bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, FORECALLERS_SALT));
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(pos, forecaller)
}
}
function forecall(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external {
_checkForecall(sourceChain, sourceAddress, payload, msg.sender);
if (getForecaller(sourceChain, sourceAddress, payload) != address(0)) revert AlreadyForecalled();
_setForecaller(sourceChain, sourceAddress, payload, msg.sender);
_execute(sourceChain, sourceAddress, payload);
}
function execute(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external override {
bytes32 payloadHash = keccak256(payload);
if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
revert NotApprovedByGateway();
address forecaller = getForecaller(sourceChain, sourceAddress, payload);
if (forecaller != address(0)) {
_setForecaller(sourceChain, sourceAddress, payload, address(0));
} else {
_execute(sourceChain, sourceAddress, payload);
}
}
function getForecallerWithToken(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount
) public view override returns (address forecaller) {
bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, symbol, amount, FORECALLERS_SALT));
// solhint-disable-next-line no-inline-assembly
assembly {
forecaller := sload(pos)
}
}
function _setForecallerWithToken(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address forecaller
) internal {
bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, symbol, amount, FORECALLERS_SALT));
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(pos, forecaller)
}
}
function forecallWithToken(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) external override {
address token = gateway.tokenAddresses(tokenSymbol);
uint256 amountPost = amountPostFee(amount, payload);
_safeTransferFrom(token, msg.sender, amountPost);
_checkForecallWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, msg.sender);
if (getForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount) != address(0))
revert AlreadyForecalled();
_setForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, msg.sender);
_executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amountPost);
}
function executeWithToken(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) external override {
bytes32 payloadHash = keccak256(payload);
if (
!gateway.validateContractCallAndMint(
commandId,
sourceChain,
sourceAddress,
payloadHash,
tokenSymbol,
amount
)
) revert NotApprovedByGateway();
address forecaller = getForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount);
if (forecaller != address(0)) {
_setForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, address(0));
address token = gateway.tokenAddresses(tokenSymbol);
_safeTransfer(token, forecaller, amount);
} else {
_executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount);
}
}
function _execute(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) internal virtual {}
function _executeWithToken(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) internal virtual {}
// Override this to keep a fee.
function amountPostFee(
uint256 amount,
bytes calldata /*payload*/
) public virtual override returns (uint256) {
return amount;
}
// Override this and revert if you want to only allow certain people/calls to be able to forecall.
function _checkForecall(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
address forecaller
) internal virtual {}
// Override this and revert if you want to only allow certain people/calls to be able to forecall.
function _checkForecallWithToken(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount,
address forecaller
) internal virtual {}
function _safeTransfer(
address tokenAddress,
address receiver,
uint256 amount
) internal {
(bool success, bytes memory returnData) = tokenAddress.call(
abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount)
);
bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));
if (!transferred || tokenAddress.code.length == 0) revert TransferFailed();
}
function _safeTransferFrom(
address tokenAddress,
address from,
uint256 amount
) internal {
(bool success, bytes memory returnData) = tokenAddress.call(
abi.encodeWithSelector(IERC20.transferFrom.selector, from, address(this), amount)
);
bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));
if (!transferred || tokenAddress.code.length == 0) revert TransferFailed();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';
interface IAxelarExecutable {
error InvalidAddress();
error NotApprovedByGateway();
function gateway() external view returns (IAxelarGateway);
function execute(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external;
function executeWithToken(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol';
interface IAxelarForecallable is IAxelarExecutable {
error AlreadyForecalled();
error TransferFailed();
function forecall(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external;
function forecallWithToken(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) external;
function getForecaller(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external returns (address forecaller);
function getForecallerWithToken(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount
) external returns (address forecaller);
function amountPostFee(uint256 amount, bytes calldata payload) external returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IAxelarGateway {
/**********\
|* Errors *|
\**********/
error NotSelf();
error NotProxy();
error InvalidCodeHash();
error SetupFailed();
error InvalidAuthModule();
error InvalidTokenDeployer();
error InvalidAmount();
error InvalidChainId();
error InvalidCommands();
error TokenDoesNotExist(string symbol);
error TokenAlreadyExists(string symbol);
error TokenDeployFailed(string symbol);
error TokenContractDoesNotExist(address token);
error BurnFailed(string symbol);
error MintFailed(string symbol);
error InvalidSetMintLimitsParams();
error ExceedMintLimit(string symbol);
/**********\
|* Events *|
\**********/
event TokenSent(
address indexed sender,
string destinationChain,
string destinationAddress,
string symbol,
uint256 amount
);
event ContractCall(
address indexed sender,
string destinationChain,
string destinationContractAddress,
bytes32 indexed payloadHash,
bytes payload
);
event ContractCallWithToken(
address indexed sender,
string destinationChain,
string destinationContractAddress,
bytes32 indexed payloadHash,
bytes payload,
string symbol,
uint256 amount
);
event Executed(bytes32 indexed commandId);
event TokenDeployed(string symbol, address tokenAddresses);
event ContractCallApproved(
bytes32 indexed commandId,
string sourceChain,
string sourceAddress,
address indexed contractAddress,
bytes32 indexed payloadHash,
bytes32 sourceTxHash,
uint256 sourceEventIndex
);
event ContractCallApprovedWithMint(
bytes32 indexed commandId,
string sourceChain,
string sourceAddress,
address indexed contractAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
bytes32 sourceTxHash,
uint256 sourceEventIndex
);
event TokenMintLimitUpdated(string symbol, uint256 limit);
event OperatorshipTransferred(bytes newOperatorsData);
event Upgraded(address indexed implementation);
/********************\
|* Public Functions *|
\********************/
function sendToken(
string calldata destinationChain,
string calldata destinationAddress,
string calldata symbol,
uint256 amount
) external;
function callContract(
string calldata destinationChain,
string calldata contractAddress,
bytes calldata payload
) external;
function callContractWithToken(
string calldata destinationChain,
string calldata contractAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount
) external;
function isContractCallApproved(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
address contractAddress,
bytes32 payloadHash
) external view returns (bool);
function isContractCallAndMintApproved(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
address contractAddress,
bytes32 payloadHash,
string calldata symbol,
uint256 amount
) external view returns (bool);
function validateContractCall(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash
) external returns (bool);
function validateContractCallAndMint(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash,
string calldata symbol,
uint256 amount
) external returns (bool);
/***********\
|* Getters *|
\***********/
function authModule() external view returns (address);
function tokenDeployer() external view returns (address);
function tokenMintLimit(string memory symbol) external view returns (uint256);
function tokenMintAmount(string memory symbol) external view returns (uint256);
function allTokensFrozen() external view returns (bool);
function implementation() external view returns (address);
function tokenAddresses(string memory symbol) external view returns (address);
function tokenFrozen(string memory symbol) external view returns (bool);
function isCommandExecuted(bytes32 commandId) external view returns (bool);
function adminEpoch() external view returns (uint256);
function adminThreshold(uint256 epoch) external view returns (uint256);
function admins(uint256 epoch) external view returns (address[] memory);
/*******************\
|* Admin Functions *|
\*******************/
function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external;
function upgrade(
address newImplementation,
bytes32 newImplementationCodeHash,
bytes calldata setupParams
) external;
/**********************\
|* External Functions *|
\**********************/
function setup(bytes calldata params) external;
function execute(bytes calldata input) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
error InvalidAccount();
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// General interface for upgradable contracts
interface IUpgradable {
error NotOwner();
error InvalidOwner();
error InvalidCodeHash();
error InvalidImplementation();
error SetupFailed();
error NotProxy();
event Upgraded(address indexed newImplementation);
event OwnershipTransferred(address indexed newOwner);
// Get current owner
function owner() external view returns (address);
function contractId() external pure returns (bytes32);
function upgrade(
address newImplementation,
bytes32 newImplementationCodeHash,
bytes calldata params
) external;
function setup(bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '../interfaces/IUpgradable.sol';
abstract contract Upgradable is IUpgradable {
// bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
// keccak256('owner')
bytes32 internal constant _OWNER_SLOT = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0;
modifier onlyOwner() {
if (owner() != msg.sender) revert NotOwner();
_;
}
function owner() public view returns (address owner_) {
// solhint-disable-next-line no-inline-assembly
assembly {
owner_ := sload(_OWNER_SLOT)
}
}
function transferOwnership(address newOwner) external virtual onlyOwner {
if (newOwner == address(0)) revert InvalidOwner();
emit OwnershipTransferred(newOwner);
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(_OWNER_SLOT, newOwner)
}
}
function implementation() public view returns (address implementation_) {
// solhint-disable-next-line no-inline-assembly
assembly {
implementation_ := sload(_IMPLEMENTATION_SLOT)
}
}
function upgrade(
address newImplementation,
bytes32 newImplementationCodeHash,
bytes calldata params
) external override onlyOwner {
if (IUpgradable(newImplementation).contractId() != IUpgradable(this).contractId())
revert InvalidImplementation();
if (newImplementationCodeHash != newImplementation.codehash) revert InvalidCodeHash();
if (params.length > 0) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = newImplementation.delegatecall(abi.encodeWithSelector(this.setup.selector, params));
if (!success) revert SetupFailed();
}
emit Upgraded(newImplementation);
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(_IMPLEMENTATION_SLOT, newImplementation)
}
}
function setup(bytes calldata data) external override {
// Prevent setup from being called on the implementation
if (implementation() == address(0)) revert NotProxy();
_setup(data);
}
// solhint-disable-next-line no-empty-blocks
function _setup(bytes calldata data) internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
interface IRoledPausable {
event PauserProposed(address indexed currentPauser, address indexed pendingPauser);
event PauserUpdated(address indexed pendingPauser);
event Paused();
event Unpaused();
error ContractIsPaused();
error NotPauser();
error NotPendingPauser();
function updatePauser(address _newPauser) external;
function acceptPauser() external;
function pause() external;
function unpause() external;
function paused() external view returns (bool value);
function pauser() external view returns (address value);
function pendingPauser() external view returns (address value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
interface ISquidMulticall {
enum CallType {
Default,
FullTokenBalance,
FullNativeBalance,
CollectTokenBalance
}
struct Call {
CallType callType;
address target;
uint256 value;
bytes callData;
bytes payload;
}
error AlreadyRunning();
error CallFailed(uint256 callPosition, bytes reason);
function run(Call[] calldata calls) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import {ISquidMulticall} from "./ISquidMulticall.sol";
interface ISquidRouter {
event CrossMulticallExecuted(bytes32 indexed payloadHash);
event CrossMulticallFailed(bytes32 indexed payloadHash, bytes reason, address indexed refundRecipient);
error ZeroAddressProvided();
error ApprovalFailed();
function bridgeCall(
string calldata bridgedTokenSymbol,
uint256 amount,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasRefundRecipient,
bool enableExpress
) external payable;
function callBridge(
address token,
uint256 amount,
ISquidMulticall.Call[] calldata calls,
string calldata bridgedTokenSymbol,
string calldata destinationChain,
string calldata destinationAddress
) external payable;
function callBridgeCall(
address token,
uint256 amount,
ISquidMulticall.Call[] calldata calls,
string calldata bridgedTokenSymbol,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasRefundRecipient,
bool enableExpress
) external payable;
function fundAndRunMulticall(address token, uint256 amount, ISquidMulticall.Call[] memory calls) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import {IRoledPausable} from "../interfaces/IRoledPausable.sol";
import {StorageSlot} from "./StorageSlot.sol";
abstract contract RoledPausable is IRoledPausable {
using StorageSlot for bytes32;
bytes32 internal constant PAUSED_SLOT = keccak256("RoledPausable.paused");
bytes32 internal constant PAUSER_SLOT = keccak256("RoledPausable.pauser");
bytes32 internal constant PENDING_PAUSER_SLOT = keccak256("RoledPausable.pendingPauser");
modifier whenNotPaused() {
if (paused()) revert ContractIsPaused();
_;
}
modifier onlyPauser() {
if (msg.sender != pauser()) revert NotPauser();
_;
}
constructor() {
_setPauser(msg.sender);
}
function updatePauser(address newPauser) external onlyPauser {
PENDING_PAUSER_SLOT.setAddress(newPauser);
emit PauserProposed(msg.sender, newPauser);
}
function acceptPauser() external {
if (msg.sender != pendingPauser()) revert NotPendingPauser();
_setPauser(msg.sender);
PENDING_PAUSER_SLOT.setAddress(address(0));
}
function pause() external virtual onlyPauser {
PAUSED_SLOT.setBool(true);
emit Paused();
}
function unpause() external virtual onlyPauser {
PAUSED_SLOT.setBool(false);
emit Unpaused();
}
function pauser() public view returns (address value) {
value = PAUSER_SLOT.getAddress();
}
function paused() public view returns (bool value) {
value = PAUSED_SLOT.getBool();
}
function pendingPauser() public view returns (address value) {
value = PENDING_PAUSER_SLOT.getAddress();
}
function _setPauser(address _pauser) internal {
PAUSER_SLOT.setAddress(_pauser);
emit PauserUpdated(_pauser);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
library StorageSlot {
function setUint256(bytes32 slot, uint256 value) internal {
assembly {
sstore(slot, value)
}
}
function getUint256(bytes32 slot) internal view returns (uint256 value) {
assembly {
value := sload(slot)
}
}
function setAddress(bytes32 slot, address value) internal {
assembly {
sstore(slot, value)
}
}
function getAddress(bytes32 slot) internal view returns (address value) {
assembly {
value := sload(slot)
}
}
function setBool(bytes32 slot, bool value) internal {
assembly {
sstore(slot, value)
}
}
function getBool(bytes32 slot) internal view returns (bool value) {
assembly {
value := sload(slot)
}
}
}{
"optimizer": {
"enabled": true,
"runs": 99999
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_gateway","type":"address"},{"internalType":"address","name":"_gasService","type":"address"},{"internalType":"address","name":"_forecallGasService","type":"address"},{"internalType":"address","name":"_multicall","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyForecalled","type":"error"},{"inputs":[],"name":"ApprovalFailed","type":"error"},{"inputs":[],"name":"ContractIsPaused","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidCodeHash","type":"error"},{"inputs":[],"name":"InvalidImplementation","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"NotApprovedByGateway","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotPauser","type":"error"},{"inputs":[],"name":"NotPendingPauser","type":"error"},{"inputs":[],"name":"NotProxy","type":"error"},{"inputs":[],"name":"SetupFailed","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"ZeroAddressProvided","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"name":"CrossMulticallExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"},{"indexed":true,"internalType":"address","name":"refundRecipient","type":"address"}],"name":"CrossMulticallFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"currentPauser","type":"address"},{"indexed":true,"internalType":"address","name":"pendingPauser","type":"address"}],"name":"PauserProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingPauser","type":"address"}],"name":"PauserUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"FORECALLERS_SALT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"amountPostFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"bridgedTokenSymbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"gasRefundRecipient","type":"address"},{"internalType":"bool","name":"enableExpress","type":"bool"}],"name":"bridgeCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"enum ISquidMulticall.CallType","name":"callType","type":"uint8"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct ISquidMulticall.Call[]","name":"calls","type":"tuple[]"},{"internalType":"string","name":"bridgedTokenSymbol","type":"string"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"}],"name":"callBridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"enum ISquidMulticall.CallType","name":"callType","type":"uint8"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct ISquidMulticall.Call[]","name":"calls","type":"tuple[]"},{"internalType":"string","name":"bridgedTokenSymbol","type":"string"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"gasRefundRecipient","type":"address"},{"internalType":"bool","name":"enableExpress","type":"bool"}],"name":"callBridgeCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"contractId","outputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"executeWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"forecall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"forecallWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"enum ISquidMulticall.CallType","name":"callType","type":"uint8"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct ISquidMulticall.Call[]","name":"calls","type":"tuple[]"}],"name":"fundAndRunMulticall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"gateway","outputs":[{"internalType":"contract IAxelarGateway","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"getForecaller","outputs":[{"internalType":"address","name":"forecaller","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getForecallerWithToken","outputs":[{"internalType":"address","name":"forecaller","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"value","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"value","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingPauser","outputs":[{"internalType":"address","name":"value","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPauser","type":"address"}],"name":"updatePauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes32","name":"newImplementationCodeHash","type":"bytes32"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
61010034620001e857601f620035b938819003918201601f19168301916001600160401b03831184841017620001ed57808492608094604052833981010312620001e8576200004e8162000203565b906200005d6020820162000203565b906200007a6060620000726040840162000203565b920162000203565b6001600160a01b039390929084168015620001d657608052337f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c379558360405191337fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab600080a2169081158015620001cb575b8015620001c0575b620001b1575060a052821660c0521660e0526040516133a090816200021982396080518181816102ec01528181610ef40152818161175f01528181611b3801528181611e5e015281816120310152818161211a01528181612234015281816125440152612edc015260a0518161311e015260c05181612ff8015260e05181818161049b01528181610df301528181610e6c01528181610fad0152818161138c0152818161145d015281816116e50152818161197401526122d80152f35b638474420160e01b8152600490fd5b5084841615620000f4565b5084831615620000ec565b60405163e6c4247b60e01b8152600490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620001e85756fe60c0604052600436101561001257600080fd5b6000803560e01c806309cc027b146125c15780630d38218a14612568578063116191b6146124f9578063167a6f90146124135780631a98b2e014611ec95780632147796014611d265780633ca2fd8e14611cc85780633f4ba83a14611c115780634916065814611a1b57806352c41eb6146115c8578063554bab3c1461150457806358181a80146112d05780635c60da1b1461125f5780635c975abb146112025780638291286c146111a95780638456cb59146110c7578063846a1bc614610c7c5780638da5cb5b14610c0b5780639a7165e414610b9a5780639ded06df14610a4b5780639fd0506d146109da578063a3499c731461070b578063d0224434146106ad578063e888e86c14610279578063f2fde38b1461017b5763facd28a91461013b57600080fd5b3461017857602061015a61014e36612989565b94939093929192612aaf565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b80fd5b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576101b36126b5565b7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0805473ffffffffffffffffffffffffffffffffffffffff90813391160361024f5782168015610225577f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc6861638480a25580f35b60046040517f49e27cff000000000000000000000000000000000000000000000000000000008152fd5b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b50346101785761028836612612565b6040989194969293959851977f935b13f600000000000000000000000000000000000000000000000000000000998a8a52602060048b01528b8a602081806102d4602482018d8d612a0d565b0373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169e8f5afa80156106155789898c8e6103488a80966103519873ffffffffffffffffffffffffffffffffffffffff9a9161068e575b503390612c84565b878c8a8d612b4a565b166106645761039f9287878a8c610373956040519a8b9860208a019b8c612aea565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283612789565b339151902055828401906040858303126106605784359567ffffffffffffffff871161065c576103d660209361041598880161296e565b9373ffffffffffffffffffffffffffffffffffffffff6103f78589016126d8565b16986040519889948593849384528760048501526024840191612a0d565b03915afa938415610651578694610620575b5085604051917f70a0823100000000000000000000000000000000000000000000000000000000835230600484015260208360248173ffffffffffffffffffffffffffffffffffffffff8a165afa9283156106155782936105d9575b5073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166104c6848289613183565b803b156105d55761050a83929183926040519586809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af191826105bd575b5050610580577fdd7b1484db8d21f4fbda2407f2920037dc379dd66e18b0851aa9d6c14ef493b99261057a9261055761055e9388610551612b97565b98612bc7565b3691612804565b6020815191012092604051918291602083526020830190612ced565b0390a380f35b5061058f935036925090612804565b602081519101207f7c3aa10c5d96985be6de7d2e6fa79bdef95a95a9cb272f4113b3fe1ca89fedae8280a280f35b6105c69061272a565b6105d1578638610515565b8680fd5b8280fd5b915091506020813d60201161060d575b816105f660209383612789565b81010312610608578690519138610483565b600080fd5b3d91506105e9565b6040513d84823e3d90fd5b61064391945060203d60201161064a575b61063b8183612789565b810190612b6b565b9238610427565b503d610631565b6040513d88823e3d90fd5b8880fd5b8780fd5b60046040517f35b7d550000000000000000000000000000000000000000000000000000000008152fd5b6106a7915060203d60201161064a5761063b8183612789565b38610340565b5034610178576106bc36612989565b73ffffffffffffffffffffffffffffffffffffffff6106e4828486888a8c9b99989a9c612aaf565b16610664576107029361037392604051978895602087019889612a4c565b33915190205580f35b50346101785760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576107436126b5565b60443567ffffffffffffffff81116105d5576107639036906004016125e4565b907f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05473ffffffffffffffffffffffffffffffffffffffff90813391160361024f578316916040517f8291286c000000000000000000000000000000000000000000000000000000008082526020918281600481895afa9081156109a25788916109ad575b506040519182528282600481305afa9182156109a2578892610973575b500361094957843f6024350361091f57859282610869575b505050807fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b91a27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5580f35b6108d984936108ad604051938492868401967f9ded06df00000000000000000000000000000000000000000000000000000000885260248501526044840191612a0d565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612789565b5190855af46108e6612b97565b50156108f5578238808061081d565b60046040517f97905dfb000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8f84fb24000000000000000000000000000000000000000000000000000000008152fd5b60046040517f68155f9a000000000000000000000000000000000000000000000000000000008152fd5b9091508281813d831161099b575b61098b8183612789565b8101031261060857519038610805565b503d610981565b6040513d8a823e3d90fd5b90508281813d83116109d3575b6109c48183612789565b810103126106085751386107e8565b503d6109ba565b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043567ffffffffffffffff8111610b9657610a9b9036906004016125e4565b9073ffffffffffffffffffffffffffffffffffffffff91827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc541615610b6c5781602091810103126105d557610af0906126d8565b168015610b4257807f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c379557fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab600080a280f35b60046040517f84744201000000000000000000000000000000000000000000000000000000008152fd5b60046040517fbf10dd3a000000000000000000000000000000000000000000000000000000008152fd5b5080fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb9397025473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b506101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857610cb06126b5565b67ffffffffffffffff906044358281116110c357610cd29036906004016126f9565b916064358481116110bf57610ceb9036906004016125e4565b93909260843586811161066057610d069036906004016125e4565b60a4979197358281116110bb57610d219036906004016125e4565b93909260c4359081116110b757610d3c9036906004016125e4565b96909573ffffffffffffffffffffffffffffffffffffffff60e4351660e43503610608576101043515156101043503610608577fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d578b92610da2913691612859565b90829073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee03610f765750506024355b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163b156105d557610e5391839160405180809581947ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b039173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af1801561061557610f62575b5050604051977f935b13f6000000000000000000000000000000000000000000000000000000008952602060048a015260208980610edb602482018c8c612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa8015610f5757610f36998b91610f39575b50610104359860e43598612e5d565b80f35b610f51915060203d811161064a5761063b8183612789565b38610f27565b6040513d8c823e3d90fd5b610f6b9061272a565b61065c578838610e99565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000060208201908152336024808401919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16604484015235606483015292949192829161100081608481016108ad565b519082855af161100e612b97565b8161105e575b5015908115611054575b5061102a578a91610ddc565b60046040517f90b8ec18000000000000000000000000000000000000000000000000000000008152fd5b90503b153861101e565b8051801592508215611073575b505038611014565b6110869250602080918301019101612ad2565b388061106b565b60046040517f6d39fcd0000000000000000000000000000000000000000000000000000000008152fd5b8a80fd5b8980fd5b8580fd5b8380fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785773ffffffffffffffffffffffffffffffffffffffff7f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f5760017fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c557f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e7528180a180f35b60046040517f492f6781000000000000000000000000000000000000000000000000000000008152fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fc097d45e5a99ca772ab5ec2e5457c2e249760944b95b0b97cbb6b03ec55bae848152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c546040519015158152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b5060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576113036126b5565b6024359060443567ffffffffffffffff81116110c35761132790369060040161296e565b7fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d5783928373ffffffffffffffffffffffffffffffffffffffff9373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85821614600014611415575050915b7f00000000000000000000000000000000000000000000000000000000000000001690813b156114105783916113ef916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af18015610615576114005750f35b6114099061272a565b6101785780f35b505050fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815233602483015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008816166044830152606482019490945294959194909282916114a181608481016108ad565b519082855af16114af612b97565b816114d5575b50159081156114cb575b5061102a57839261138a565b90503b15386114bf565b80518015925082156114ea575b5050386114b5565b6114fd9250602080918301019101612ad2565b38806114e2565b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761153c6126b5565b73ffffffffffffffffffffffffffffffffffffffff90817f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f57807fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb9397025516337f3210edd3f0fc490ffc59a4adae6f48dbda2d8e89afe5b37a0145a54762f3ecf98380a380f35b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c081360112610b96576115fc6126b5565b67ffffffffffffffff91602435916044358481116110bf576116229036906004016126f9565b90946064358181116106605761163c9036906004016125e4565b936084358381116110bb576116559036906004016125e4565b91909360a4359081116110b7576116709036906004016125e4565b9890957fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d578b9a6116a6913691612859565b908a73ffffffffffffffffffffffffffffffffffffffff9373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8582161460001461192c575050905b827f00000000000000000000000000000000000000000000000000000000000000001690813b15611928578b91611748916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af1908115610f57578a91611914575b5050807f00000000000000000000000000000000000000000000000000000000000000001694604051917f935b13f60000000000000000000000000000000000000000000000000000000083526020928360048201528381806117c1602482018d8b612a0d565b03818b5afa9081156118e95784908d926118f4575b5060249192604051928380927f70a0823100000000000000000000000000000000000000000000000000000000825230600483015286165afa9384156118e9578c946118b4575b5050828761182a92613183565b853b156110bb57899761187e97899561188e61189d946040519d8e9c8d9b8c9a7f26ef699d000000000000000000000000000000000000000000000000000000008c52608060048d015260848c0191612a0d565b91868a84030160248b0152612a0d565b92868403016044870152612a0d565b90606483015203925af18015610615576114005750f35b819c50809294503d83116118e2575b6118cd8183612789565b810103126106085798518a999091808761181d565b503d6118c3565b6040513d8e823e3d90fd5b6024925061190e90823d841161064a5761063b8183612789565b916117d6565b61191d9061272a565b61065c57883861175a565b8b80fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815233602483015273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000088161660448301526064820194909452939c9193909282916119b881608481016108ad565b519082855af16119c6612b97565b816119ec575b50159081156119e2575b5061102a578a996116e2565b90503b15386119d6565b8051801592508215611a01575b5050386119cc565b611a149250602080918301019101612ad2565b38806119f9565b5034610178577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc608081360112610b965767ffffffffffffffff906024358281116110c357611a6e9036906004016125e4565b9290916044358281116110bf57611a899036906004016125e4565b9490926064359081116105d157611aa49036906004016125e4565b959092611ab2368886612804565b6020815191012090611b12604051917f5f6970c3000000000000000000000000000000000000000000000000000000008352600435600484015260806024840152611b0160848401878b612a0d565b908382030160448401528488612a0d565b9160648201526020818073ffffffffffffffffffffffffffffffffffffffff9403818c867f0000000000000000000000000000000000000000000000000000000000000000165af1908115611c06578991611bd8575b5015611bae57611b7c87858488878b612aaf565b1615611ba557600095611b9e936108ad9260405196879560208701998a612a4c565b5190205580f35b50505050505080f35b60046040517f500c44b4000000000000000000000000000000000000000000000000000000008152fd5b611bf9915060203d8111611bff575b611bf18183612789565b810190612ad2565b38611b68565b503d611be7565b6040513d8b823e3d90fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785773ffffffffffffffffffffffffffffffffffffffff7f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f57807fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c557fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d169338180a180f35b50346101785760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760243567ffffffffffffffff8111610b9657611d189036906004016125e4565b505060206040516004358152f35b5060e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785767ffffffffffffffff6004358181116105d557611d729036906004016125e4565b9091604435818111611ec557611d8c9036906004016125e4565b6064929192358281116105d157611da79036906004016125e4565b909260843590811161066057611dc19036906004016125e4565b93909260a4359573ffffffffffffffffffffffffffffffffffffffff9889881688036106085760c435988915158a03610608577fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d576020604051809c7f935b13f60000000000000000000000000000000000000000000000000000000082528260048301528180611e5a602482018789612a0d565b03917f0000000000000000000000000000000000000000000000000000000000000000165afa9182156118e957610f369b8d93611ea5575b50611ea06024353385612c84565b612e5d565b611ebe91935060203d811161064a5761063b8183612789565b9138611e92565b8480fd5b5034610178577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c081360112610b965760243567ffffffffffffffff81116105d557611f1a9036906004016125e4565b9160443567ffffffffffffffff8111611ec557611f3b9036906004016125e4565b60649491943567ffffffffffffffff81116105d157611f5e9036906004016125e4565b9590946084359667ffffffffffffffff881161065c5761200f611f8760209936906004016125e4565b999097611f9536858c612804565b8281519101209060405193849283927f1876eed9000000000000000000000000000000000000000000000000000000008452600435600485015260c06024850152611ff9611fe88d60c48701908c612a0d565b828682030160448701528c8c612a0d565b9160648501528382030160848401528d8c612a0d565b60a43560a483015203818d73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af1908115610f57578a916123f4575b5015611bae5761207a60a4358988848b89898c8a612b4a565b9673ffffffffffffffffffffffffffffffffffffffff881615612184576000936108ad8897948b60209a6121019d99966120c2966040519889978f89019b60a435978d612aea565b5190205560405194859283927f935b13f60000000000000000000000000000000000000000000000000000000084528560048501526024840191612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa90811561217957610f36928492612158575b5060a43591612bc7565b61217291925060203d60201161064a5761063b8183612789565b903861214e565b6040513d85823e3d90fd5b9596509350505050808201926040838503126110bf5782359367ffffffffffffffff85116105d1576121bd60209161221b96860161296e565b9173ffffffffffffffffffffffffffffffffffffffff6121de8387016126d8565b169660405196879283927f935b13f60000000000000000000000000000000000000000000000000000000084528560048501526024840191612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9384156106515786946123d3575b5085604051917f70a0823100000000000000000000000000000000000000000000000000000000835230600484015260208360248173ffffffffffffffffffffffffffffffffffffffff8a165afa92831561061557829361239f575b5073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690612304848389613183565b813b156105d5578291612346916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af1908161238c575b50610580577fdd7b1484db8d21f4fbda2407f2920037dc379dd66e18b0851aa9d6c14ef493b99261057a9261055761055e9388610551612b97565b6123989097919761272a565b9538612351565b9092506020813d6020116123cb575b816123bb60209383612789565b81010312610b96575191386122c0565b3d91506123ae565b6123ed91945060203d60201161064a5761063b8183612789565b9238612264565b61240d915060203d602011611bff57611bf18183612789565b38612061565b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178577fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb93970273ffffffffffffffffffffffffffffffffffffffff81541633036124cf578190337f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c37955337fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab8380a25580f35b60046040517fb3a270d8000000000000000000000000000000000000000000000000000000008152fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f8152f35b503461017857602061015a6125d536612612565b97969096959195949294612b4a565b9181601f840112156106085782359167ffffffffffffffff8311610608576020838186019501011161060857565b60a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8201126106085767ffffffffffffffff90600435828111610608578161265d916004016125e4565b939093926024358181116106085783612678916004016125e4565b939093926044358381116106085782612693916004016125e4565b93909392606435918211610608576126ad916004016125e4565b909160843590565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361060857565b359073ffffffffffffffffffffffffffffffffffffffff8216820361060857565b9181601f840112156106085782359167ffffffffffffffff8311610608576020808501948460051b01011161060857565b67ffffffffffffffff811161273e57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6080810190811067ffffffffffffffff82111761273e57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761273e57604052565b67ffffffffffffffff811161273e57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192612810826127ca565b9161281e6040519384612789565b829481845281830111610608578281602093846000960137010152565b9080601f830112156106085781602061285693359101612804565b90565b9291909267ffffffffffffffff80851161273e578460051b60408051946020809661288682860182612789565b8099815201928501948186116106085780935b8685106128aa575050505050505050565b843586811161060857820160a091828286031261060857855192830183811089821117612940578652813560048110156106085783526128eb8a83016126d8565b8a8401528582013586840152606080830135898111610608578661291091850161283b565b90840152608092838301359389851161060857612931878d9687960161283b565b90820152815201940193612899565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b9080601f830112156106085781602061285693359101612859565b9060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126106085767ffffffffffffffff60043581811161060857836129d4916004016125e4565b9390939260243583811161060857826129ef916004016125e4565b9390939260443591821161060857612a09916004016125e4565b9091565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b969590612aaa93606095612a8e612a9c937fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f999660808d5260808d0191612a0d565b918a830360208c0152612a0d565b918783036040890152612a0d565b930152565b946108ad919294612acb9460405196879560208701998a612a4c565b5190205490565b90816020910312610608575180151581036106085790565b95612a9c7fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f999460a09996612a8e612b4099959d9e9d612b329760c08d5260c08d0191612a0d565b918483036060860152612a0d565b9460808201520152565b9792946108ad94612acb979296989398604051998a9860208a019c8d612aea565b90816020910312610608575173ffffffffffffffffffffffffffffffffffffffff811681036106085790565b3d15612bc2573d90612ba8826127ca565b91612bb66040519384612789565b82523d6000602084013e565b606090565b9160009182916040519073ffffffffffffffffffffffffffffffffffffffff60208301937fa9059cbb000000000000000000000000000000000000000000000000000000008552166024830152604482015260448152612c268161276d565b519082855af1612c34612b97565b81612c55575b5015908115612c4b575b5061102a57565b90503b1538612c44565b8051801592508215612c6a575b505038612c3a565b612c7d9250602080918301019101612ad2565b3880612c62565b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff90931660248201523060448201526064810193909352916000918291612c2681608481016108ad565b919082519283825260005b848110612d375750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b602081830181015184830182015201612cf8565b602080820181835283518091526040918284019381848460051b83010196019460009485925b858410612d8357505050505050505090565b90919293949596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc082820301845288518051600480821015612e315750612e1f83899384936001965273ffffffffffffffffffffffffffffffffffffffff8482015116848301528781015188830152612e0c6060808301519060a08091860152840190612ced565b9160808092015191818403910152612ced565b9a019401940192969594939190612d71565b8a60216024927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b919992949698999790959760805260a0526040968751927f70a0823100000000000000000000000000000000000000000000000000000000845260009a30600486015273ffffffffffffffffffffffffffffffffffffffff9160208660248186608051165afa958615613179578d96613142575b5047612ff0575b50507f00000000000000000000000000000000000000000000000000000000000000001695612f0a8488608051613183565b863b156110b757918a9796959492918894928a519b8c998a9889977fb54170840000000000000000000000000000000000000000000000000000000089526004890160a0905260a4890190612f5e92612a0d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc94858983030160248a0152612f9392612a0d565b8387820301604488015260a051612fa992612a0d565b91858303016064860152612fbc92612a0d565b90608483015203925af1908115612fe75750612fd6575050565b612fe0829161272a565b6101785750565b513d84823e3d90fd5b1561311b57817f00000000000000000000000000000000000000000000000000000000000000005b16904790823b15613117578c92898f938a8f948f958f8b8d918c93519b8c9a8b998a987fc62c2002000000000000000000000000000000000000000000000000000000008a523060048b015260248a0160e0905260e48a019061307a92612a0d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc94858a83030160448b01526130af92612a0d565b8388820301606489015260a0516130c592612a0d565b918683030160848701526130d892612a0d565b918d60a48501521660c483015203925af1801561310d576130fa575b80612ed8565b613106909b919b61272a565b99386130f4565b8a513d8e823e3d90fd5b8d80fd5b817f0000000000000000000000000000000000000000000000000000000000000000613018565b9095506020813d8211613171575b8161315d60209383612789565b8101031261316d57519438612ed1565b8c80fd5b3d9150613150565b8b513d8f823e3d90fd5b90604092835180917fdd62ed3e00000000000000000000000000000000000000000000000000000000825230600483015273ffffffffffffffffffffffffffffffffffffffff80941693846024840152826044602095869389165afa91821561335f57600092613330575b5081106131fd575b5050505050565b6132af575b91600092918380938651908101927f095ea7b300000000000000000000000000000000000000000000000000000000845260248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60448201526044815261326b8161276d565b51925af1613277612b97565b501561328657808080806131f6565b600490517f8164f842000000000000000000000000000000000000000000000000000000008152fd5b6000808551838101907f095ea7b3000000000000000000000000000000000000000000000000000000008252856024820152826044820152604481526132f48161276d565b519082875af1613302612b97565b5061320257600484517f8164f842000000000000000000000000000000000000000000000000000000008152fd5b90918382813d8311613358575b6133478183612789565b8101031261017857505190386131ee565b503d61333d565b86513d6000823e3d90fdfea264697066735822122092b491d862f5d7f0f51a05f1561f5c4485044ab0040ff8acdc07f03b840cac9b64736f6c634300081400330000000000000000000000004f4495243837681061c4743b74b3eedf548d56a50000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827120000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827120000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3
Deployed Bytecode
0x60c0604052600436101561001257600080fd5b6000803560e01c806309cc027b146125c15780630d38218a14612568578063116191b6146124f9578063167a6f90146124135780631a98b2e014611ec95780632147796014611d265780633ca2fd8e14611cc85780633f4ba83a14611c115780634916065814611a1b57806352c41eb6146115c8578063554bab3c1461150457806358181a80146112d05780635c60da1b1461125f5780635c975abb146112025780638291286c146111a95780638456cb59146110c7578063846a1bc614610c7c5780638da5cb5b14610c0b5780639a7165e414610b9a5780639ded06df14610a4b5780639fd0506d146109da578063a3499c731461070b578063d0224434146106ad578063e888e86c14610279578063f2fde38b1461017b5763facd28a91461013b57600080fd5b3461017857602061015a61014e36612989565b94939093929192612aaf565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b80fd5b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576101b36126b5565b7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0805473ffffffffffffffffffffffffffffffffffffffff90813391160361024f5782168015610225577f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc6861638480a25580f35b60046040517f49e27cff000000000000000000000000000000000000000000000000000000008152fd5b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b50346101785761028836612612565b6040989194969293959851977f935b13f600000000000000000000000000000000000000000000000000000000998a8a52602060048b01528b8a602081806102d4602482018d8d612a0d565b0373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5169e8f5afa80156106155789898c8e6103488a80966103519873ffffffffffffffffffffffffffffffffffffffff9a9161068e575b503390612c84565b878c8a8d612b4a565b166106645761039f9287878a8c610373956040519a8b9860208a019b8c612aea565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283612789565b339151902055828401906040858303126106605784359567ffffffffffffffff871161065c576103d660209361041598880161296e565b9373ffffffffffffffffffffffffffffffffffffffff6103f78589016126d8565b16986040519889948593849384528760048501526024840191612a0d565b03915afa938415610651578694610620575b5085604051917f70a0823100000000000000000000000000000000000000000000000000000000835230600484015260208360248173ffffffffffffffffffffffffffffffffffffffff8a165afa9283156106155782936105d9575b5073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3166104c6848289613183565b803b156105d55761050a83929183926040519586809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af191826105bd575b5050610580577fdd7b1484db8d21f4fbda2407f2920037dc379dd66e18b0851aa9d6c14ef493b99261057a9261055761055e9388610551612b97565b98612bc7565b3691612804565b6020815191012092604051918291602083526020830190612ced565b0390a380f35b5061058f935036925090612804565b602081519101207f7c3aa10c5d96985be6de7d2e6fa79bdef95a95a9cb272f4113b3fe1ca89fedae8280a280f35b6105c69061272a565b6105d1578638610515565b8680fd5b8280fd5b915091506020813d60201161060d575b816105f660209383612789565b81010312610608578690519138610483565b600080fd5b3d91506105e9565b6040513d84823e3d90fd5b61064391945060203d60201161064a575b61063b8183612789565b810190612b6b565b9238610427565b503d610631565b6040513d88823e3d90fd5b8880fd5b8780fd5b60046040517f35b7d550000000000000000000000000000000000000000000000000000000008152fd5b6106a7915060203d60201161064a5761063b8183612789565b38610340565b5034610178576106bc36612989565b73ffffffffffffffffffffffffffffffffffffffff6106e4828486888a8c9b99989a9c612aaf565b16610664576107029361037392604051978895602087019889612a4c565b33915190205580f35b50346101785760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576107436126b5565b60443567ffffffffffffffff81116105d5576107639036906004016125e4565b907f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05473ffffffffffffffffffffffffffffffffffffffff90813391160361024f578316916040517f8291286c000000000000000000000000000000000000000000000000000000008082526020918281600481895afa9081156109a25788916109ad575b506040519182528282600481305afa9182156109a2578892610973575b500361094957843f6024350361091f57859282610869575b505050807fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b91a27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5580f35b6108d984936108ad604051938492868401967f9ded06df00000000000000000000000000000000000000000000000000000000885260248501526044840191612a0d565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612789565b5190855af46108e6612b97565b50156108f5578238808061081d565b60046040517f97905dfb000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8f84fb24000000000000000000000000000000000000000000000000000000008152fd5b60046040517f68155f9a000000000000000000000000000000000000000000000000000000008152fd5b9091508281813d831161099b575b61098b8183612789565b8101031261060857519038610805565b503d610981565b6040513d8a823e3d90fd5b90508281813d83116109d3575b6109c48183612789565b810103126106085751386107e8565b503d6109ba565b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043567ffffffffffffffff8111610b9657610a9b9036906004016125e4565b9073ffffffffffffffffffffffffffffffffffffffff91827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc541615610b6c5781602091810103126105d557610af0906126d8565b168015610b4257807f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c379557fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab600080a280f35b60046040517f84744201000000000000000000000000000000000000000000000000000000008152fd5b60046040517fbf10dd3a000000000000000000000000000000000000000000000000000000008152fd5b5080fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb9397025473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b506101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857610cb06126b5565b67ffffffffffffffff906044358281116110c357610cd29036906004016126f9565b916064358481116110bf57610ceb9036906004016125e4565b93909260843586811161066057610d069036906004016125e4565b60a4979197358281116110bb57610d219036906004016125e4565b93909260c4359081116110b757610d3c9036906004016125e4565b96909573ffffffffffffffffffffffffffffffffffffffff60e4351660e43503610608576101043515156101043503610608577fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d578b92610da2913691612859565b90829073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee03610f765750506024355b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3163b156105d557610e5391839160405180809581947ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b039173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3165af1801561061557610f62575b5050604051977f935b13f6000000000000000000000000000000000000000000000000000000008952602060048a015260208980610edb602482018c8c612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165afa8015610f5757610f36998b91610f39575b50610104359860e43598612e5d565b80f35b610f51915060203d811161064a5761063b8183612789565b38610f27565b6040513d8c823e3d90fd5b610f6b9061272a565b61065c578838610e99565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000060208201908152336024808401919091527f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd373ffffffffffffffffffffffffffffffffffffffff16604484015235606483015292949192829161100081608481016108ad565b519082855af161100e612b97565b8161105e575b5015908115611054575b5061102a578a91610ddc565b60046040517f90b8ec18000000000000000000000000000000000000000000000000000000008152fd5b90503b153861101e565b8051801592508215611073575b505038611014565b6110869250602080918301019101612ad2565b388061106b565b60046040517f6d39fcd0000000000000000000000000000000000000000000000000000000008152fd5b8a80fd5b8980fd5b8580fd5b8380fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785773ffffffffffffffffffffffffffffffffffffffff7f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f5760017fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c557f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e7528180a180f35b60046040517f492f6781000000000000000000000000000000000000000000000000000000008152fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fc097d45e5a99ca772ab5ec2e5457c2e249760944b95b0b97cbb6b03ec55bae848152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c546040519015158152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b5060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576113036126b5565b6024359060443567ffffffffffffffff81116110c35761132790369060040161296e565b7fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d5783928373ffffffffffffffffffffffffffffffffffffffff9373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85821614600014611415575050915b7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd31690813b156114105783916113ef916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af18015610615576114005750f35b6114099061272a565b6101785780f35b505050fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815233602483015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd38816166044830152606482019490945294959194909282916114a181608481016108ad565b519082855af16114af612b97565b816114d5575b50159081156114cb575b5061102a57839261138a565b90503b15386114bf565b80518015925082156114ea575b5050386114b5565b6114fd9250602080918301019101612ad2565b38806114e2565b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761153c6126b5565b73ffffffffffffffffffffffffffffffffffffffff90817f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f57807fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb9397025516337f3210edd3f0fc490ffc59a4adae6f48dbda2d8e89afe5b37a0145a54762f3ecf98380a380f35b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c081360112610b96576115fc6126b5565b67ffffffffffffffff91602435916044358481116110bf576116229036906004016126f9565b90946064358181116106605761163c9036906004016125e4565b936084358381116110bb576116559036906004016125e4565b91909360a4359081116110b7576116709036906004016125e4565b9890957fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d578b9a6116a6913691612859565b908a73ffffffffffffffffffffffffffffffffffffffff9373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8582161460001461192c575050905b827f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd31690813b15611928578b91611748916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af1908115610f57578a91611914575b5050807f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a51694604051917f935b13f60000000000000000000000000000000000000000000000000000000083526020928360048201528381806117c1602482018d8b612a0d565b03818b5afa9081156118e95784908d926118f4575b5060249192604051928380927f70a0823100000000000000000000000000000000000000000000000000000000825230600483015286165afa9384156118e9578c946118b4575b5050828761182a92613183565b853b156110bb57899761187e97899561188e61189d946040519d8e9c8d9b8c9a7f26ef699d000000000000000000000000000000000000000000000000000000008c52608060048d015260848c0191612a0d565b91868a84030160248b0152612a0d565b92868403016044870152612a0d565b90606483015203925af18015610615576114005750f35b819c50809294503d83116118e2575b6118cd8183612789565b810103126106085798518a999091808761181d565b503d6118c3565b6040513d8e823e3d90fd5b6024925061190e90823d841161064a5761063b8183612789565b916117d6565b61191d9061272a565b61065c57883861175a565b8b80fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815233602483015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd388161660448301526064820194909452939c9193909282916119b881608481016108ad565b519082855af16119c6612b97565b816119ec575b50159081156119e2575b5061102a578a996116e2565b90503b15386119d6565b8051801592508215611a01575b5050386119cc565b611a149250602080918301019101612ad2565b38806119f9565b5034610178577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc608081360112610b965767ffffffffffffffff906024358281116110c357611a6e9036906004016125e4565b9290916044358281116110bf57611a899036906004016125e4565b9490926064359081116105d157611aa49036906004016125e4565b959092611ab2368886612804565b6020815191012090611b12604051917f5f6970c3000000000000000000000000000000000000000000000000000000008352600435600484015260806024840152611b0160848401878b612a0d565b908382030160448401528488612a0d565b9160648201526020818073ffffffffffffffffffffffffffffffffffffffff9403818c867f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165af1908115611c06578991611bd8575b5015611bae57611b7c87858488878b612aaf565b1615611ba557600095611b9e936108ad9260405196879560208701998a612a4c565b5190205580f35b50505050505080f35b60046040517f500c44b4000000000000000000000000000000000000000000000000000000008152fd5b611bf9915060203d8111611bff575b611bf18183612789565b810190612ad2565b38611b68565b503d611be7565b6040513d8b823e3d90fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785773ffffffffffffffffffffffffffffffffffffffff7f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f57807fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c557fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d169338180a180f35b50346101785760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760243567ffffffffffffffff8111610b9657611d189036906004016125e4565b505060206040516004358152f35b5060e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785767ffffffffffffffff6004358181116105d557611d729036906004016125e4565b9091604435818111611ec557611d8c9036906004016125e4565b6064929192358281116105d157611da79036906004016125e4565b909260843590811161066057611dc19036906004016125e4565b93909260a4359573ffffffffffffffffffffffffffffffffffffffff9889881688036106085760c435988915158a03610608577fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d576020604051809c7f935b13f60000000000000000000000000000000000000000000000000000000082528260048301528180611e5a602482018789612a0d565b03917f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165afa9182156118e957610f369b8d93611ea5575b50611ea06024353385612c84565b612e5d565b611ebe91935060203d811161064a5761063b8183612789565b9138611e92565b8480fd5b5034610178577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c081360112610b965760243567ffffffffffffffff81116105d557611f1a9036906004016125e4565b9160443567ffffffffffffffff8111611ec557611f3b9036906004016125e4565b60649491943567ffffffffffffffff81116105d157611f5e9036906004016125e4565b9590946084359667ffffffffffffffff881161065c5761200f611f8760209936906004016125e4565b999097611f9536858c612804565b8281519101209060405193849283927f1876eed9000000000000000000000000000000000000000000000000000000008452600435600485015260c06024850152611ff9611fe88d60c48701908c612a0d565b828682030160448701528c8c612a0d565b9160648501528382030160848401528d8c612a0d565b60a43560a483015203818d73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165af1908115610f57578a916123f4575b5015611bae5761207a60a4358988848b89898c8a612b4a565b9673ffffffffffffffffffffffffffffffffffffffff881615612184576000936108ad8897948b60209a6121019d99966120c2966040519889978f89019b60a435978d612aea565b5190205560405194859283927f935b13f60000000000000000000000000000000000000000000000000000000084528560048501526024840191612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165afa90811561217957610f36928492612158575b5060a43591612bc7565b61217291925060203d60201161064a5761063b8183612789565b903861214e565b6040513d85823e3d90fd5b9596509350505050808201926040838503126110bf5782359367ffffffffffffffff85116105d1576121bd60209161221b96860161296e565b9173ffffffffffffffffffffffffffffffffffffffff6121de8387016126d8565b169660405196879283927f935b13f60000000000000000000000000000000000000000000000000000000084528560048501526024840191612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165afa9384156106515786946123d3575b5085604051917f70a0823100000000000000000000000000000000000000000000000000000000835230600484015260208360248173ffffffffffffffffffffffffffffffffffffffff8a165afa92831561061557829361239f575b5073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd31690612304848389613183565b813b156105d5578291612346916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af1908161238c575b50610580577fdd7b1484db8d21f4fbda2407f2920037dc379dd66e18b0851aa9d6c14ef493b99261057a9261055761055e9388610551612b97565b6123989097919761272a565b9538612351565b9092506020813d6020116123cb575b816123bb60209383612789565b81010312610b96575191386122c0565b3d91506123ae565b6123ed91945060203d60201161064a5761063b8183612789565b9238612264565b61240d915060203d602011611bff57611bf18183612789565b38612061565b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178577fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb93970273ffffffffffffffffffffffffffffffffffffffff81541633036124cf578190337f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c37955337fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab8380a25580f35b60046040517fb3a270d8000000000000000000000000000000000000000000000000000000008152fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5168152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f8152f35b503461017857602061015a6125d536612612565b97969096959195949294612b4a565b9181601f840112156106085782359167ffffffffffffffff8311610608576020838186019501011161060857565b60a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8201126106085767ffffffffffffffff90600435828111610608578161265d916004016125e4565b939093926024358181116106085783612678916004016125e4565b939093926044358381116106085782612693916004016125e4565b93909392606435918211610608576126ad916004016125e4565b909160843590565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361060857565b359073ffffffffffffffffffffffffffffffffffffffff8216820361060857565b9181601f840112156106085782359167ffffffffffffffff8311610608576020808501948460051b01011161060857565b67ffffffffffffffff811161273e57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6080810190811067ffffffffffffffff82111761273e57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761273e57604052565b67ffffffffffffffff811161273e57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192612810826127ca565b9161281e6040519384612789565b829481845281830111610608578281602093846000960137010152565b9080601f830112156106085781602061285693359101612804565b90565b9291909267ffffffffffffffff80851161273e578460051b60408051946020809661288682860182612789565b8099815201928501948186116106085780935b8685106128aa575050505050505050565b843586811161060857820160a091828286031261060857855192830183811089821117612940578652813560048110156106085783526128eb8a83016126d8565b8a8401528582013586840152606080830135898111610608578661291091850161283b565b90840152608092838301359389851161060857612931878d9687960161283b565b90820152815201940193612899565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b9080601f830112156106085781602061285693359101612859565b9060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126106085767ffffffffffffffff60043581811161060857836129d4916004016125e4565b9390939260243583811161060857826129ef916004016125e4565b9390939260443591821161060857612a09916004016125e4565b9091565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b969590612aaa93606095612a8e612a9c937fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f999660808d5260808d0191612a0d565b918a830360208c0152612a0d565b918783036040890152612a0d565b930152565b946108ad919294612acb9460405196879560208701998a612a4c565b5190205490565b90816020910312610608575180151581036106085790565b95612a9c7fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f999460a09996612a8e612b4099959d9e9d612b329760c08d5260c08d0191612a0d565b918483036060860152612a0d565b9460808201520152565b9792946108ad94612acb979296989398604051998a9860208a019c8d612aea565b90816020910312610608575173ffffffffffffffffffffffffffffffffffffffff811681036106085790565b3d15612bc2573d90612ba8826127ca565b91612bb66040519384612789565b82523d6000602084013e565b606090565b9160009182916040519073ffffffffffffffffffffffffffffffffffffffff60208301937fa9059cbb000000000000000000000000000000000000000000000000000000008552166024830152604482015260448152612c268161276d565b519082855af1612c34612b97565b81612c55575b5015908115612c4b575b5061102a57565b90503b1538612c44565b8051801592508215612c6a575b505038612c3a565b612c7d9250602080918301019101612ad2565b3880612c62565b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff90931660248201523060448201526064810193909352916000918291612c2681608481016108ad565b919082519283825260005b848110612d375750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b602081830181015184830182015201612cf8565b602080820181835283518091526040918284019381848460051b83010196019460009485925b858410612d8357505050505050505090565b90919293949596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc082820301845288518051600480821015612e315750612e1f83899384936001965273ffffffffffffffffffffffffffffffffffffffff8482015116848301528781015188830152612e0c6060808301519060a08091860152840190612ced565b9160808092015191818403910152612ced565b9a019401940192969594939190612d71565b8a60216024927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b919992949698999790959760805260a0526040968751927f70a0823100000000000000000000000000000000000000000000000000000000845260009a30600486015273ffffffffffffffffffffffffffffffffffffffff9160208660248186608051165afa958615613179578d96613142575b5047612ff0575b50507f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a51695612f0a8488608051613183565b863b156110b757918a9796959492918894928a519b8c998a9889977fb54170840000000000000000000000000000000000000000000000000000000089526004890160a0905260a4890190612f5e92612a0d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc94858983030160248a0152612f9392612a0d565b8387820301604488015260a051612fa992612a0d565b91858303016064860152612fbc92612a0d565b90608483015203925af1908115612fe75750612fd6575050565b612fe0829161272a565b6101785750565b513d84823e3d90fd5b1561311b57817f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827125b16904790823b15613117578c92898f938a8f948f958f8b8d918c93519b8c9a8b998a987fc62c2002000000000000000000000000000000000000000000000000000000008a523060048b015260248a0160e0905260e48a019061307a92612a0d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc94858a83030160448b01526130af92612a0d565b8388820301606489015260a0516130c592612a0d565b918683030160848701526130d892612a0d565b918d60a48501521660c483015203925af1801561310d576130fa575b80612ed8565b613106909b919b61272a565b99386130f4565b8a513d8e823e3d90fd5b8d80fd5b817f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a082712613018565b9095506020813d8211613171575b8161315d60209383612789565b8101031261316d57519438612ed1565b8c80fd5b3d9150613150565b8b513d8f823e3d90fd5b90604092835180917fdd62ed3e00000000000000000000000000000000000000000000000000000000825230600483015273ffffffffffffffffffffffffffffffffffffffff80941693846024840152826044602095869389165afa91821561335f57600092613330575b5081106131fd575b5050505050565b6132af575b91600092918380938651908101927f095ea7b300000000000000000000000000000000000000000000000000000000845260248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60448201526044815261326b8161276d565b51925af1613277612b97565b501561328657808080806131f6565b600490517f8164f842000000000000000000000000000000000000000000000000000000008152fd5b6000808551838101907f095ea7b3000000000000000000000000000000000000000000000000000000008252856024820152826044820152604481526132f48161276d565b519082875af1613302612b97565b5061320257600484517f8164f842000000000000000000000000000000000000000000000000000000008152fd5b90918382813d8311613358575b6133478183612789565b8101031261017857505190386131ee565b503d61333d565b86513d6000823e3d90fdfea264697066735822122092b491d862f5d7f0f51a05f1561f5c4485044ab0040ff8acdc07f03b840cac9b64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a50000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827120000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827120000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3
-----Decoded View---------------
Arg [0] : _gateway (address): 0x4F4495243837681061C4743b74B3eEdf548D56A5
Arg [1] : _gasService (address): 0x2d5d7d31F671F86C782533cc367F14109a082712
Arg [2] : _forecallGasService (address): 0x2d5d7d31F671F86C782533cc367F14109a082712
Arg [3] : _multicall (address): 0x4fd39C9E151e50580779bd04B1f7eCc310079fd3
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5
Arg [1] : 0000000000000000000000002d5d7d31f671f86c782533cc367f14109a082712
Arg [2] : 0000000000000000000000002d5d7d31f671f86c782533cc367f14109a082712
Arg [3] : 0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.