Latest 25 from a total of 68,260 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer V2With ... | 424709113 | 2 mins ago | IN | 0.00002703 ETH | 0.00000369 | ||||
| Transfer V2With ... | 424699362 | 43 mins ago | IN | 0.00002706 ETH | 0.00000351 | ||||
| Transfer V2With ... | 424698677 | 46 mins ago | IN | 0.00002706 ETH | 0.0000035 | ||||
| Transfer V2With ... | 424696441 | 55 mins ago | IN | 0.00002707 ETH | 0.0000035 | ||||
| Transfer V2With ... | 424696351 | 55 mins ago | IN | 0.00002707 ETH | 0.00000369 | ||||
| Transfer V2With ... | 424695853 | 57 mins ago | IN | 0.00002707 ETH | 0.0000037 | ||||
| Transfer V2With ... | 424690553 | 1 hr ago | IN | 0.00002706 ETH | 0.00000356 | ||||
| Transfer V2With ... | 424689737 | 1 hr ago | IN | 0.00002706 ETH | 0.00000354 | ||||
| Transfer V2With ... | 424688290 | 1 hr ago | IN | 0.00002706 ETH | 0.00000358 | ||||
| Transfer V2With ... | 424680793 | 2 hrs ago | IN | 0.00002705 ETH | 0.00000351 | ||||
| Transfer V2With ... | 424677382 | 2 hrs ago | IN | 0.0000338 ETH | 0.00000368 | ||||
| Transfer V2With ... | 424675863 | 2 hrs ago | IN | 0.00002704 ETH | 0.00000368 | ||||
| Transfer V2With ... | 424675019 | 2 hrs ago | IN | 0.00002704 ETH | 0.00000373 | ||||
| Transfer V2With ... | 424669841 | 2 hrs ago | IN | 0 ETH | 0.0000035 | ||||
| Transfer V2With ... | 424666152 | 3 hrs ago | IN | 0.00002708 ETH | 0.00000359 | ||||
| Transfer V2With ... | 424660519 | 3 hrs ago | IN | 0.00002708 ETH | 0.0000035 | ||||
| Transfer V2With ... | 424655846 | 3 hrs ago | IN | 0 ETH | 0.00000346 | ||||
| Transfer V2With ... | 424653695 | 3 hrs ago | IN | 0.00003386 ETH | 0.0000035 | ||||
| Transfer V2With ... | 424650178 | 4 hrs ago | IN | 0.00002706 ETH | 0.00000352 | ||||
| Transfer V2With ... | 424642016 | 4 hrs ago | IN | 0.00002704 ETH | 0.00000353 | ||||
| Transfer V2With ... | 424639435 | 4 hrs ago | IN | 0.00002705 ETH | 0.0000035 | ||||
| Transfer V2With ... | 424639293 | 4 hrs ago | IN | 0.00023342 ETH | 0.0000035 | ||||
| Transfer V2With ... | 424633881 | 5 hrs ago | IN | 0.00002706 ETH | 0.00000354 | ||||
| Transfer With Pe... | 424631409 | 5 hrs ago | IN | 0.00002707 ETH | 0.00000323 | ||||
| Transfer V2With ... | 424624881 | 5 hrs ago | IN | 0.00002702 ETH | 0.00000349 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 424389310 | 22 hrs ago | 0.00002728 ETH | ||||
| 424053279 | 45 hrs ago | 0.00254628 ETH | ||||
| 423954194 | 2 days ago | 0.0139923 ETH | ||||
| 423186229 | 4 days ago | 0.0030267 ETH | ||||
| 422812369 | 5 days ago | 0.00323389 ETH | ||||
| 422421112 | 6 days ago | 0.01072441 ETH | ||||
| 421588503 | 9 days ago | 0.0066256 ETH | ||||
| 420952039 | 10 days ago | 0.01591661 ETH | ||||
| 420009688 | 13 days ago | 0.00891864 ETH | ||||
| 419896443 | 13 days ago | 0.00002585 ETH | ||||
| 419387558 | 15 days ago | 0.02583255 ETH | ||||
| 417978719 | 19 days ago | 0.03261347 ETH | ||||
| 417967440 | 19 days ago | 0.00002548 ETH | ||||
| 416144933 | 24 days ago | 0.028197 ETH | ||||
| 414742988 | 28 days ago | 0.00002745 ETH | ||||
| 414384877 | 29 days ago | 0.02589739 ETH | ||||
| 413822645 | 31 days ago | 0.00002696 ETH | ||||
| 412236964 | 36 days ago | 0.01481651 ETH | ||||
| 411279959 | 38 days ago | 0.01693541 ETH | ||||
| 410165827 | 42 days ago | 0.02248946 ETH | ||||
| 408523638 | 46 days ago | 0.03325137 ETH | ||||
| 408150404 | 47 days ago | 0.00019533 ETH | ||||
| 406480009 | 52 days ago | 0.10129944 ETH | ||||
| 402855773 | 63 days ago | 0.000029 ETH | ||||
| 402417765 | 64 days ago | 0.10535138 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
CashmereCCTP
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 10000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
import {ITokenMessenger} from "./circle/ITokenMessenger.sol";
import {ITokenMessengerV2} from "./circle/ITokenMessengerV2.sol";
contract CashmereCCTP is AccessControl {
error FeeExceedsAmount();
error TransferFailed();
error NativeTransferFailed();
error InvalidSignature();
error DeadlineExpired();
error NativeAmountTooLow();
error GasDropLimitExceeded();
error WithdrawCooldownNotPassed();
error WithdrawLimitExceeded();
error ReentrancyError();
error InvalidSignatureLength();
error Paused();
error BPTooHigh();
error ZeroLimit();
uint256 private constant BP = 10000;
bytes32 private constant EMPTY_BYTES32 = bytes32(0);
struct State {
// -- slot (total 32 bytes)
address signer; // 20 bytes
uint32 nonce; // 4 bytes
uint32 maxUSDCGasDrop; // 4 bytes, should be enough for $4k
uint16 feeBP; // 2 bytes
bool reentrancyLock; // 1 byte
bool paused; // 1 byte
// -- slot (total 32 bytes)
uint128 maxNativeGasDrop; // 16 bytes, should be enough for 3e20 ether
uint128 lastFeeWithdrawTimestamp; // 16 bytes
}
State public state;
uint32 public immutable localDomain;
ITokenMessenger public immutable tokenMessenger;
ITokenMessengerV2 public immutable tokenMessengerV2;
address public immutable usdc;
/* NOTE: _transferFrom doesn't check return value,
which might be correct only for USDC, but not for other tokens.
*/
uint256 private constant MAX_FEE_BP = 100; // 1%
uint256 private constant FEE_WITHDRAW_COOLDOWN = 4 hours;
uint256 private constant FEE_WITHDRAW_LIMIT = 10000 * 1e6; // 10000 USDC
event FeeBPUpdated(uint16 feeBP);
event SignerUpdated(address newSigner);
event FeeWithdraw(address destination, uint256 amount, uint256 nativeAmount);
event PausedUpdated(bool paused);
event MaxUSDCGasDropUpdated(uint64 newLimit);
event MaxNativeGasDropUpdated(uint256 newLimit);
event CashmereTransfer(
uint32 destinationDomain,
uint256 indexed nonce,
bytes32 recipient,
bytes32 solanaOwner,
address indexed user,
uint64 amount,
uint256 gasDropAmount,
bool isNative
);
struct TransferParams {
uint64 amount;
uint128 fee;
uint64 deadline;
uint128 gasDropAmount;
uint32 destinationDomain;
bytes32 recipient;
bytes32 solanaOwner;
bool isNative;
bytes signature;
}
struct TransferV2Params {
uint64 amount;
uint256 maxFee;
uint128 fee;
uint64 deadline;
uint128 gasDropAmount;
uint32 destinationDomain;
uint32 minFinalityThreshold;
bytes32 recipient;
bytes32 solanaOwner;
bool isNative;
bytes hookData;
bytes signature;
}
struct PermitParams {
uint256 value;
uint256 deadline;
bytes signature;
}
constructor(
address _tokenMessenger,
address _tokenMessengerV2,
address _usdc
) {
tokenMessenger = ITokenMessenger(_tokenMessenger);
tokenMessengerV2 = ITokenMessengerV2(_tokenMessengerV2);
localDomain = tokenMessenger.localMessageTransmitter().localDomain();
usdc = _usdc;
state.maxUSDCGasDrop = 100_000_000; // 100 USDC
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
resetApprove();
}
modifier _verifySignature(bytes32 _hash, bytes memory _sig) {
bytes32 r;
bytes32 s;
uint8 v;
if (_sig.length != 65) {
revert InvalidSignatureLength();
}
assembly {
/*
First 32 bytes stores the length of the signature
add(sig, 32) = pointer of sig + 32
effectively, skips first 32 bytes of signature
mload(p) loads next 32 bytes starting at the memory address p into memory
*/
// first 32 bytes, after the length prefix
r := mload(add(_sig, 32))
// second 32 bytes
s := mload(add(_sig, 64))
// final byte (first byte of the next 32 bytes)
v := byte(0, mload(add(_sig, 96)))
}
if (ecrecover(_hash, v, r, s) != state.signer) {
revert InvalidSignature();
}
_;
}
modifier nonReentrant() {
if (state.reentrancyLock)
revert ReentrancyError();
state.reentrancyLock = true;
_;
state.reentrancyLock = false;
}
modifier checkPause() {
if (state.paused)
revert Paused();
_;
}
function _transferFrom(address from, address to, uint256 amount) private {
(bool success, ) = usdc.call(
abi.encodeWithSelector(
IERC20.transferFrom.selector,
from,
to,
amount
)
);
if (!success) {
revert TransferFailed();
}
}
function getFee(
uint64 _amount,
uint256 _staticFee
) public view returns (uint64) {
return uint64((_amount * state.feeBP) / BP + _staticFee);
}
function setFeeBP(uint16 _feeBP) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (_feeBP > MAX_FEE_BP) {
revert BPTooHigh();
}
state.feeBP = _feeBP;
emit FeeBPUpdated(_feeBP);
}
function setPaused(bool _paused) external onlyRole(DEFAULT_ADMIN_ROLE) {
state.paused = _paused;
emit PausedUpdated(_paused);
}
function setSigner(address _signer) external onlyRole(DEFAULT_ADMIN_ROLE) {
state.signer = _signer;
emit SignerUpdated(_signer);
}
function setMaxUSDCGasDrop(uint32 _newLimit) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (_newLimit == 0) {
revert ZeroLimit();
}
state.maxUSDCGasDrop = _newLimit;
emit MaxUSDCGasDropUpdated(_newLimit);
}
function setMaxNativeGasDrop(uint128 _newLimit) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (_newLimit == 0) {
revert ZeroLimit();
}
state.maxNativeGasDrop = _newLimit;
emit MaxNativeGasDropUpdated(_newLimit);
}
function withdrawFee(
uint256 _usdcAmount,
uint256 _nativeAmount,
address _destination
) external onlyRole(DEFAULT_ADMIN_ROLE) nonReentrant {
uint128 timestamp = uint128(block.timestamp);
if (timestamp - state.lastFeeWithdrawTimestamp < FEE_WITHDRAW_COOLDOWN) {
revert WithdrawCooldownNotPassed();
}
if (_usdcAmount > FEE_WITHDRAW_LIMIT) {
revert WithdrawLimitExceeded();
}
IERC20(usdc).transfer(_destination, _usdcAmount);
(bool success, ) = payable(_destination).call{value: _nativeAmount}("");
if (!success) {
revert NativeTransferFailed();
}
state.lastFeeWithdrawTimestamp = timestamp;
emit FeeWithdraw(_destination, _usdcAmount, _nativeAmount);
}
function resetApprove() public onlyRole(DEFAULT_ADMIN_ROLE) {
IERC20(usdc).approve(address(tokenMessenger), type(uint256).max);
if (address(tokenMessengerV2) != address(0))
IERC20(usdc).approve(address(tokenMessengerV2), type(uint256).max);
}
function transfer(
TransferParams memory _params
)
payable
external
nonReentrant
{
_transfer(_params);
}
function transferV2(
TransferV2Params memory _params
)
payable
external
nonReentrant
{
_transferV2(_params);
}
function _beforeTransfer(
uint256 deadline,
uint64 amount,
uint32 destinationDomain,
bool isNative,
uint256 fee,
uint256 gasDropAmount
) internal checkPause() returns (uint64) {
if (block.timestamp > deadline)
revert DeadlineExpired();
uint64 usdcTransferAmount = amount;
uint64 usdcFeeAmount = getFee(amount, isNative ? 0 : uint64(fee));
if (isNative) {
if (gasDropAmount > state.maxNativeGasDrop)
revert GasDropLimitExceeded();
} else {
if (gasDropAmount > state.maxUSDCGasDrop)
revert GasDropLimitExceeded();
}
if (!isNative)
usdcTransferAmount += uint64(gasDropAmount);
if (amount < usdcFeeAmount)
revert FeeExceedsAmount();
address sender = msg.sender;
_transferFrom(sender, address(this), usdcTransferAmount);
amount -= usdcFeeAmount;
if (isNative) {
uint256 nativeFeeAmount = fee + gasDropAmount;
if (nativeFeeAmount > msg.value) {
revert NativeAmountTooLow();
}
uint256 change = msg.value - nativeFeeAmount;
if (change > 0) {
(bool success, ) = sender.call{value: change}("");
if (!success)
revert NativeTransferFailed();
}
}
return amount;
}
function _transfer(
TransferParams memory _params
)
internal
_verifySignature(
keccak256(
abi.encodePacked(
localDomain,
_params.destinationDomain,
_params.fee,
_params.deadline,
_params.isNative,
uint8(1)
)
),
_params.signature
)
{
uint64 amount = _beforeTransfer(
_params.deadline,
_params.amount,
_params.destinationDomain,
_params.isNative,
_params.fee,
_params.gasDropAmount
);
tokenMessenger.depositForBurn(
amount,
_params.destinationDomain,
_params.recipient,
usdc
);
unchecked {
emit CashmereTransfer(
_params.destinationDomain,
state.nonce++,
_params.recipient,
_params.solanaOwner,
msg.sender,
amount,
_params.gasDropAmount,
_params.isNative
);
}
}
function _transferV2(
TransferV2Params memory _params
)
internal
_verifySignature(
keccak256(
abi.encodePacked(
localDomain,
_params.destinationDomain,
_params.fee,
_params.deadline,
_params.isNative,
uint8(2)
)
),
_params.signature
)
{
uint64 amount = _beforeTransfer(
_params.deadline,
_params.amount,
_params.destinationDomain,
_params.isNative,
_params.fee,
_params.gasDropAmount
);
tokenMessengerV2.depositForBurnWithHook(
amount,
_params.destinationDomain,
_params.recipient,
usdc,
EMPTY_BYTES32,
_params.maxFee,
_params.minFinalityThreshold,
_params.hookData
);
unchecked {
emit CashmereTransfer(
_params.destinationDomain,
state.nonce++,
_params.recipient,
_params.solanaOwner,
msg.sender,
amount,
_params.gasDropAmount,
_params.isNative
);
}
}
// --- Permit variant --------------------------------------------------
function _handlePermit(PermitParams memory _permitParams) internal {
IUSDCPermit(usdc).permit(
msg.sender,
address(this),
_permitParams.value,
_permitParams.deadline,
_permitParams.signature
);
}
function transferWithPermit(
TransferParams memory _params,
PermitParams memory _permitParams
) payable external nonReentrant {
_handlePermit(_permitParams);
_transfer(_params);
}
function transferV2WithPermit(
TransferV2Params memory _params,
PermitParams memory _permitParams
) payable external nonReentrant {
_handlePermit(_permitParams);
_transferV2(_params);
}
}
interface IUSDCPermit is IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
bytes memory signature
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {IERC165, ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[ERC-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC-20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
import {IMessageTransmitter} from "./IMessageTransmitter.sol";
interface ITokenMessenger {
function depositForBurn(
uint256 amount,
uint32 destinationDomain,
bytes32 mintRecipient,
address burnToken
) external returns (uint64 _nonce);
function localMessageTransmitter() external view returns (IMessageTransmitter);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
interface ITokenMessengerV2 {
function depositForBurn(
uint256 amount,
uint32 destinationDomain,
bytes32 mintRecipient,
address burnToken,
bytes32 destinationCaller,
uint256 maxFee,
uint32 minFinalityThreshold
) external;
function depositForBurnWithHook(
uint256 amount,
uint32 destinationDomain,
bytes32 mintRecipient,
address burnToken,
bytes32 destinationCaller,
uint256 maxFee,
uint32 minFinalityThreshold,
bytes calldata hookData
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)
pragma solidity >=0.8.4;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted to signal this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
interface IMessageTransmitter {
function receiveMessage(
bytes memory message,
bytes memory attestation
) external;
function localDomain() external view returns (uint32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"forge-std/=lib/forge-std/src/",
"surl/=lib/surl/src/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@layerzerolabs/=node_modules/@layerzerolabs/",
"@stargatefinance/=node_modules/@stargatefinance/",
"ds-test/=lib/wormhole-solidity-sdk/lib/forge-std/lib/ds-test/src/",
"wormhole-solidity-sdk/=lib/wormhole-solidity-sdk/src/"
],
"optimizer": {
"enabled": true,
"runs": 10000000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_tokenMessenger","type":"address"},{"internalType":"address","name":"_tokenMessengerV2","type":"address"},{"internalType":"address","name":"_usdc","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"BPTooHigh","type":"error"},{"inputs":[],"name":"DeadlineExpired","type":"error"},{"inputs":[],"name":"FeeExceedsAmount","type":"error"},{"inputs":[],"name":"GasDropLimitExceeded","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidSignatureLength","type":"error"},{"inputs":[],"name":"NativeAmountTooLow","type":"error"},{"inputs":[],"name":"NativeTransferFailed","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"inputs":[],"name":"ReentrancyError","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"WithdrawCooldownNotPassed","type":"error"},{"inputs":[],"name":"WithdrawLimitExceeded","type":"error"},{"inputs":[],"name":"ZeroLimit","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"recipient","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"solanaOwner","type":"bytes32"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint64","name":"amount","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"gasDropAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isNative","type":"bool"}],"name":"CashmereTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"feeBP","type":"uint16"}],"name":"FeeBPUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"destination","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"name":"FeeWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"MaxNativeGasDropUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"newLimit","type":"uint64"}],"name":"MaxUSDCGasDropUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newSigner","type":"address"}],"name":"SignerUpdated","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_amount","type":"uint64"},{"internalType":"uint256","name":"_staticFee","type":"uint256"}],"name":"getFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetApprove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_feeBP","type":"uint16"}],"name":"setFeeBP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_newLimit","type":"uint128"}],"name":"setMaxNativeGasDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_newLimit","type":"uint32"}],"name":"setMaxUSDCGasDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint32","name":"maxUSDCGasDrop","type":"uint32"},{"internalType":"uint16","name":"feeBP","type":"uint16"},{"internalType":"bool","name":"reentrancyLock","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"uint128","name":"maxNativeGasDrop","type":"uint128"},{"internalType":"uint128","name":"lastFeeWithdrawTimestamp","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenMessenger","outputs":[{"internalType":"contract ITokenMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenMessengerV2","outputs":[{"internalType":"contract ITokenMessengerV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"amount","type":"uint64"},{"internalType":"uint128","name":"fee","type":"uint128"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint128","name":"gasDropAmount","type":"uint128"},{"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"solanaOwner","type":"bytes32"},{"internalType":"bool","name":"isNative","type":"bool"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct CashmereCCTP.TransferParams","name":"_params","type":"tuple"}],"name":"transfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"amount","type":"uint64"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"uint128","name":"fee","type":"uint128"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint128","name":"gasDropAmount","type":"uint128"},{"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"internalType":"uint32","name":"minFinalityThreshold","type":"uint32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"solanaOwner","type":"bytes32"},{"internalType":"bool","name":"isNative","type":"bool"},{"internalType":"bytes","name":"hookData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct CashmereCCTP.TransferV2Params","name":"_params","type":"tuple"}],"name":"transferV2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"amount","type":"uint64"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"uint128","name":"fee","type":"uint128"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint128","name":"gasDropAmount","type":"uint128"},{"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"internalType":"uint32","name":"minFinalityThreshold","type":"uint32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"solanaOwner","type":"bytes32"},{"internalType":"bool","name":"isNative","type":"bool"},{"internalType":"bytes","name":"hookData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct CashmereCCTP.TransferV2Params","name":"_params","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct CashmereCCTP.PermitParams","name":"_permitParams","type":"tuple"}],"name":"transferV2WithPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"amount","type":"uint64"},{"internalType":"uint128","name":"fee","type":"uint128"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint128","name":"gasDropAmount","type":"uint128"},{"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"solanaOwner","type":"bytes32"},{"internalType":"bool","name":"isNative","type":"bool"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct CashmereCCTP.TransferParams","name":"_params","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct CashmereCCTP.PermitParams","name":"_permitParams","type":"tuple"}],"name":"transferWithPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_usdcAmount","type":"uint256"},{"internalType":"uint256","name":"_nativeAmount","type":"uint256"},{"internalType":"address","name":"_destination","type":"address"}],"name":"withdrawFee","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
61010060405234801561001157600080fd5b5060405161337838038061337883398101604081905261003091610383565b6001600160a01b0380841660a081905290831660c05260408051632c12192160e01b81529051632c121921916004808201926020929091908290030181865afa158015610081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100a591906103d0565b6001600160a01b0316638d3638f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010691906103f4565b63ffffffff166080526001600160a01b03811660e0526001805463ffffffff60c01b19166205f5e160c81b17905561013f600033610150565b506101486101fc565b50505061043c565b6000828152602081815260408083206001600160a01b038516845290915281205460ff166101f2576000838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556101aa3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016101f6565b5060005b92915050565b600061020781610312565b60e05160a05160405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af115801561025d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610281919061041a565b5060c0516001600160a01b03161561030f5760e05160c05160405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af11580156102e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030d919061041a565b505b50565b61030f81336000828152602081815260408083206001600160a01b038516845290915290205460ff1661030d5760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440160405180910390fd5b6001600160a01b038116811461030f57600080fd5b60008060006060848603121561039857600080fd5b83516103a38161036e565b60208501519093506103b48161036e565b60408501519092506103c58161036e565b809150509250925092565b6000602082840312156103e257600080fd5b81516103ed8161036e565b9392505050565b60006020828403121561040657600080fd5b815163ffffffff811681146103ed57600080fd5b60006020828403121561042c57600080fd5b815180151581146103ed57600080fd5b60805160a05160c05160e051612ea16104d7600039600081816102d00152818161090f015281816113150152818161144a0152818161198001528181611e3201528181611fce01526124630152600081816104a501528181611385015281816113fc0152611dff015260008181610329015281816112c701526119ab0152600081816103c30152818161167f0152611b380152612ea16000f3fe60806040526004361061018b5760003560e01c806370e604ed116100d6578063ae0026a51161007f578063c19d93fb11610059578063c19d93fb146104fa578063d547741f1461067f578063daacd2281461069f57600080fd5b8063ae0026a514610493578063ba268351146104c7578063bd8f5542146104e757600080fd5b8063914a037f116100b0578063914a037f1461040d57806391d148541461042d578063a217fddf1461047e57600080fd5b806370e604ed146103915780638d3638f4146103b15780638f9fc08b146103fa57600080fd5b80633974d1a41161013857806351f9ec781161011257806351f9ec781461034b5780636827806f1461035e5780636c19e7831461037157600080fd5b80633974d1a4146102855780633e413bee146102be578063461178301461031757600080fd5b8063248a9ca311610169578063248a9ca3146102075780632f2ff15d1461024557806336568abe1461026557600080fd5b806301ffc9a714610190578063033732ed146101c557806316c38b3c146101e7575b600080fd5b34801561019c57600080fd5b506101b06101ab36600461250a565b6106b4565b60405190151581526020015b60405180910390f35b3480156101d157600080fd5b506101e56101e0366004612575565b61074d565b005b3480156101f357600080fd5b506101e56102023660046125c3565b610ace565b34801561021357600080fd5b506102376102223660046125e0565b60009081526020819052604090206001015490565b6040519081526020016101bc565b34801561025157600080fd5b506101e56102603660046125f9565b610b68565b34801561027157600080fd5b506101e56102803660046125f9565b610b93565b34801561029157600080fd5b506102a56102a0366004612646565b610bf1565b60405167ffffffffffffffff90911681526020016101bc565b3480156102ca57600080fd5b506102f27f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b34801561032357600080fd5b506102f27f000000000000000000000000000000000000000000000000000000000000000081565b6101e5610359366004612895565b610c50565b6101e561036c3660046129e3565b610d2c565b34801561037d57600080fd5b506101e561038c366004612a18565b610ddd565b34801561039d57600080fd5b506101e56103ac366004612a33565b610e5b565b3480156103bd57600080fd5b506103e57f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101bc565b6101e5610408366004612ad5565b610f28565b34801561041957600080fd5b506101e5610428366004612b3e565b61100e565b34801561043957600080fd5b506101b06104483660046125f9565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561048a57600080fd5b50610237600081565b34801561049f57600080fd5b506102f27f000000000000000000000000000000000000000000000000000000000000000081565b3480156104d357600080fd5b506101e56104e2366004612b59565b6110d4565b6101e56104f5366004612b74565b6111a0565b34801561050657600080fd5b506001546002546106089173ffffffffffffffffffffffffffffffffffffffff81169163ffffffff740100000000000000000000000000000000000000008304811692780100000000000000000000000000000000000000000000000081049091169161ffff7c01000000000000000000000000000000000000000000000000000000008304169160ff7e0100000000000000000000000000000000000000000000000000000000000082048116927f010000000000000000000000000000000000000000000000000000000000000090920416906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041688565b6040805173ffffffffffffffffffffffffffffffffffffffff909916895263ffffffff97881660208a0152969095169587019590955261ffff909216606086015215156080850152151560a08401526fffffffffffffffffffffffffffffffff91821660c08401521660e0820152610100016101bc565b34801561068b57600080fd5b506101e561069a3660046125f9565b61125a565b3480156106ab57600080fd5b506101e561127f565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061074757507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000610758816114bc565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff16156107b7576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905560025442906138409061083a906fffffffffffffffffffffffffffffffff7001000000000000000000000000000000009091041683612bd9565b6fffffffffffffffffffffffffffffffff161015610884576040517f8c67ec2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6402540be4008511156108c3576040517f14f310c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015610958573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097c9190612c01565b5060008373ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146109d7576040519150601f19603f3d011682016040523d82523d6000602084013e6109dc565b606091505b5050905080610a17576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280546fffffffffffffffffffffffffffffffff8481167001000000000000000000000000000000000291161790556040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018890529081018690527f5c170c563ea37bd3580cc3b1c6d0d9e35c29182d2e26ce550917bdb7ef34bbcd9060600160405180910390a15050600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905550505050565b6000610ad9816114bc565b600180548315157f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091161790556040517f31311016d7204faff81880133e3db244ae8a8b9ce15e83e2432258226d15f94290610b5c90841515815260200190565b60405180910390a15050565b600082815260208190526040902060010154610b83816114bc565b610b8d83836114c6565b50505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610be2576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bec82826115c2565b505050565b600154600090829061271090610c2b907c0100000000000000000000000000000000000000000000000000000000900461ffff1686612c1e565b67ffffffffffffffff16610c3f9190612c48565b610c499190612c83565b9392505050565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff1615610caf576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055610d018161167d565b50600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff1615610d8b576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055610d0181611b1e565b6000610de8816114bc565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519081527f5553331329228fbd4123164423717a4a7539f6dfa1c3279a923b98fd681a6c7390602001610b5c565b6000610e66816114bc565b60648261ffff161115610ea5576040517f5729169200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000061ffff8516908102919091179091556040519081527ff3fd883c20f30c82e056937cd20d1d8366e8a3af7fe360a311ae5e39aa35c0ba90602001610b5c565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff1615610f87576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055610fd981611f85565b610fe28261167d565b5050600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055565b6000611019816114bc565b816fffffffffffffffffffffffffffffffff16600003611065576040517f96cb8a7f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff84169081179091556040519081527f7fe4661681a49384f48dc46b4622dff13e4c39724ab10796a457d7b0b28a0b7190602001610b5c565b60006110df816114bc565b8163ffffffff1660000361111f576040517f96cb8a7f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff8516908102919091179091556040519081527f716c587171174fdedd81a1eee2b0eef689facd12e32eb12fb15c7b4b45fddeb090602001610b5c565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff16156111ff576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905561125181611f85565b610fe282611b1e565b600082815260208190526040902060010154611275816114bc565b610b8d83836115c2565b600061128a816114bc565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303816000875af115801561135e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113829190612c01565b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16156114b9576040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303816000875af1158015611493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b79190612c01565b505b50565b6114b9813361203d565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff166115ba5760008381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556115583390565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610747565b506000610747565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16156115ba5760008381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8616808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610747565b7f00000000000000000000000000000000000000000000000000000000000000008160800151826020015183604001518460e00151600160405160200161178c9695949392919060e096871b7fffffffff0000000000000000000000000000000000000000000000000000000090811682529590961b909416600486015260809290921b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016600885015260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166018840152151560f890811b60208401521b7fff0000000000000000000000000000000000000000000000000000000000000016602182015260220190565b60405160208183030381529060405280519060200120816101000151600080600083516041146117e8576040517f4be6321b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505060208181015160408084015160608086015160018054855160008082529881018088528b90529290971a948201859052918101859052608081018390529394919373ffffffffffffffffffffffffffffffffffffffff9092169160a0016020604051602081039080840390855afa15801561186a573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16146118c1576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611917876040015167ffffffffffffffff16886000015189608001518a60e001518b602001516fffffffffffffffffffffffffffffffff168c606001516fffffffffffffffffffffffffffffffff166120c7565b608088015160a08901516040517f6fd3504e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015263ffffffff9092166024830152604482015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660648301529192507f000000000000000000000000000000000000000000000000000000000000000090911690636fd3504e906084016020604051808303816000875af11580156119f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1a9190612c96565b506001805463ffffffff740100000000000000000000000000000000000000008083048216808501909216027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff90921691909117909155608088015160a089015160c08a015160608b015160e08c01516040513396957f99820c9006ede8f2cc4d50fd1d69dc1dbb1e3bdd7abc6c6a7d61f77d0af9083e95611b0d959194909391928a929063ffffffff9690961686526020860194909452604085019290925267ffffffffffffffff1660608401526fffffffffffffffffffffffffffffffff166080830152151560a082015260c00190565b60405180910390a350505050505050565b60a0810151604080830151606084015161012085015183517f000000000000000000000000000000000000000000000000000000000000000060e090811b7fffffffff00000000000000000000000000000000000000000000000000000000908116602084015296901b909516602486015260809290921b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016602885015260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166038840152151560f81b908201527f020000000000000000000000000000000000000000000000000000000000000060418201526042016040516020818303038152906040528051906020012081610160015160008060008351604114611c75576040517f4be6321b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505060208181015160408084015160608086015160018054855160008082529881018088528b90529290971a948201859052918101859052608081018390529394919373ffffffffffffffffffffffffffffffffffffffff9092169160a0016020604051602081039080840390855afa158015611cf7573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614611d4e576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611da5876060015167ffffffffffffffff1688600001518960a001518a61012001518b604001516fffffffffffffffffffffffffffffffff168c608001516fffffffffffffffffffffffffffffffff166120c7565b60a088015160e089015160208a015160c08b01516101408c01516040517f779b432d00000000000000000000000000000000000000000000000000000000815295965073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169563779b432d95611e60958995919490937f000000000000000000000000000000000000000000000000000000000000000093600093929190600401612d21565b600060405180830381600087803b158015611e7a57600080fd5b505af1158015611e8e573d6000803e3d6000fd5b50506001805463ffffffff740100000000000000000000000000000000000000008083048216808501909216027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff9092169190911790915560a08a015160e08b01516101008c015160808d01516101208e01516040513398509596507f99820c9006ede8f2cc4d50fd1d69dc1dbb1e3bdd7abc6c6a7d61f77d0af9083e95611b0d959493928a92909163ffffffff9690961686526020860194909452604085019290925267ffffffffffffffff1660608401526fffffffffffffffffffffffffffffffff166080830152151560a082015260c00190565b8051602082015160408084015190517f9fd5a6cf00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001693639fd5a6cf936120089333933093929190600401612d9a565b600060405180830381600087803b15801561202257600080fd5b505af1158015612036573d6000803e3d6000fd5b5050505050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166114b7576040517fe2517d3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024810183905260440160405180910390fd5b6001546000907f0100000000000000000000000000000000000000000000000000000000000000900460ff161561212a576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86421115612164576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85600061218882876121765786612179565b60005b67ffffffffffffffff16610bf1565b905085156121e3576002546fffffffffffffffffffffffffffffffff168411156121de576040517f032459be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612241565b6001547801000000000000000000000000000000000000000000000000900463ffffffff16841115612241576040517f032459be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85612253576122508483612dfc565b91505b8067ffffffffffffffff168867ffffffffffffffff1610156122a1576040517f8399777400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336122b7813067ffffffffffffffff86166123d2565b6122c1828a612e1c565b985086156123c45760006122d58688612c83565b905034811115612311576040517fbc81f8fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061231d8234612e3c565b905080156123c15760008373ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461237f576040519150601f19603f3d011682016040523d82523d6000602084013e612384565b606091505b50509050806123bf576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b50505b509698975050505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000927f0000000000000000000000000000000000000000000000000000000000000000169161248d91612e4f565b6000604051808303816000865af19150503d80600081146124ca576040519150601f19603f3d011682016040523d82523d6000602084013e6124cf565b606091505b5050905080610b8d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006020828403121561251c57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610c4957600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461257057600080fd5b919050565b60008060006060848603121561258a57600080fd5b83359250602084013591506125a16040850161254c565b90509250925092565b80151581146114b957600080fd5b8035612570816125aa565b6000602082840312156125d557600080fd5b8135610c49816125aa565b6000602082840312156125f257600080fd5b5035919050565b6000806040838503121561260c57600080fd5b8235915061261c6020840161254c565b90509250929050565b67ffffffffffffffff811681146114b957600080fd5b803561257081612625565b6000806040838503121561265957600080fd5b823561266481612625565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156126c5576126c5612672565b60405290565b604051610180810167ffffffffffffffff811182821017156126c5576126c5612672565b80356fffffffffffffffffffffffffffffffff8116811461257057600080fd5b803563ffffffff8116811461257057600080fd5b600082601f83011261273457600080fd5b813567ffffffffffffffff81111561274e5761274e612672565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810167ffffffffffffffff8111828210171561279b5761279b612672565b6040528181528382016020018510156127b357600080fd5b816020850160208301376000918101602001919091529392505050565b600061012082840312156127e357600080fd5b6127eb6126a1565b90506127f68261263b565b8152612804602083016126ef565b60208201526128156040830161263b565b6040820152612826606083016126ef565b60608201526128376080830161270f565b608082015260a0828101359082015260c0808301359082015261285c60e083016125b8565b60e082015261010082013567ffffffffffffffff81111561287c57600080fd5b61288884828501612723565b6101008301525092915050565b6000602082840312156128a757600080fd5b813567ffffffffffffffff8111156128be57600080fd5b6128ca848285016127d0565b949350505050565b600061018082840312156128e557600080fd5b6128ed6126cb565b90506128f88261263b565b815260208281013590820152612910604083016126ef565b60408201526129216060830161263b565b6060820152612932608083016126ef565b608082015261294360a0830161270f565b60a082015261295460c0830161270f565b60c082015260e08281013590820152610100808301359082015261297b61012083016125b8565b61012082015261014082013567ffffffffffffffff81111561299c57600080fd5b6129a884828501612723565b6101408301525061016082013567ffffffffffffffff8111156129ca57600080fd5b6129d684828501612723565b6101608301525092915050565b6000602082840312156129f557600080fd5b813567ffffffffffffffff811115612a0c57600080fd5b6128ca848285016128d2565b600060208284031215612a2a57600080fd5b610c498261254c565b600060208284031215612a4557600080fd5b813561ffff81168114610c4957600080fd5b600060608284031215612a6957600080fd5b6040516060810167ffffffffffffffff81118282101715612a8c57612a8c612672565b60409081528335825260208085013590830152909150819083013567ffffffffffffffff811115612abc57600080fd5b612ac885828601612723565b6040830152505092915050565b60008060408385031215612ae857600080fd5b823567ffffffffffffffff811115612aff57600080fd5b612b0b858286016127d0565b925050602083013567ffffffffffffffff811115612b2857600080fd5b612b3485828601612a57565b9150509250929050565b600060208284031215612b5057600080fd5b610c49826126ef565b600060208284031215612b6b57600080fd5b610c498261270f565b60008060408385031215612b8757600080fd5b823567ffffffffffffffff811115612b9e57600080fd5b612b0b858286016128d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6fffffffffffffffffffffffffffffffff828116828216039081111561074757610747612baa565b600060208284031215612c1357600080fd5b8151610c49816125aa565b67ffffffffffffffff8181168382160290811690818114612c4157612c41612baa565b5092915050565b600082612c7e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8082018082111561074757610747612baa565b600060208284031215612ca857600080fd5b8151610c4981612625565b60005b83811015612cce578181015183820152602001612cb6565b50506000910152565b60008151808452612cef816020860160208601612cb3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b67ffffffffffffffff8916815263ffffffff8816602082015286604082015273ffffffffffffffffffffffffffffffffffffffff861660608201528460808201528360a082015263ffffffff831660c082015261010060e08201526000612d8c610100830184612cd7565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff8516602082015283604082015282606082015260a060808201526000612df160a0830184612cd7565b979650505050505050565b67ffffffffffffffff818116838216019081111561074757610747612baa565b67ffffffffffffffff828116828216039081111561074757610747612baa565b8181038181111561074757610747612baa565b60008251612e61818460208701612cb3565b919091019291505056fea26469706673582212203c2e29281c4d8f8e7e7fe3f7b1d11c2ca43b117f78e8bb8a54c5f7a6a9006f3c64736f6c634300081c003300000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a00000000000000000000000028b5a0e9c621a5badaa536219b3a228c8168cf5d000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831
Deployed Bytecode
0x60806040526004361061018b5760003560e01c806370e604ed116100d6578063ae0026a51161007f578063c19d93fb11610059578063c19d93fb146104fa578063d547741f1461067f578063daacd2281461069f57600080fd5b8063ae0026a514610493578063ba268351146104c7578063bd8f5542146104e757600080fd5b8063914a037f116100b0578063914a037f1461040d57806391d148541461042d578063a217fddf1461047e57600080fd5b806370e604ed146103915780638d3638f4146103b15780638f9fc08b146103fa57600080fd5b80633974d1a41161013857806351f9ec781161011257806351f9ec781461034b5780636827806f1461035e5780636c19e7831461037157600080fd5b80633974d1a4146102855780633e413bee146102be578063461178301461031757600080fd5b8063248a9ca311610169578063248a9ca3146102075780632f2ff15d1461024557806336568abe1461026557600080fd5b806301ffc9a714610190578063033732ed146101c557806316c38b3c146101e7575b600080fd5b34801561019c57600080fd5b506101b06101ab36600461250a565b6106b4565b60405190151581526020015b60405180910390f35b3480156101d157600080fd5b506101e56101e0366004612575565b61074d565b005b3480156101f357600080fd5b506101e56102023660046125c3565b610ace565b34801561021357600080fd5b506102376102223660046125e0565b60009081526020819052604090206001015490565b6040519081526020016101bc565b34801561025157600080fd5b506101e56102603660046125f9565b610b68565b34801561027157600080fd5b506101e56102803660046125f9565b610b93565b34801561029157600080fd5b506102a56102a0366004612646565b610bf1565b60405167ffffffffffffffff90911681526020016101bc565b3480156102ca57600080fd5b506102f27f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e583181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bc565b34801561032357600080fd5b506102f27f00000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a81565b6101e5610359366004612895565b610c50565b6101e561036c3660046129e3565b610d2c565b34801561037d57600080fd5b506101e561038c366004612a18565b610ddd565b34801561039d57600080fd5b506101e56103ac366004612a33565b610e5b565b3480156103bd57600080fd5b506103e57f000000000000000000000000000000000000000000000000000000000000000381565b60405163ffffffff90911681526020016101bc565b6101e5610408366004612ad5565b610f28565b34801561041957600080fd5b506101e5610428366004612b3e565b61100e565b34801561043957600080fd5b506101b06104483660046125f9565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561048a57600080fd5b50610237600081565b34801561049f57600080fd5b506102f27f00000000000000000000000028b5a0e9c621a5badaa536219b3a228c8168cf5d81565b3480156104d357600080fd5b506101e56104e2366004612b59565b6110d4565b6101e56104f5366004612b74565b6111a0565b34801561050657600080fd5b506001546002546106089173ffffffffffffffffffffffffffffffffffffffff81169163ffffffff740100000000000000000000000000000000000000008304811692780100000000000000000000000000000000000000000000000081049091169161ffff7c01000000000000000000000000000000000000000000000000000000008304169160ff7e0100000000000000000000000000000000000000000000000000000000000082048116927f010000000000000000000000000000000000000000000000000000000000000090920416906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041688565b6040805173ffffffffffffffffffffffffffffffffffffffff909916895263ffffffff97881660208a0152969095169587019590955261ffff909216606086015215156080850152151560a08401526fffffffffffffffffffffffffffffffff91821660c08401521660e0820152610100016101bc565b34801561068b57600080fd5b506101e561069a3660046125f9565b61125a565b3480156106ab57600080fd5b506101e561127f565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061074757507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000610758816114bc565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff16156107b7576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905560025442906138409061083a906fffffffffffffffffffffffffffffffff7001000000000000000000000000000000009091041683612bd9565b6fffffffffffffffffffffffffffffffff161015610884576040517f8c67ec2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6402540be4008511156108c3576040517f14f310c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018790527f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831169063a9059cbb906044016020604051808303816000875af1158015610958573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097c9190612c01565b5060008373ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d80600081146109d7576040519150601f19603f3d011682016040523d82523d6000602084013e6109dc565b606091505b5050905080610a17576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280546fffffffffffffffffffffffffffffffff8481167001000000000000000000000000000000000291161790556040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018890529081018690527f5c170c563ea37bd3580cc3b1c6d0d9e35c29182d2e26ce550917bdb7ef34bbcd9060600160405180910390a15050600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905550505050565b6000610ad9816114bc565b600180548315157f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091161790556040517f31311016d7204faff81880133e3db244ae8a8b9ce15e83e2432258226d15f94290610b5c90841515815260200190565b60405180910390a15050565b600082815260208190526040902060010154610b83816114bc565b610b8d83836114c6565b50505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610be2576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bec82826115c2565b505050565b600154600090829061271090610c2b907c0100000000000000000000000000000000000000000000000000000000900461ffff1686612c1e565b67ffffffffffffffff16610c3f9190612c48565b610c499190612c83565b9392505050565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff1615610caf576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055610d018161167d565b50600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff1615610d8b576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055610d0181611b1e565b6000610de8816114bc565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519081527f5553331329228fbd4123164423717a4a7539f6dfa1c3279a923b98fd681a6c7390602001610b5c565b6000610e66816114bc565b60648261ffff161115610ea5576040517f5729169200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000061ffff8516908102919091179091556040519081527ff3fd883c20f30c82e056937cd20d1d8366e8a3af7fe360a311ae5e39aa35c0ba90602001610b5c565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff1615610f87576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179055610fd981611f85565b610fe28261167d565b5050600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055565b6000611019816114bc565b816fffffffffffffffffffffffffffffffff16600003611065576040517f96cb8a7f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff84169081179091556040519081527f7fe4661681a49384f48dc46b4622dff13e4c39724ab10796a457d7b0b28a0b7190602001610b5c565b60006110df816114bc565b8163ffffffff1660000361111f576040517f96cb8a7f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff8516908102919091179091556040519081527f716c587171174fdedd81a1eee2b0eef689facd12e32eb12fb15c7b4b45fddeb090602001610b5c565b6001547e01000000000000000000000000000000000000000000000000000000000000900460ff16156111ff576040517f29f745a700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0100000000000000000000000000000000000000000000000000000000000017905561125181611f85565b610fe282611b1e565b600082815260208190526040902060010154611275816114bc565b610b8d83836115c2565b600061128a816114bc565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248301527f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831169063095ea7b3906044016020604051808303816000875af115801561135e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113829190612c01565b507f00000000000000000000000028b5a0e9c621a5badaa536219b3a228c8168cf5d73ffffffffffffffffffffffffffffffffffffffff16156114b9576040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000028b5a0e9c621a5badaa536219b3a228c8168cf5d811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248301527f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831169063095ea7b3906044016020604051808303816000875af1158015611493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b79190612c01565b505b50565b6114b9813361203d565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff166115ba5760008381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556115583390565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610747565b506000610747565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16156115ba5760008381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8616808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610747565b7f00000000000000000000000000000000000000000000000000000000000000038160800151826020015183604001518460e00151600160405160200161178c9695949392919060e096871b7fffffffff0000000000000000000000000000000000000000000000000000000090811682529590961b909416600486015260809290921b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016600885015260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166018840152151560f890811b60208401521b7fff0000000000000000000000000000000000000000000000000000000000000016602182015260220190565b60405160208183030381529060405280519060200120816101000151600080600083516041146117e8576040517f4be6321b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505060208181015160408084015160608086015160018054855160008082529881018088528b90529290971a948201859052918101859052608081018390529394919373ffffffffffffffffffffffffffffffffffffffff9092169160a0016020604051602081039080840390855afa15801561186a573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16146118c1576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611917876040015167ffffffffffffffff16886000015189608001518a60e001518b602001516fffffffffffffffffffffffffffffffff168c606001516fffffffffffffffffffffffffffffffff166120c7565b608088015160a08901516040517f6fd3504e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015263ffffffff9092166024830152604482015273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831811660648301529192507f00000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a90911690636fd3504e906084016020604051808303816000875af11580156119f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1a9190612c96565b506001805463ffffffff740100000000000000000000000000000000000000008083048216808501909216027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff90921691909117909155608088015160a089015160c08a015160608b015160e08c01516040513396957f99820c9006ede8f2cc4d50fd1d69dc1dbb1e3bdd7abc6c6a7d61f77d0af9083e95611b0d959194909391928a929063ffffffff9690961686526020860194909452604085019290925267ffffffffffffffff1660608401526fffffffffffffffffffffffffffffffff166080830152151560a082015260c00190565b60405180910390a350505050505050565b60a0810151604080830151606084015161012085015183517f000000000000000000000000000000000000000000000000000000000000000360e090811b7fffffffff00000000000000000000000000000000000000000000000000000000908116602084015296901b909516602486015260809290921b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016602885015260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166038840152151560f81b908201527f020000000000000000000000000000000000000000000000000000000000000060418201526042016040516020818303038152906040528051906020012081610160015160008060008351604114611c75576040517f4be6321b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505060208181015160408084015160608086015160018054855160008082529881018088528b90529290971a948201859052918101859052608081018390529394919373ffffffffffffffffffffffffffffffffffffffff9092169160a0016020604051602081039080840390855afa158015611cf7573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614611d4e576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611da5876060015167ffffffffffffffff1688600001518960a001518a61012001518b604001516fffffffffffffffffffffffffffffffff168c608001516fffffffffffffffffffffffffffffffff166120c7565b60a088015160e089015160208a015160c08b01516101408c01516040517f779b432d00000000000000000000000000000000000000000000000000000000815295965073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000028b5a0e9c621a5badaa536219b3a228c8168cf5d169563779b432d95611e60958995919490937f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e583193600093929190600401612d21565b600060405180830381600087803b158015611e7a57600080fd5b505af1158015611e8e573d6000803e3d6000fd5b50506001805463ffffffff740100000000000000000000000000000000000000008083048216808501909216027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff9092169190911790915560a08a015160e08b01516101008c015160808d01516101208e01516040513398509596507f99820c9006ede8f2cc4d50fd1d69dc1dbb1e3bdd7abc6c6a7d61f77d0af9083e95611b0d959493928a92909163ffffffff9690961686526020860194909452604085019290925267ffffffffffffffff1660608401526fffffffffffffffffffffffffffffffff166080830152151560a082015260c00190565b8051602082015160408084015190517f9fd5a6cf00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e58311693639fd5a6cf936120089333933093929190600401612d9a565b600060405180830381600087803b15801561202257600080fd5b505af1158015612036573d6000803e3d6000fd5b5050505050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166114b7576040517fe2517d3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024810183905260440160405180910390fd5b6001546000907f0100000000000000000000000000000000000000000000000000000000000000900460ff161561212a576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86421115612164576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85600061218882876121765786612179565b60005b67ffffffffffffffff16610bf1565b905085156121e3576002546fffffffffffffffffffffffffffffffff168411156121de576040517f032459be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612241565b6001547801000000000000000000000000000000000000000000000000900463ffffffff16841115612241576040517f032459be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85612253576122508483612dfc565b91505b8067ffffffffffffffff168867ffffffffffffffff1610156122a1576040517f8399777400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336122b7813067ffffffffffffffff86166123d2565b6122c1828a612e1c565b985086156123c45760006122d58688612c83565b905034811115612311576040517fbc81f8fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061231d8234612e3c565b905080156123c15760008373ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461237f576040519150601f19603f3d011682016040523d82523d6000602084013e612384565b606091505b50509050806123bf576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b50505b509698975050505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000927f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831169161248d91612e4f565b6000604051808303816000865af19150503d80600081146124ca576040519150601f19603f3d011682016040523d82523d6000602084013e6124cf565b606091505b5050905080610b8d576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006020828403121561251c57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610c4957600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461257057600080fd5b919050565b60008060006060848603121561258a57600080fd5b83359250602084013591506125a16040850161254c565b90509250925092565b80151581146114b957600080fd5b8035612570816125aa565b6000602082840312156125d557600080fd5b8135610c49816125aa565b6000602082840312156125f257600080fd5b5035919050565b6000806040838503121561260c57600080fd5b8235915061261c6020840161254c565b90509250929050565b67ffffffffffffffff811681146114b957600080fd5b803561257081612625565b6000806040838503121561265957600080fd5b823561266481612625565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156126c5576126c5612672565b60405290565b604051610180810167ffffffffffffffff811182821017156126c5576126c5612672565b80356fffffffffffffffffffffffffffffffff8116811461257057600080fd5b803563ffffffff8116811461257057600080fd5b600082601f83011261273457600080fd5b813567ffffffffffffffff81111561274e5761274e612672565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810167ffffffffffffffff8111828210171561279b5761279b612672565b6040528181528382016020018510156127b357600080fd5b816020850160208301376000918101602001919091529392505050565b600061012082840312156127e357600080fd5b6127eb6126a1565b90506127f68261263b565b8152612804602083016126ef565b60208201526128156040830161263b565b6040820152612826606083016126ef565b60608201526128376080830161270f565b608082015260a0828101359082015260c0808301359082015261285c60e083016125b8565b60e082015261010082013567ffffffffffffffff81111561287c57600080fd5b61288884828501612723565b6101008301525092915050565b6000602082840312156128a757600080fd5b813567ffffffffffffffff8111156128be57600080fd5b6128ca848285016127d0565b949350505050565b600061018082840312156128e557600080fd5b6128ed6126cb565b90506128f88261263b565b815260208281013590820152612910604083016126ef565b60408201526129216060830161263b565b6060820152612932608083016126ef565b608082015261294360a0830161270f565b60a082015261295460c0830161270f565b60c082015260e08281013590820152610100808301359082015261297b61012083016125b8565b61012082015261014082013567ffffffffffffffff81111561299c57600080fd5b6129a884828501612723565b6101408301525061016082013567ffffffffffffffff8111156129ca57600080fd5b6129d684828501612723565b6101608301525092915050565b6000602082840312156129f557600080fd5b813567ffffffffffffffff811115612a0c57600080fd5b6128ca848285016128d2565b600060208284031215612a2a57600080fd5b610c498261254c565b600060208284031215612a4557600080fd5b813561ffff81168114610c4957600080fd5b600060608284031215612a6957600080fd5b6040516060810167ffffffffffffffff81118282101715612a8c57612a8c612672565b60409081528335825260208085013590830152909150819083013567ffffffffffffffff811115612abc57600080fd5b612ac885828601612723565b6040830152505092915050565b60008060408385031215612ae857600080fd5b823567ffffffffffffffff811115612aff57600080fd5b612b0b858286016127d0565b925050602083013567ffffffffffffffff811115612b2857600080fd5b612b3485828601612a57565b9150509250929050565b600060208284031215612b5057600080fd5b610c49826126ef565b600060208284031215612b6b57600080fd5b610c498261270f565b60008060408385031215612b8757600080fd5b823567ffffffffffffffff811115612b9e57600080fd5b612b0b858286016128d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6fffffffffffffffffffffffffffffffff828116828216039081111561074757610747612baa565b600060208284031215612c1357600080fd5b8151610c49816125aa565b67ffffffffffffffff8181168382160290811690818114612c4157612c41612baa565b5092915050565b600082612c7e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8082018082111561074757610747612baa565b600060208284031215612ca857600080fd5b8151610c4981612625565b60005b83811015612cce578181015183820152602001612cb6565b50506000910152565b60008151808452612cef816020860160208601612cb3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b67ffffffffffffffff8916815263ffffffff8816602082015286604082015273ffffffffffffffffffffffffffffffffffffffff861660608201528460808201528360a082015263ffffffff831660c082015261010060e08201526000612d8c610100830184612cd7565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff8516602082015283604082015282606082015260a060808201526000612df160a0830184612cd7565b979650505050505050565b67ffffffffffffffff818116838216019081111561074757610747612baa565b67ffffffffffffffff828116828216039081111561074757610747612baa565b8181038181111561074757610747612baa565b60008251612e61818460208701612cb3565b919091019291505056fea26469706673582212203c2e29281c4d8f8e7e7fe3f7b1d11c2ca43b117f78e8bb8a54c5f7a6a9006f3c64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a00000000000000000000000028b5a0e9c621a5badaa536219b3a228c8168cf5d000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831
-----Decoded View---------------
Arg [0] : _tokenMessenger (address): 0x19330d10D9Cc8751218eaf51E8885D058642E08A
Arg [1] : _tokenMessengerV2 (address): 0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d
Arg [2] : _usdc (address): 0xaf88d065e77c8cC2239327C5EDb3A432268e5831
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a
Arg [1] : 00000000000000000000000028b5a0e9c621a5badaa536219b3a228c8168cf5d
Arg [2] : 000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.