Source Code
Latest 25 from a total of 746 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Fulfill Order | 24739686 | 1 hr ago | IN | 0 ETH | 0.00000846 | ||||
| Fulfill Order | 24739520 | 1 hr ago | IN | 0 ETH | 0.00000547 | ||||
| Fulfill Order | 24739183 | 2 hrs ago | IN | 0 ETH | 0.00000683 | ||||
| Fulfill Order | 24738960 | 3 hrs ago | IN | 0 ETH | 0.00000812 | ||||
| Fulfill Order | 24738521 | 5 hrs ago | IN | 0 ETH | 0.00000657 | ||||
| Fulfill Order | 24738459 | 5 hrs ago | IN | 0 ETH | 0.00000841 | ||||
| Fulfill Order | 24738032 | 6 hrs ago | IN | 0 ETH | 0.00001041 | ||||
| Fulfill Order | 24737802 | 7 hrs ago | IN | 0 ETH | 0.0000166 | ||||
| Fulfill Order | 24737771 | 7 hrs ago | IN | 0.01 ETH | 0.00002368 | ||||
| Fulfill Order | 24737705 | 7 hrs ago | IN | 0 ETH | 0.00002249 | ||||
| Fulfill Order | 24737588 | 8 hrs ago | IN | 0 ETH | 0.00001175 | ||||
| Fulfill Order | 24737108 | 9 hrs ago | IN | 0 ETH | 0.00001516 | ||||
| Fulfill Order | 24737102 | 9 hrs ago | IN | 0 ETH | 0.00001471 | ||||
| Fulfill Order | 24737093 | 9 hrs ago | IN | 0 ETH | 0.00001543 | ||||
| Fulfill Order | 24737021 | 10 hrs ago | IN | 0 ETH | 0.00001775 | ||||
| Fulfill Order | 24736967 | 10 hrs ago | IN | 0 ETH | 0.00001999 | ||||
| Fulfill Order | 24736960 | 10 hrs ago | IN | 0 ETH | 0.00002098 | ||||
| Fulfill Order | 24736900 | 10 hrs ago | IN | 0 ETH | 0.00004058 | ||||
| Fulfill Order | 24736873 | 10 hrs ago | IN | 0 ETH | 0.00004535 | ||||
| Fulfill Order | 24736637 | 11 hrs ago | IN | 0 ETH | 0.00001568 | ||||
| Fulfill Order | 24736461 | 11 hrs ago | IN | 0 ETH | 0.0000167 | ||||
| Fulfill Order | 24736348 | 12 hrs ago | IN | 0 ETH | 0.00002055 | ||||
| Fulfill Order | 24736342 | 12 hrs ago | IN | 0 ETH | 0.00002653 | ||||
| Fulfill Order | 24735982 | 13 hrs ago | IN | 0 ETH | 0.0000182 | ||||
| Fulfill Order | 24735980 | 13 hrs ago | IN | 0 ETH | 0.00002009 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 24740010 | 1 min ago | 0.55836772 ETH | ||||
| Fulfill Order | 24740010 | 1 min ago | 0.55836772 ETH | ||||
| Transfer | 24739963 | 11 mins ago | 0.11484559 ETH | ||||
| Fulfill Order | 24739963 | 11 mins ago | 0.11484559 ETH | ||||
| Transfer | 24739844 | 35 mins ago | 0.47175493 ETH | ||||
| Fulfill Order | 24739844 | 35 mins ago | 0.47175493 ETH | ||||
| Transfer | 24739706 | 1 hr ago | 0.04658321 ETH | ||||
| Fulfill Order | 24739706 | 1 hr ago | 0.04658321 ETH | ||||
| Transfer | 24739681 | 1 hr ago | 6.07599931 ETH | ||||
| Fulfill Order | 24739681 | 1 hr ago | 6.07599931 ETH | ||||
| Transfer | 24739581 | 1 hr ago | 0.37693395 ETH | ||||
| Fulfill Order | 24739581 | 1 hr ago | 0.37693395 ETH | ||||
| Transfer | 24739496 | 1 hr ago | 0.0025767 ETH | ||||
| Fulfill Order | 24739496 | 1 hr ago | 0.0025767 ETH | ||||
| Transfer | 24739394 | 2 hrs ago | 0.49988853 ETH | ||||
| Fulfill Order | 24739394 | 2 hrs ago | 0.49988853 ETH | ||||
| Transfer | 24739288 | 2 hrs ago | 0.04634779 ETH | ||||
| Fulfill Order | 24739288 | 2 hrs ago | 0.04634779 ETH | ||||
| Transfer | 24739177 | 2 hrs ago | 0.0018224 ETH | ||||
| Fulfill Order | 24739177 | 2 hrs ago | 0.0018224 ETH | ||||
| Transfer | 24739125 | 2 hrs ago | 2.38675527 ETH | ||||
| Fulfill Order | 24739125 | 2 hrs ago | 2.38675527 ETH | ||||
| Transfer | 24738964 | 3 hrs ago | 0.25557668 ETH | ||||
| Fulfill Order | 24738964 | 3 hrs ago | 0.25557668 ETH | ||||
| Transfer | 24738946 | 3 hrs ago | 0.17480443 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SwiftDest
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 1000 runs
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "../interfaces/IWormhole.sol";
import "../libs/BytesLib.sol";
import "../libs/SignatureVerifier.sol";
import "./SwiftStructs.sol";
import "./SwiftErrors.sol";
contract SwiftDest is ReentrancyGuard {
event OrderCreated(bytes32 key);
event OrderFulfilled(bytes32 key, uint64 sequence, uint256 fulfilledAmount);
event OrderUnlocked(bytes32 key);
event OrderCanceled(bytes32 key, uint64 sequence);
event OrderRefunded(bytes32 key, uint256 refundedAmount);
using SafeERC20 for IERC20;
using BytesLib for bytes;
using SignatureVerifier for bytes;
uint8 constant NATIVE_DECIMALS = 18;
IWormhole public immutable wormhole;
address public auctionVerifier;
uint16 public auctionChainId;
bytes32 public auctionAddr;
uint8 public consistencyLevel;
address public immutable rescueVault;
address public guardian;
address public nextGuardian;
bool public paused;
mapping(bytes32 => Order) public orders;
mapping(bytes32 => bytes) public unlockMsgs;
mapping(bytes32 => uint256) public pendingAmounts;
mapping(uint16 => bytes32) public emitters;
mapping(uint64 => bool) public usedSequences;
constructor(
address _wormhole,
address _auctionVerifier,
uint16 _auctionChainId,
bytes32 _auctionAddr,
uint8 _consistencyLevel,
address _rescueVault
) {
guardian = msg.sender;
wormhole = IWormhole(_wormhole);
auctionVerifier = _auctionVerifier;
auctionChainId = _auctionChainId;
auctionAddr = _auctionAddr;
consistencyLevel = _consistencyLevel;
rescueVault = _rescueVault;
}
function fulfillOrder(
uint256 fulfillAmount,
bytes memory encodedVm,
OrderParams memory params,
ExtraParams memory extraParams,
UnlockParams memory unlockParams,
PermitParams calldata permit
) nonReentrant public payable returns (bytes memory) {
(IWormhole.VM memory vm, bool valid, string memory reason) = IWormhole(auctionVerifier).parseAndVerifyVM(encodedVm);
require(valid, reason);
if (vm.emitterChainId != auctionChainId) {
revert InvalidEmitterChain();
}
if (vm.emitterAddress != auctionAddr) {
revert InvalidEmitterAddress();
}
FulfillMsg memory fulfillMsg = parseFulfillPayload(vm.payload);
params.destChainId = wormhole.chainId();
if (keccak256(encodeKey(buildKey(params, extraParams))) != fulfillMsg.orderHash) {
revert InvalidOrderHash();
}
address tokenOut = truncateAddress(params.tokenOut);
if (tokenOut != address(0)) {
fulfillAmount = pullTokenIn(tokenOut, fulfillAmount, permit);
}
if (truncateAddress(fulfillMsg.driver) != tx.origin && block.timestamp <= params.deadline - fulfillMsg.penaltyPeriod) {
revert Unauthorized();
}
if (block.timestamp >= params.deadline) {
revert DeadlineViolation();
}
if (orders[fulfillMsg.orderHash].status != Status.CREATED) {
revert InvalidOrderStatus();
}
if (params.payloadType == 2) {
orders[fulfillMsg.orderHash].status = Status.FULFILLED;
} else {
orders[fulfillMsg.orderHash].status = Status.SETTLED;
}
makePayments(fulfillAmount, PaymentParams({
payloadType: params.payloadType,
orderHash: fulfillMsg.orderHash,
promisedAmount: fulfillMsg.promisedAmount,
minAmountOut: params.minAmountOut,
destAddr: truncateAddress(params.destAddr),
tokenOut: tokenOut,
gasDrop: params.gasDrop,
batch: unlockParams.batch
}));
uint64 sequence = batchOrSendUnlockMsg(buildUnlockMsg(fulfillMsg.orderHash, params, extraParams, unlockParams), unlockParams.batch);
emit OrderFulfilled(fulfillMsg.orderHash, sequence, fulfillAmount);
return vm.payload;
}
function fulfillSimple(
uint256 fulfillAmount,
bytes32 orderHash,
OrderParams memory params,
ExtraParams memory extraParams,
UnlockParams memory unlockParams,
PermitParams calldata permit
) public nonReentrant payable {
if (params.auctionMode != uint8(AuctionMode.LIMIT_ORDER)) {
revert InvalidAuctionMode();
}
address tokenOut = truncateAddress(params.tokenOut);
if (tokenOut != address(0)) {
fulfillAmount = pullTokenIn(tokenOut, fulfillAmount, permit);
}
params.destChainId = wormhole.chainId();
if (keccak256(encodeKey(buildKey(params, extraParams))) != orderHash) {
revert InvalidOrderHash();
}
if (block.timestamp > params.deadline) {
revert DeadlineViolation();
}
if (orders[orderHash].status != Status.CREATED) {
revert InvalidOrderStatus();
}
if (params.payloadType == 2) {
orders[orderHash].status = Status.FULFILLED;
} else {
orders[orderHash].status = Status.SETTLED;
}
makePayments(fulfillAmount, PaymentParams({
payloadType: params.payloadType,
orderHash: orderHash,
promisedAmount: params.minAmountOut,
minAmountOut: params.minAmountOut,
destAddr: truncateAddress(params.destAddr),
tokenOut: tokenOut,
gasDrop: params.gasDrop,
batch: unlockParams.batch
}));
uint64 sequence = batchOrSendUnlockMsg(buildUnlockMsg(orderHash, params, extraParams, unlockParams), unlockParams.batch);
emit OrderFulfilled(orderHash, sequence, fulfillAmount);
}
function cancelOrder(
bytes32 orderHash,
OrderParams memory params,
ExtraParams memory extraParams,
bytes32 canceler
) public nonReentrant payable returns (uint64 sequence) {
params.destChainId = wormhole.chainId();
bytes32 computedOrderHash = keccak256(encodeKey(buildKey(params, extraParams)));
if (computedOrderHash != orderHash) {
revert InvalidOrderHash();
}
Order memory order = orders[orderHash];
if (block.timestamp <= params.deadline) {
revert DeadlineViolation();
}
if (order.status != Status.CREATED) {
revert InvalidOrderStatus();
}
orders[orderHash].status = Status.CANCELED;
RefundMsg memory refundMsg = RefundMsg({
action: uint8(Action.REFUND),
orderHash: orderHash,
srcChainId: extraParams.srcChainId,
tokenIn: extraParams.tokenIn,
trader: params.trader,
canceler: canceler,
cancelFee: params.cancelFee,
refundFee: params.refundFee
});
bytes memory encoded = encodeRefundMsg(refundMsg);
sequence = wormhole.publishMessage{
value : msg.value
}(0, encoded, consistencyLevel);
emit OrderCanceled(orderHash, sequence);
}
function postBatch(bytes32[] memory orderHashes) public payable returns (uint64 sequence) {
bytes memory encoded;
for(uint i=0; i<orderHashes.length; i++) {
bytes memory unlockMsg = unlockMsgs[orderHashes[i]];
if (unlockMsg.length != UNLOCK_MSG_SIZE) {
revert OrderNotExists(orderHashes[i]);
}
encoded = abi.encodePacked(encoded, unlockMsg);
delete unlockMsgs[orderHashes[i]];
}
bytes memory payload = abi.encodePacked(uint8(Action.COMPRESSED_UNLOCK), uint16(orderHashes.length), keccak256(encoded));
sequence = wormhole.publishMessage{
value : msg.value
}(0, payload, consistencyLevel);
}
function settleWithPayload(
OrderParams memory params,
ExtraParams memory extraParams
) nonReentrant public returns (uint256 netAmount) {
if (params.payloadType != 2) {
revert InvalidAction();
}
if (truncateAddress(params.destAddr) != msg.sender) {
revert Unauthorized();
}
params.destChainId = wormhole.chainId();
bytes32 orderHash = keccak256(encodeKey(buildKey(params, extraParams)));
if (orders[orderHash].status != Status.FULFILLED) {
revert InvalidOrderStatus();
}
orders[orderHash].status = Status.SETTLED;
netAmount = pendingAmounts[orderHash];
address tokenOut = truncateAddress(params.tokenOut);
if (tokenOut == address(0)) {
payEth(msg.sender, netAmount, true);
} else {
IERC20(tokenOut).safeTransfer(msg.sender, netAmount);
}
}
function rescue(bytes memory encodedVm) public {
if (msg.sender != guardian) {
revert Unauthorized();
}
(IWormhole.VM memory vm, bool valid, string memory reason) = IWormhole(wormhole).parseAndVerifyVM(encodedVm);
require(valid, reason);
if (usedSequences[vm.sequence]) {
revert SequenceAlreadyUsed();
}
usedSequences[vm.sequence] = true;
if (vm.emitterChainId != 1) {
revert InvalidEmitterChain();
}
if (vm.emitterAddress != emitters[1]) {
revert InvalidEmitterAddress();
}
RescueMsg memory rescueMsg = parseRescuePayload(vm.payload);
if (rescueMsg.chainId != wormhole.chainId()) {
revert InvalidSrcChain();
}
if (rescueMsg.targetContract != address(this)) {
revert InvalidTargetContract();
}
if (rescueMsg.orderHash != bytes32(0)) {
orders[rescueMsg.orderHash].status = Status(rescueMsg.orderStatus);
}
if (rescueMsg.amount > 0) {
uint256 amount = deNormalizeAmount(rescueMsg.amount, decimalsOf(rescueMsg.token));
if (rescueMsg.token == address(0)) {
payEth(rescueVault, amount, true);
} else {
IERC20(rescueMsg.token).safeTransfer(rescueVault, amount);
}
}
}
function makePayments(
uint256 fulfillAmount,
PaymentParams memory params
) internal {
uint8 decimals;
if (params.tokenOut == address(0)) {
decimals = NATIVE_DECIMALS;
} else {
decimals = decimalsOf(params.tokenOut);
}
if (fulfillAmount < deNormalizeAmount(params.promisedAmount, decimals)) {
revert InsufficientAmount();
}
if (normalizeAmount(fulfillAmount, decimals) < params.minAmountOut) {
revert InvalidAmount();
}
if (params.tokenOut == address(0)) {
if (
(params.batch && msg.value != fulfillAmount) ||
(!params.batch && msg.value != fulfillAmount + wormhole.messageFee())
) {
revert InvalidWormholeFee();
}
if (params.payloadType == 2) {
pendingAmounts[params.orderHash] = fulfillAmount;
} else {
payEth(params.destAddr, fulfillAmount, true);
}
} else {
if (params.gasDrop > 0) {
uint256 gasDrop = deNormalizeAmount(params.gasDrop, NATIVE_DECIMALS);
if (
(params.batch && msg.value != gasDrop) ||
(!params.batch && msg.value != gasDrop + wormhole.messageFee())
) {
revert InvalidGasDrop();
}
payEth(params.destAddr, gasDrop, false);
} else if (
(params.batch && msg.value != 0) ||
(!params.batch && msg.value != wormhole.messageFee())
) {
revert InvalidWormholeFee();
}
if (params.payloadType == 2) {
pendingAmounts[params.orderHash] = fulfillAmount;
} else {
IERC20(params.tokenOut).safeTransfer(params.destAddr, fulfillAmount);
}
}
}
function buildUnlockMsg(
bytes32 orderHash,
OrderParams memory params,
ExtraParams memory extraParams,
UnlockParams memory unlockParams
) internal view returns (UnlockMsg memory) {
return UnlockMsg({
action: uint8(Action.UNLOCK),
orderHash: orderHash,
srcChainId: extraParams.srcChainId,
tokenIn: extraParams.tokenIn,
referrerAddr: params.referrerAddr,
referrerBps: params.referrerBps,
protocolBps: extraParams.protocolBps,
unlockReceiver: unlockParams.recipient,
driver: unlockParams.driver,
fulfillTime: uint64(block.timestamp)
});
}
function batchOrSendUnlockMsg(UnlockMsg memory unlockMsg, bool batch) internal returns (uint64 sequence) {
bytes memory encodedUnlockMsg = encodeUnlockMsg(unlockMsg);
if (batch) {
unlockMsgs[unlockMsg.orderHash] = encodedUnlockMsg;
} else {
return wormhole.publishMessage{
value : wormhole.messageFee()
}(0, abi.encodePacked(Action.UNLOCK, encodedUnlockMsg), consistencyLevel);
}
}
function buildKey(
OrderParams memory params,
ExtraParams memory extraParams
) internal pure returns (Key memory) {
return Key({
payloadType: params.payloadType,
trader: params.trader,
srcChainId: extraParams.srcChainId,
tokenIn: extraParams.tokenIn,
destAddr: params.destAddr,
destChainId: params.destChainId,
tokenOut: params.tokenOut,
minAmountOut: params.minAmountOut,
gasDrop: params.gasDrop,
cancelFee: params.cancelFee,
refundFee: params.refundFee,
deadline: params.deadline,
referrerAddr: params.referrerAddr,
referrerBps: params.referrerBps,
protocolBps: extraParams.protocolBps,
auctionMode: params.auctionMode,
random: params.random,
customPayloadHash: extraParams.customPayloadHash
});
}
function parseFulfillPayload(bytes memory encoded) public pure returns (FulfillMsg memory fulfillMsg) {
uint index = 0;
fulfillMsg.action = encoded.toUint8(index);
index += 1;
if (fulfillMsg.action != uint8(Action.FULFILL)) {
revert InvalidAction();
}
fulfillMsg.orderHash = encoded.toBytes32(index);
index += 32;
fulfillMsg.promisedAmount = encoded.toUint64(index);
index += 8;
fulfillMsg.driver = encoded.toBytes32(index);
index += 32;
fulfillMsg.penaltyPeriod = encoded.toUint16(index);
index += 2;
}
function parseRescuePayload(bytes memory encoded) public pure returns (RescueMsg memory rescueMsg) {
uint index = 0;
rescueMsg.action = encoded.toUint8(index);
index += 1;
if (rescueMsg.action != uint8(Action.RESCUE)) {
revert InvalidAction();
}
rescueMsg.orderHash = encoded.toBytes32(index);
index += 32;
rescueMsg.orderStatus = encoded.toUint8(index);
index += 1;
rescueMsg.token = address(uint160(encoded.toUint256(index)));
index += 32;
rescueMsg.amount = encoded.toUint64(index);
index += 8;
}
function encodeKey(Key memory key) internal pure returns (bytes memory encoded) {
encoded = abi.encodePacked(
key.payloadType,
key.trader,
key.srcChainId,
key.tokenIn,
key.destAddr,
key.destChainId,
key.tokenOut,
key.minAmountOut,
key.gasDrop,
key.cancelFee,
key.refundFee,
key.deadline
);
encoded = encoded.concat(abi.encodePacked(
key.referrerAddr,
key.referrerBps,
key.protocolBps,
key.auctionMode,
key.random,
key.customPayloadHash
));
}
function encodeUnlockMsg(UnlockMsg memory unlockMsg) internal pure returns (bytes memory encoded) {
encoded = abi.encodePacked(
//unlockMsg.action,
unlockMsg.orderHash,
unlockMsg.srcChainId,
unlockMsg.tokenIn,
unlockMsg.referrerAddr,
unlockMsg.referrerBps,
unlockMsg.protocolBps,
unlockMsg.unlockReceiver,
unlockMsg.driver,
unlockMsg.fulfillTime
);
}
function encodeRefundMsg(RefundMsg memory refundMsg) internal pure returns (bytes memory encoded) {
encoded = abi.encodePacked(
refundMsg.action,
refundMsg.orderHash,
refundMsg.srcChainId,
refundMsg.tokenIn,
refundMsg.trader,
refundMsg.canceler,
refundMsg.cancelFee,
refundMsg.refundFee
);
}
function payEth(address to, uint256 amount, bool revertOnFailure) internal {
(bool success, ) = payable(to).call{value: amount}('');
if (revertOnFailure) {
require(success, 'payment failed');
}
}
function truncateAddress(bytes32 b) internal pure returns (address) {
if (bytes12(b) != 0) {
revert InvalidEvmAddr();
}
return address(uint160(uint256(b)));
}
function decimalsOf(address token) internal view returns(uint8) {
(,bytes memory queriedDecimals) = token.staticcall(abi.encodeWithSignature('decimals()'));
return abi.decode(queriedDecimals, (uint8));
}
function normalizeAmount(uint256 amount, uint8 decimals) internal pure returns(uint256) {
if (decimals > 8) {
amount /= 10 ** (decimals - 8);
}
return amount;
}
function deNormalizeAmount(uint256 amount, uint8 decimals) internal pure returns(uint256) {
if (decimals > 8) {
amount *= 10 ** (decimals - 8);
}
return amount;
}
function pullTokenIn(
address tokenIn,
uint256 amountIn,
PermitParams calldata permitParams
) internal returns (uint256) {
uint256 allowance = IERC20(tokenIn).allowance(msg.sender, address(this));
if (allowance < amountIn) {
execPermit(tokenIn, msg.sender, permitParams);
}
uint256 balance = IERC20(tokenIn).balanceOf(address(this));
IERC20(tokenIn).safeTransferFrom(msg.sender, address(this), amountIn);
return IERC20(tokenIn).balanceOf(address(this)) - balance;
}
function execPermit(
address token,
address owner,
PermitParams calldata permitParams
) internal {
IERC20Permit(token).permit(
owner,
address(this),
permitParams.value,
permitParams.deadline,
permitParams.v,
permitParams.r,
permitParams.s
);
}
function setPause(bool _pause) public {
if (msg.sender != guardian) {
revert Unauthorized();
}
paused = _pause;
}
function setAuctionConfig(address _auctionVerifier, uint16 _auctionChainId, bytes32 _auctionAddr) public {
if (msg.sender != guardian) {
revert Unauthorized();
}
if (_auctionChainId == 0 || _auctionAddr == bytes32(0)) {
revert InvalidAuctionConfig();
}
auctionVerifier = _auctionVerifier;
auctionChainId = _auctionChainId;
auctionAddr = _auctionAddr;
}
function setConsistencyLevel(uint8 _consistencyLevel) public {
if (msg.sender != guardian) {
revert Unauthorized();
}
consistencyLevel = _consistencyLevel;
}
function setEmitters(uint16[] memory chainIds, bytes32[] memory addresses) public {
if (msg.sender != guardian) {
revert Unauthorized();
}
require(chainIds.length == addresses.length, 'invalid array length');
for (uint i=0; i<chainIds.length; i++) {
if (emitters[chainIds[i]] != bytes32(0)) {
revert EmitterAddressExists();
}
emitters[chainIds[i]] = addresses[i];
}
}
function changeGuardian(address newGuardian) public {
if (msg.sender != guardian) {
revert Unauthorized();
}
nextGuardian = newGuardian;
}
function claimGuardian() public {
if (msg.sender != nextGuardian) {
revert Unauthorized();
}
guardian = nextGuardian;
}
function getOrders(bytes32[] memory orderHashes) public view returns (Order[] memory) {
Order[] memory result = new Order[](orderHashes.length);
for (uint i=0; i<orderHashes.length; i++) {
result[i] = orders[orderHashes[i]];
}
return result;
}
receive() external payable {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;
interface IWormhole {
struct GuardianSet {
address[] keys;
uint32 expirationTime;
}
struct Signature {
bytes32 r;
bytes32 s;
uint8 v;
uint8 guardianIndex;
}
struct VM {
uint8 version;
uint32 timestamp;
uint32 nonce;
uint16 emitterChainId;
bytes32 emitterAddress;
uint64 sequence;
uint8 consistencyLevel;
bytes payload;
uint32 guardianSetIndex;
Signature[] signatures;
bytes32 hash;
}
struct ContractUpgrade {
bytes32 module;
uint8 action;
uint16 chain;
address newContract;
}
struct GuardianSetUpgrade {
bytes32 module;
uint8 action;
uint16 chain;
GuardianSet newGuardianSet;
uint32 newGuardianSetIndex;
}
struct SetMessageFee {
bytes32 module;
uint8 action;
uint16 chain;
uint256 messageFee;
}
struct TransferFees {
bytes32 module;
uint8 action;
uint16 chain;
uint256 amount;
bytes32 recipient;
}
struct RecoverChainId {
bytes32 module;
uint8 action;
uint256 evmChainId;
uint16 newChainId;
}
event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel);
event ContractUpgraded(address indexed oldContract, address indexed newContract);
event GuardianSetAdded(uint32 indexed index);
function publishMessage(
uint32 nonce,
bytes memory payload,
uint8 consistencyLevel
) external payable returns (uint64 sequence);
function initialize() external;
function parseAndVerifyVM(bytes calldata encodedVM) external view returns (VM memory vm, bool valid, string memory reason);
function verifyVM(VM memory vm) external view returns (bool valid, string memory reason);
function verifySignatures(bytes32 hash, Signature[] memory signatures, GuardianSet memory guardianSet) external pure returns (bool valid, string memory reason);
function parseVM(bytes memory encodedVM) external pure returns (VM memory vm);
function quorum(uint numGuardians) external pure returns (uint numSignaturesRequiredForQuorum);
function getGuardianSet(uint32 index) external view returns (GuardianSet memory);
function getCurrentGuardianSetIndex() external view returns (uint32);
function getGuardianSetExpiry() external view returns (uint32);
function governanceActionIsConsumed(bytes32 hash) external view returns (bool);
function isInitialized(address impl) external view returns (bool);
function chainId() external view returns (uint16);
function isFork() external view returns (bool);
function governanceChainId() external view returns (uint16);
function governanceContract() external view returns (bytes32);
function messageFee() external view returns (uint256);
function evmChainId() external view returns (uint256);
function nextSequence(address emitter) external view returns (uint64);
function parseContractUpgrade(bytes memory encodedUpgrade) external pure returns (ContractUpgrade memory cu);
function parseGuardianSetUpgrade(bytes memory encodedUpgrade) external pure returns (GuardianSetUpgrade memory gsu);
function parseSetMessageFee(bytes memory encodedSetMessageFee) external pure returns (SetMessageFee memory smf);
function parseTransferFees(bytes memory encodedTransferFees) external pure returns (TransferFees memory tf);
function parseRecoverChainId(bytes memory encodedRecoverChainId) external pure returns (RecoverChainId memory rci);
function submitContractUpgrade(bytes memory _vm) external;
function submitSetMessageFee(bytes memory _vm) external;
function submitNewGuardianSet(bytes memory _vm) external;
function submitTransferFees(bytes memory _vm) external;
function submitRecoverChainId(bytes memory _vm) external;
}// SPDX-License-Identifier: Unlicense
/*
* @title Solidity Bytes Arrays Utils
* @author Gonçalo Sá <goncalo.sa@consensys.net>
*
* @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
* The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
*/
pragma solidity >=0.8.0 <0.9.0;
library BytesLib {
function concat(
bytes memory _preBytes,
bytes memory _postBytes
)
internal
pure
returns (bytes memory)
{
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Store the length of the first bytes array at the beginning of
// the memory for tempBytes.
let length := mload(_preBytes)
mstore(tempBytes, length)
// Maintain a memory counter for the current write location in the
// temp bytes array by adding the 32 bytes for the array length to
// the starting location.
let mc := add(tempBytes, 0x20)
// Stop copying when the memory counter reaches the length of the
// first bytes array.
let end := add(mc, length)
for {
// Initialize a copy counter to the start of the _preBytes data,
// 32 bytes into its memory.
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
// Increase both counters by 32 bytes each iteration.
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Write the _preBytes data into the tempBytes memory 32 bytes
// at a time.
mstore(mc, mload(cc))
}
// Add the length of _postBytes to the current length of tempBytes
// and store it as the new length in the first 32 bytes of the
// tempBytes memory.
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
// Move the memory counter back from a multiple of 0x20 to the
// actual end of the _preBytes data.
mc := end
// Stop copying when the memory counter reaches the new combined
// length of the arrays.
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
// Update the free-memory pointer by padding our last write location
// to 32 bytes: add 31 bytes to the end of tempBytes to move to the
// next 32 byte block, then round down to the nearest multiple of
// 32. If the sum of the length of the two arrays is zero then add
// one before rounding down to leave a blank 32 bytes (the length block with 0).
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31) // Round down to the nearest 32 bytes.
))
}
return tempBytes;
}
function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
assembly {
// Read the first 32 bytes of _preBytes storage, which is the length
// of the array. (We don't need to use the offset into the slot
// because arrays use the entire slot.)
let fslot := sload(_preBytes.slot)
// Arrays of 31 bytes or less have an even value in their slot,
// while longer arrays have an odd value. The actual length is
// the slot divided by two for odd values, and the lowest order
// byte divided by two for even values.
// If the slot is even, bitwise and the slot with 255 and divide by
// two to get the length. If the slot is odd, bitwise and the slot
// with -1 and divide by two.
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
let newlength := add(slength, mlength)
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
switch add(lt(slength, 32), lt(newlength, 32))
case 2 {
// Since the new array still fits in the slot, we just need to
// update the contents of the slot.
// uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
sstore(
_preBytes.slot,
// all the modifications to the slot are inside this
// next block
add(
// we can just add to the slot contents because the
// bytes we want to change are the LSBs
fslot,
add(
mul(
div(
// load the bytes from memory
mload(add(_postBytes, 0x20)),
// zero all bytes to the right
exp(0x100, sub(32, mlength))
),
// and now shift left the number of bytes to
// leave space for the length in the slot
exp(0x100, sub(32, newlength))
),
// increase length by the double of the memory
// bytes length
mul(mlength, 2)
)
)
)
}
case 1 {
// The stored value fits in the slot, but the combined value
// will exceed it.
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// The contents of the _postBytes array start 32 bytes into
// the structure. Our first read should obtain the `submod`
// bytes that can fit into the unused space in the last word
// of the stored array. To get this, we read 32 bytes starting
// from `submod`, so the data we read overlaps with the array
// contents by `submod` bytes. Masking the lowest-order
// `submod` bytes allows us to add that value directly to the
// stored value.
let submod := sub(32, slength)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(
sc,
add(
and(
fslot,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
),
and(mload(mc), mask)
)
)
for {
mc := add(mc, 0x20)
sc := add(sc, 1)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
default {
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
// Start copying to the last used word of the stored array.
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// Copy over the first `submod` bytes of the new data as in
// case 1 above.
let slengthmod := mod(slength, 32)
let mlengthmod := mod(mlength, 32)
let submod := sub(32, slengthmod)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(sc, add(sload(sc), and(mload(mc), mask)))
for {
sc := add(sc, 1)
mc := add(mc, 0x20)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
}
}
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
)
internal
pure
returns (bytes memory)
{
require(_length + 31 >= _length, "slice_overflow");
require(_bytes.length >= _start + _length, "slice_outOfBounds");
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
//zero out the 32 bytes slice we are about to return
//we need to do it because Solidity does not garbage collect
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
uint8 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x1), _start))
}
return tempUint;
}
function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
uint16 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x2), _start))
}
return tempUint;
}
function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
uint32 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x4), _start))
}
return tempUint;
}
function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
uint64 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x8), _start))
}
return tempUint;
}
function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
uint96 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0xc), _start))
}
return tempUint;
}
function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
uint128 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x10), _start))
}
return tempUint;
}
function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
uint256 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x20), _start))
}
return tempUint;
}
function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
bytes32 tempBytes32;
assembly {
tempBytes32 := mload(add(add(_bytes, 0x20), _start))
}
return tempBytes32;
}
function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
bool success = true;
assembly {
let length := mload(_preBytes)
// if lengths don't match the arrays are not equal
switch eq(length, mload(_postBytes))
case 1 {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
let mc := add(_preBytes, 0x20)
let end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
} eq(add(lt(mc, end), cb), 2) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// if any of these checks fails then arrays are not equal
if iszero(eq(mload(mc), mload(cc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
function equalStorage(
bytes storage _preBytes,
bytes memory _postBytes
)
internal
view
returns (bool)
{
bool success = true;
assembly {
// we know _preBytes_offset is 0
let fslot := sload(_preBytes.slot)
// Decode the length of the stored array like in concatStorage().
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
// if lengths don't match the arrays are not equal
switch eq(slength, mlength)
case 1 {
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
if iszero(iszero(slength)) {
switch lt(slength, 32)
case 1 {
// blank the last byte which is the length
fslot := mul(div(fslot, 0x100), 0x100)
if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
// unsuccess:
success := 0
}
}
default {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := keccak256(0x0, 0x20)
let mc := add(_postBytes, 0x20)
let end := add(mc, mlength)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
for {} eq(add(lt(mc, end), cb), 2) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
if iszero(eq(sload(sc), mload(mc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC1271} from "../interfaces/IERC1271.sol";
library SignatureVerifier {
/// @notice Thrown when the passed in signature is not a valid length
error InvalidSignatureLength();
/// @notice Thrown when the recovered signer is equal to the zero address
error InvalidSignature();
/// @notice Thrown when the recovered signer does not equal the claimedSigner
error InvalidSigner();
/// @notice Thrown when the recovered contract signature is incorrect
error InvalidContractSignature();
bytes32 constant UPPER_BIT_MASK = (0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
function verify(bytes calldata signature, bytes32 hash, address claimedSigner) internal view {
bytes32 r;
bytes32 s;
uint8 v;
if (claimedSigner.code.length == 0) {
if (signature.length == 65) {
(r, s) = abi.decode(signature, (bytes32, bytes32));
v = uint8(signature[64]);
} else if (signature.length == 64) {
// EIP-2098
bytes32 vs;
(r, vs) = abi.decode(signature, (bytes32, bytes32));
s = vs & UPPER_BIT_MASK;
v = uint8(uint256(vs >> 255)) + 27;
} else {
revert InvalidSignatureLength();
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) revert InvalidSignature();
if (signer != claimedSigner) revert InvalidSigner();
} else {
bytes4 magicValue = IERC1271(claimedSigner).isValidSignature(hash, signature);
if (magicValue != IERC1271.isValidSignature.selector) revert InvalidContractSignature();
}
}
}struct Order {
Status status;
uint64 amountIn;
uint16 destChainId;
}
struct OrderParams {
uint8 payloadType;
bytes32 trader;
bytes32 destAddr;
uint16 destChainId;
bytes32 referrerAddr;
bytes32 tokenOut;
uint64 minAmountOut;
uint64 gasDrop;
uint64 cancelFee;
uint64 refundFee;
uint64 deadline;
uint8 referrerBps;
uint8 auctionMode;
bytes32 random;
}
struct ExtraParams {
uint16 srcChainId;
bytes32 tokenIn;
uint8 protocolBps;
bytes32 customPayloadHash;
}
struct PermitParams {
uint256 value;
uint256 deadline;
uint8 v;
bytes32 r;
bytes32 s;
}
struct Key {
uint8 payloadType;
bytes32 trader;
uint16 srcChainId;
bytes32 tokenIn;
bytes32 destAddr;
uint16 destChainId;
bytes32 tokenOut;
uint64 minAmountOut;
uint64 gasDrop;
uint64 cancelFee;
uint64 refundFee;
uint64 deadline;
bytes32 referrerAddr;
uint8 referrerBps;
uint8 protocolBps;
uint8 auctionMode;
bytes32 random;
bytes32 customPayloadHash;
}
struct PaymentParams {
uint8 payloadType;
bytes32 orderHash;
uint64 promisedAmount;
uint64 minAmountOut;
address destAddr;
address tokenOut;
uint64 gasDrop;
bool batch;
}
enum Status {
CREATED,
FULFILLED,
SETTLED,
UNLOCKED,
CANCELED,
REFUNDED
}
enum Action {
INVALID,
FULFILL,
UNLOCK,
REFUND,
BATCH_UNLOCK,
COMPRESSED_UNLOCK,
SET_REFUND_VERIFIER,
RESCUE
}
enum AuctionMode {
INVALID,
LIMIT_ORDER,
ENGLISH
}
struct UnlockMsg {
uint8 action;
bytes32 orderHash;
uint16 srcChainId;
bytes32 tokenIn;
bytes32 referrerAddr;
uint8 referrerBps;
uint8 protocolBps;
bytes32 unlockReceiver;
bytes32 driver;
uint64 fulfillTime;
}
uint constant UNLOCK_MSG_SIZE = 172; // excluding the action field
struct RefundMsg {
uint8 action;
bytes32 orderHash;
uint16 srcChainId;
bytes32 tokenIn;
bytes32 trader;
bytes32 canceler;
uint64 cancelFee;
uint64 refundFee;
}
struct FulfillMsg {
uint8 action;
bytes32 orderHash;
bytes32 driver;
uint64 promisedAmount;
uint16 penaltyPeriod;
}
struct TransferParams {
address from;
uint256 validAfter;
uint256 validBefore;
}
struct UnlockParams {
bytes32 recipient;
bytes32 driver;
bool batch;
}
struct RescueMsg {
uint8 action;
uint16 chainId;
address targetContract;
bytes32 orderHash;
uint8 orderStatus;
address token;
uint64 amount;
}
struct RefundVerifier {
uint8 action;
uint16 chainId;
address targetContract;
address verifier;
uint16 emitterChainId;
bytes32 emitterAddr;
}error Paused(); error Unauthorized(); error InvalidAction(); error InvalidBpsFee(); error InvalidOrderStatus(); error InvalidOrderHash(); error InvalidEmitterChain(); error InvalidEmitterAddress(); error InvalidSrcChain(); error OrderNotExists(bytes32 orderHash); error SmallAmountIn(); error FeesTooHigh(); error InvalidGasDrop(); error InvalidDestChain(); error DuplicateOrder(); error InsufficientAmount(); error InvalidAmount(); error DeadlineViolation(); error InvalidWormholeFee(); error InvalidAuctionMode(); error InvalidEvmAddr(); error InvalidPayload(); error InvalidPayloadLength(); error EmitterAddressExists(); error InvalidBatchIndex(); error InvalidAuctionConfig(); error SequenceAlreadyUsed(); error InvalidTargetContract();
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 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.
*/
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].
*/
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
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC1271 {
/// @dev Should return whether the signature provided is valid for the provided data
/// @param hash Hash of the data to be signed
/// @param signature Signature byte array associated with _data
/// @return magicValue The bytes4 magic value 0x1626ba7e
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}{
"remappings": [
"ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"openzeppelin/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/=lib/openzeppelin-contracts/",
"ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/"
],
"optimizer": {
"enabled": true,
"runs": 1000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "prague",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_wormhole","type":"address"},{"internalType":"address","name":"_auctionVerifier","type":"address"},{"internalType":"uint16","name":"_auctionChainId","type":"uint16"},{"internalType":"bytes32","name":"_auctionAddr","type":"bytes32"},{"internalType":"uint8","name":"_consistencyLevel","type":"uint8"},{"internalType":"address","name":"_rescueVault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DeadlineViolation","type":"error"},{"inputs":[],"name":"EmitterAddressExists","type":"error"},{"inputs":[],"name":"InsufficientAmount","type":"error"},{"inputs":[],"name":"InvalidAction","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidAuctionConfig","type":"error"},{"inputs":[],"name":"InvalidAuctionMode","type":"error"},{"inputs":[],"name":"InvalidEmitterAddress","type":"error"},{"inputs":[],"name":"InvalidEmitterChain","type":"error"},{"inputs":[],"name":"InvalidEvmAddr","type":"error"},{"inputs":[],"name":"InvalidGasDrop","type":"error"},{"inputs":[],"name":"InvalidOrderHash","type":"error"},{"inputs":[],"name":"InvalidOrderStatus","type":"error"},{"inputs":[],"name":"InvalidSrcChain","type":"error"},{"inputs":[],"name":"InvalidTargetContract","type":"error"},{"inputs":[],"name":"InvalidWormholeFee","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OrderNotExists","type":"error"},{"inputs":[],"name":"SequenceAlreadyUsed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"sequence","type":"uint64"}],"name":"OrderCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"OrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"sequence","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"fulfilledAmount","type":"uint256"}],"name":"OrderFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"refundedAmount","type":"uint256"}],"name":"OrderRefunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"OrderUnlocked","type":"event"},{"inputs":[],"name":"auctionAddr","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auctionChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auctionVerifier","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"components":[{"internalType":"uint8","name":"payloadType","type":"uint8"},{"internalType":"bytes32","name":"trader","type":"bytes32"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"minAmountOut","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"auctionMode","type":"uint8"},{"internalType":"bytes32","name":"random","type":"bytes32"}],"internalType":"struct OrderParams","name":"params","type":"tuple"},{"components":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"bytes32","name":"tokenIn","type":"bytes32"},{"internalType":"uint8","name":"protocolBps","type":"uint8"},{"internalType":"bytes32","name":"customPayloadHash","type":"bytes32"}],"internalType":"struct ExtraParams","name":"extraParams","type":"tuple"},{"internalType":"bytes32","name":"canceler","type":"bytes32"}],"name":"cancelOrder","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newGuardian","type":"address"}],"name":"changeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"consistencyLevel","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"emitters","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fulfillAmount","type":"uint256"},{"internalType":"bytes","name":"encodedVm","type":"bytes"},{"components":[{"internalType":"uint8","name":"payloadType","type":"uint8"},{"internalType":"bytes32","name":"trader","type":"bytes32"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"minAmountOut","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"auctionMode","type":"uint8"},{"internalType":"bytes32","name":"random","type":"bytes32"}],"internalType":"struct OrderParams","name":"params","type":"tuple"},{"components":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"bytes32","name":"tokenIn","type":"bytes32"},{"internalType":"uint8","name":"protocolBps","type":"uint8"},{"internalType":"bytes32","name":"customPayloadHash","type":"bytes32"}],"internalType":"struct ExtraParams","name":"extraParams","type":"tuple"},{"components":[{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"driver","type":"bytes32"},{"internalType":"bool","name":"batch","type":"bool"}],"internalType":"struct UnlockParams","name":"unlockParams","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct PermitParams","name":"permit","type":"tuple"}],"name":"fulfillOrder","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fulfillAmount","type":"uint256"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"components":[{"internalType":"uint8","name":"payloadType","type":"uint8"},{"internalType":"bytes32","name":"trader","type":"bytes32"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"minAmountOut","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"auctionMode","type":"uint8"},{"internalType":"bytes32","name":"random","type":"bytes32"}],"internalType":"struct OrderParams","name":"params","type":"tuple"},{"components":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"bytes32","name":"tokenIn","type":"bytes32"},{"internalType":"uint8","name":"protocolBps","type":"uint8"},{"internalType":"bytes32","name":"customPayloadHash","type":"bytes32"}],"internalType":"struct ExtraParams","name":"extraParams","type":"tuple"},{"components":[{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"driver","type":"bytes32"},{"internalType":"bool","name":"batch","type":"bool"}],"internalType":"struct UnlockParams","name":"unlockParams","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct PermitParams","name":"permit","type":"tuple"}],"name":"fulfillSimple","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"orderHashes","type":"bytes32[]"}],"name":"getOrders","outputs":[{"components":[{"internalType":"enum Status","name":"status","type":"uint8"},{"internalType":"uint64","name":"amountIn","type":"uint64"},{"internalType":"uint16","name":"destChainId","type":"uint16"}],"internalType":"struct Order[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"orders","outputs":[{"internalType":"enum Status","name":"status","type":"uint8"},{"internalType":"uint64","name":"amountIn","type":"uint64"},{"internalType":"uint16","name":"destChainId","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"parseFulfillPayload","outputs":[{"components":[{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"bytes32","name":"driver","type":"bytes32"},{"internalType":"uint64","name":"promisedAmount","type":"uint64"},{"internalType":"uint16","name":"penaltyPeriod","type":"uint16"}],"internalType":"struct FulfillMsg","name":"fulfillMsg","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"parseRescuePayload","outputs":[{"components":[{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"uint8","name":"orderStatus","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint64","name":"amount","type":"uint64"}],"internalType":"struct RescueMsg","name":"rescueMsg","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"pendingAmounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"orderHashes","type":"bytes32[]"}],"name":"postBatch","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedVm","type":"bytes"}],"name":"rescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rescueVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_auctionVerifier","type":"address"},{"internalType":"uint16","name":"_auctionChainId","type":"uint16"},{"internalType":"bytes32","name":"_auctionAddr","type":"bytes32"}],"name":"setAuctionConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_consistencyLevel","type":"uint8"}],"name":"setConsistencyLevel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"chainIds","type":"uint16[]"},{"internalType":"bytes32[]","name":"addresses","type":"bytes32[]"}],"name":"setEmitters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_pause","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"payloadType","type":"uint8"},{"internalType":"bytes32","name":"trader","type":"bytes32"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"minAmountOut","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"auctionMode","type":"uint8"},{"internalType":"bytes32","name":"random","type":"bytes32"}],"internalType":"struct OrderParams","name":"params","type":"tuple"},{"components":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"bytes32","name":"tokenIn","type":"bytes32"},{"internalType":"uint8","name":"protocolBps","type":"uint8"},{"internalType":"bytes32","name":"customPayloadHash","type":"bytes32"}],"internalType":"struct ExtraParams","name":"extraParams","type":"tuple"}],"name":"settleWithPayload","outputs":[{"internalType":"uint256","name":"netAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"unlockMsgs","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"usedSequences","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wormhole","outputs":[{"internalType":"contract IWormhole","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c060405234801561000f575f5ffd5b506040516148a03803806148a083398101604081905261002e916100b9565b60015f819055600380546001600160a01b03988916608052825461ffff909716600160a01b026001600160b01b03199097169789169790971795909517905560029290925560ff1660ff196101003302166001600160a81b0319909416939093179290921790551660a052610132565b80516001600160a01b03811681146100b4575f5ffd5b919050565b5f5f5f5f5f5f60c087890312156100ce575f5ffd5b6100d78761009e565b95506100e56020880161009e565b9450604087015161ffff811681146100fb575f5ffd5b60608801516080890151919550935060ff81168114610118575f5ffd5b915061012660a0880161009e565b90509295509295509295565b60805160a0516146e46101bc5f395f818161054001528181611c3f0152611c7f01525f81816103c3015281816107c501528181610fe10152818161121201528181611443015281816116d4015281816118cd01528181611a8701528181611e19015281816128350152818161296801528181612a6501528181612b860152612bb501526146e45ff3fe6080604052600436106101bd575f3560e01c80638a261c67116100f2578063cc8388d011610092578063f556882311610062578063f55688231461061d578063f620399014610630578063f85ae6361461065c578063fa6a6d361461067b575f5ffd5b8063cc8388d01461052f578063dae2fc1214610562578063e8dfd50814610581578063f1d3ac4f146105ac575f5ffd5b80639e70a740116100cd5780639e70a740146104a7578063b365b191146104d2578063b3f34dc7146104f1578063bedb86fb14610510575f5ffd5b80638a261c67146103e5578063919a1704146104195780639c3f1e9014610447575f5ffd5b80634a85d7881161015d578063814aa66911610138578063814aa6691461036157806381b152c014610380578063843bb5591461039f57806384acd1bb146103b2575f5ffd5b80634a85d788146102e6578063538ee295146103125780635c975abb14610331575f5ffd5b80633d474866116101985780633d4748661461024b578063452a932014610277578063459656ee146102b35780634818e84d146102c7575f5ffd5b806319535a54146101c85780632dd845c7146101f15780632fcb4f041461022a575f5ffd5b366101c457005b5f5ffd5b6101db6101d63660046139f9565b610690565b6040516101e89190613ab2565b60405180910390f35b3480156101fc575f5ffd5b5061021c61020b366004613ac4565b60076020525f908152604090205481565b6040519081526020016101e8565b348015610235575f5ffd5b50610249610244366004613af1565b610bea565b005b348015610256575f5ffd5b5061026a610265366004613b92565b610c48565b6040516101e89190613bec565b348015610282575f5ffd5b5060035461029b9061010090046001600160a01b031681565b6040516001600160a01b0390911681526020016101e8565b3480156102be575f5ffd5b50610249610d81565b3480156102d2575f5ffd5b5060045461029b906001600160a01b031681565b6102f96102f4366004613b92565b610ded565b60405167ffffffffffffffff90911681526020016101e8565b34801561031d575f5ffd5b5061024961032c366004613c5f565b611067565b34801561033c575f5ffd5b5060045461035190600160a01b900460ff1681565b60405190151581526020016101e8565b34801561036c575f5ffd5b5061024961037b366004613c7a565b6110ac565b34801561038b575f5ffd5b506101db61039a366004613ac4565b611170565b6102f96103ad366004613cb6565b611207565b3480156103bd575f5ffd5b5061029b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103f0575f5ffd5b5060015461040690600160a01b900461ffff1681565b60405161ffff90911681526020016101e8565b348015610424575f5ffd5b50610351610433366004613cfc565b60096020525f908152604090205460ff1681565b348015610452575f5ffd5b50610498610461366004613ac4565b60056020525f908152604090205460ff811690610100810467ffffffffffffffff16906901000000000000000000900461ffff1683565b6040516101e893929190613d17565b3480156104b2575f5ffd5b5061021c6104c1366004613d47565b60086020525f908152604090205481565b3480156104dd575f5ffd5b506102496104ec366004613d62565b611513565b3480156104fc575f5ffd5b5061021c61050b366004613e27565b611665565b34801561051b575f5ffd5b5061024961052a366004613e5c565b611831565b34801561053a575f5ffd5b5061029b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561056d575f5ffd5b5061024961057c366004613e77565b611899565b34801561058c575f5ffd5b5060035461059a9060ff1681565b60405160ff90911681526020016101e8565b3480156105b7575f5ffd5b506105cb6105c6366004613e77565b611cad565b6040516101e891905f60a08201905060ff8351168252602083015160208301526040830151604083015267ffffffffffffffff606084015116606083015261ffff608084015116608083015292915050565b61024961062b366004613ea9565b611da0565b34801561063b575f5ffd5b5061064f61064a366004613e77565b61215e565b6040516101e89190613ed7565b348015610667575f5ffd5b5060015461029b906001600160a01b031681565b348015610686575f5ffd5b5061021c60025481565b606061069a61225c565b6001546040517fc0fd8bde0000000000000000000000000000000000000000000000000000000081525f91829182916001600160a01b03169063c0fd8bde906106e7908c90600401613ab2565b5f60405180830381865afa158015610701573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610728919081019061407f565b9250925092508181906107575760405162461bcd60e51b815260040161074e9190613ab2565b60405180910390fd5b50600154606084015161ffff908116600160a01b909204161461078d576040516327e8d62960e11b815260040160405180910390fd5b6002548360800151146107b35760405163d08bf9e160e01b815260040160405180910390fd5b5f6107c18460e00151611cad565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa15801561081f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061084391906141e3565b61ffff1660608a0152602081015161086361085e8b8b6122b3565b612453565b80519060200120146108885760405163561a411d60e11b815260040160405180910390fd5b5f6108968a60a0015161254c565b90506001600160a01b038116156108b5576108b2818d896125a0565b9b505b326001600160a01b03166108cc836040015161254c565b6001600160a01b0316141580156109055750816080015161ffff168a61014001516108f79190614212565b67ffffffffffffffff164211155b15610922576040516282b42960e81b815260040160405180910390fd5b89610140015167ffffffffffffffff164210610951576040516354a36da760e11b815260040160405180910390fd5b5f6020808401515f908152600591829052604090205460ff169081111561097a5761097a613bc4565b1461099857604051632916ae3360e01b815260040160405180910390fd5b895160ff166002036109c7576020828101515f908152600590915260409020805460ff191660011790556109e6565b6020828101515f908152600590915260409020805460ff191660021790555b610a818c6040518061010001604052808d5f015160ff16815260200185602001518152602001856060015167ffffffffffffffff1681526020018d60c0015167ffffffffffffffff168152602001610a418e6040015161254c565b6001600160a01b03168152602001846001600160a01b031681526020018d60e0015167ffffffffffffffff1681526020018b60400151151581525061272f565b5f610b6e610b6484602001518d8d8d60408051610140810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081019190915260408051610140810190915280600260ff168152602001868152602001845f015161ffff168152602001846020015181526020018560800151815260200185610160015160ff168152602001846040015160ff168152602001835f01518152602001836020015181526020014267ffffffffffffffff168152509050949350505050565b8a60400151612b4e565b90507f6ec9b1b5a9f54d929394f18dac4ba1b1cc79823f2266c2d09cab8a3b4700b40b8360200151828f604051610bc29392919092835267ffffffffffffffff919091166020830152604082015260600190565b60405180910390a18560e001519650505050505050610be060015f55565b9695505050505050565b60035461010090046001600160a01b03163314610c19576040516282b42960e81b815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60605f825167ffffffffffffffff811115610c6557610c656136a2565b604051908082528060200260200182016040528015610cae57816020015b604080516060810182525f80825260208083018290529282015282525f19909201910181610c835790505b5090505f5b8351811015610d7a5760055f858381518110610cd157610cd1614232565b602002602001015181526020019081526020015f206040518060600160405290815f82015f9054906101000a900460ff166005811115610d1357610d13613bc4565b6005811115610d2457610d24613bc4565b81529054610100810467ffffffffffffffff1660208301526901000000000000000000900461ffff166040909101528251839083908110610d6757610d67614232565b6020908102919091010152600101610cb3565b5092915050565b6004546001600160a01b03163314610dab576040516282b42960e81b815260040160405180910390fd5b600454600380546001600160a01b03909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b5f6060815b8351811015610f69575f60065f868481518110610e1157610e11614232565b602002602001015181526020019081526020015f208054610e3190614246565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5d90614246565b8015610ea85780601f10610e7f57610100808354040283529160200191610ea8565b820191905f5260205f20905b815481529060010190602001808311610e8b57829003601f168201915b5050505050905060ac815114610f0757848281518110610eca57610eca614232565b60200260200101516040517f956fc85700000000000000000000000000000000000000000000000000000000815260040161074e91815260200190565b8281604051602001610f1a92919061428f565b604051602081830303815290604052925060065f868481518110610f4057610f40614232565b602002602001015181526020019081526020015f205f610f609190613654565b50600101610df2565b505f600584518380519060200120604051602001610fb69392919060f89390931b6001600160f81b031916835260f09190911b6001600160f01b0319166001830152600382015260230190565b60408051601f19818403018152908290526003546358cd21bf60e11b83529092506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163b19a437e91349161101e915f91879160ff16906004016142a3565b60206040518083038185885af115801561103a573d5f5f3e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061105f91906142d4565b949350505050565b60035461010090046001600160a01b03163314611096576040516282b42960e81b815260040160405180910390fd5b6003805460ff191660ff92909216919091179055565b60035461010090046001600160a01b031633146110db576040516282b42960e81b815260040160405180910390fd5b61ffff821615806110ea575080155b15611121576040517f453b7de000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805461ffff909316600160a01b027fffffffffffffffffffff000000000000000000000000000000000000000000009093166001600160a01b039094169390931791909117909155600255565b60066020525f90815260409020805461118890614246565b80601f01602080910402602001604051908101604052809291908181526020018280546111b490614246565b80156111ff5780601f106111d6576101008083540402835291602001916111ff565b820191905f5260205f20905b8154815290600101906020018083116111e257829003601f168201915b505050505081565b5f61121061225c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061129091906141e3565b61ffff1660608501525f6112a761085e86866122b3565b8051906020012090508581146112d05760405163561a411d60e11b815260040160405180910390fd5b5f868152600560208190526040808320815160608101909252805491929091839160ff9091169081111561130657611306613bc4565b600581111561131757611317613bc4565b81529054610100810467ffffffffffffffff9081166020840152690100000000000000000090910461ffff16604090920191909152610140880151919250164211611375576040516354a36da760e11b815260040160405180910390fd5b5f8151600581111561138957611389613bc4565b146113a757604051632916ae3360e01b815260040160405180910390fd5b5f878152600560209081526040808320805460ff1916600417905580516101008082018352600382528184018c9052895161ffff169282019290925288830151606082015291890151608083015260a0820187905288015167ffffffffffffffff90811660c08301526101208901511660e08201529061142682612ce1565b6003546040516358cd21bf60e11b81529192506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163b19a437e913491611480915f91879160ff16906004016142a3565b60206040518083038185885af115801561149c573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906114c191906142d4565b604080518b815267ffffffffffffffff831660208201529196507f45a58de39e77dfc9cd1d63970a706575668048121d822749d2298eb75125123e910160405180910390a15050505061105f60015f55565b60035461010090046001600160a01b03163314611542576040516282b42960e81b815260040160405180910390fd5b80518251146115935760405162461bcd60e51b815260206004820152601460248201527f696e76616c6964206172726179206c656e677468000000000000000000000000604482015260640161074e565b5f5b8251811015611660575f5f1b60085f8584815181106115b6576115b6614232565b602002602001015161ffff1661ffff1681526020019081526020015f20541461160b576040517f9a23a9de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81818151811061161d5761161d614232565b602002602001015160085f85848151811061163a5761163a614232565b60209081029190910181015161ffff1682528101919091526040015f2055600101611595565b505050565b5f61166e61225c565b825f015160ff1660021461169557604051634a7f394f60e01b815260040160405180910390fd5b336001600160a01b03166116ac846040015161254c565b6001600160a01b0316146116d2576040516282b42960e81b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa15801561172e573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061175291906141e3565b61ffff1660608401525f61176961085e85856122b3565b8051602090910120905060015f8281526005602081905260409091205460ff169081111561179957611799613bc4565b146117b757604051632916ae3360e01b815260040160405180910390fd5b5f818152600560209081526040808320805460ff19166002179055600790915281205460a08601519093506117eb9061254c565b90506001600160a01b03811661180c5761180733846001612d98565b611820565b6118206001600160a01b0382163385612e43565b505061182b60015f55565b92915050565b60035461010090046001600160a01b03163314611860576040516282b42960e81b815260040160405180910390fd5b60048054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b60035461010090046001600160a01b031633146118c8576040516282b42960e81b815260040160405180910390fd5b5f5f5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016119179190613ab2565b5f60405180830381865afa158015611931573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611958919081019061407f565b92509250925081819061197e5760405162461bcd60e51b815260040161074e9190613ab2565b5060a083015167ffffffffffffffff165f9081526009602052604090205460ff16156119d6576040517f7123717600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a083015167ffffffffffffffff165f908152600960205260409020805460ff19166001908117909155606084015161ffff1614611a27576040516327e8d62960e11b815260040160405180910390fd5b60015f5260086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f54608084015114611a755760405163d08bf9e160e01b815260040160405180910390fd5b5f611a838460e0015161215e565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ae1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b0591906141e3565b61ffff16816020015161ffff1614611b49576040517f77d876fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408101516001600160a01b03163014611b8f576040517f5569851a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606081015115611bec57806080015160ff166005811115611bb257611bb2613bc4565b60608201515f9081526005602081905260409091208054909160ff19909116906001908490811115611be657611be6613bc4565b02179055505b60c081015167ffffffffffffffff1615611ca6575f611c258260c0015167ffffffffffffffff16611c208460a00151612eec565b612fb8565b60a08301519091506001600160a01b0316611c6b57611c667f0000000000000000000000000000000000000000000000000000000000000000826001612d98565b611ca4565b60a0820151611ca4906001600160a01b03167f000000000000000000000000000000000000000000000000000000000000000083612e43565b505b5050505050565b6040805160a0810182525f80825260208201819052918101829052606081018290526080810182905290611ce18382612fef565b60ff168252611cf16001826142ef565b825190915060ff16600114611d1957604051634a7f394f60e01b815260040160405180910390fd5b611d238382613054565b602080840191909152611d3690826142ef565b9050611d4283826130b9565b67ffffffffffffffff166060830152611d5c6008826142ef565b9050611d688382613054565b6040830152611d786020826142ef565b9050611d84838261311e565b61ffff166080830152611d986002826142ef565b905050919050565b611da861225c565b61018084015160ff16600114611dea576040517ffd426f5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611df88560a0015161254c565b90506001600160a01b03811615611e1757611e148188846125a0565b96505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e73573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e9791906141e3565b61ffff16606086015285611eae61085e87876122b3565b8051906020012014611ed35760405163561a411d60e11b815260040160405180910390fd5b84610140015167ffffffffffffffff16421115611f03576040516354a36da760e11b815260040160405180910390fd5b5f86815260056020819052604082205460ff1690811115611f2657611f26613bc4565b14611f4457604051632916ae3360e01b815260040160405180910390fd5b845160ff16600203611f6d575f868152600560205260409020805460ff19166001179055611f86565b5f868152600560205260409020805460ff191660021790555b61201d87604051806101000160405280885f015160ff1681526020018981526020018860c0015167ffffffffffffffff1681526020018860c0015167ffffffffffffffff168152602001611fdd896040015161254c565b6001600160a01b03168152602001846001600160a01b031681526020018860e0015167ffffffffffffffff1681526020018660400151151581525061272f565b5f6121066120fc8888888860408051610140810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081019190915260408051610140810190915280600260ff168152602001868152602001845f015161ffff168152602001846020015181526020018560800151815260200185610160015160ff168152602001846040015160ff168152602001835f01518152602001836020015181526020014267ffffffffffffffff168152509050949350505050565b8560400151612b4e565b6040805189815267ffffffffffffffff831660208201529081018a90529091507f6ec9b1b5a9f54d929394f18dac4ba1b1cc79823f2266c2d09cab8a3b4700b40b9060600160405180910390a15050611ca460015f55565b6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c08101829052906121a08382612fef565b60ff1682526121b06001826142ef565b825190915060ff166007146121d857604051634a7f394f60e01b815260040160405180910390fd5b6121e28382613054565b60608301526121f26020826142ef565b90506121fe8382612fef565b60ff1660808301526122116001826142ef565b905061221d8382613183565b6001600160a01b031660a08301526122366020826142ef565b905061224283826130b9565b67ffffffffffffffff1660c0830152611d986008826142ef565b60025f54036122ad5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161074e565b60025f55565b60408051610240810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101829052610220810191909152604051806102400160405280845f015160ff16815260200184602001518152602001835f015161ffff1681526020018360200151815260200184604001518152602001846060015161ffff1681526020018460a0015181526020018460c0015167ffffffffffffffff1681526020018460e0015167ffffffffffffffff16815260200184610100015167ffffffffffffffff16815260200184610120015167ffffffffffffffff16815260200184610140015167ffffffffffffffff1681526020018460800151815260200184610160015160ff168152602001836040015160ff16815260200184610180015160ff168152602001846101a0015181526020018360600151815250905092915050565b6060815f015182602001518360400151846060015185608001518660a001518760c001518860e001518961010001518a61012001518b61014001518c61016001516040516020016124af9c9b9a99989796959493929190614302565b60408051601f19818403018152908290526101808401516101a08501516101c08601516101e087015161020088015161022089015195975061182b96612535969060200195865260f894851b6001600160f81b0319908116602088015293851b841660218701529190931b90911660228401526023830191909152604382015260630190565b60408051601f1981840301815291905282906131df565b5f73ffffffffffffffffffffffffffffffffffffffff1982161561259c576040517ff652ddbc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201525f9081906001600160a01b0386169063dd62ed3e90604401602060405180830381865afa158015612605573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061262991906143e0565b90508381101561263e5761263e85338561325c565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015612682573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126a691906143e0565b90506126bd6001600160a01b038716333088613327565b6040516370a0823160e01b815230600482015281906001600160a01b038816906370a0823190602401602060405180830381865afa158015612701573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061272591906143e0565b610be091906143f7565b60a08101515f906001600160a01b031661274b5750601261275b565b6127588260a00151612eec565b90505b612773826040015167ffffffffffffffff1682612fb8565b8310156127ac576040517f5945ea5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816060015167ffffffffffffffff166127c58483613378565b10156127fd576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a08201516001600160a01b0316612912578160e0015180156128205750823414155b806128c157508160e001511580156128c157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa15801561288f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128b391906143e0565b6128bd90846142ef565b3414155b156128df576040516317dfbee160e01b815260040160405180910390fd5b815160ff1660020361290257506020908101515f90815260079091526040902055565b6116608260800151846001612d98565b60c082015167ffffffffffffffff1615612a40575f6129408360c0015167ffffffffffffffff166012612fb8565b90508260e0015180156129535750803414155b806129f457508260e001511580156129f457507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129e691906143e0565b6129f090826142ef565b3414155b15612a2b576040517fdca3db9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3a8360800151825f612d98565b50612b05565b8160e001518015612a5057503415155b80612ae757508160e00151158015612ae757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa158015612abf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ae391906143e0565b3414155b15612b05576040516317dfbee160e01b815260040160405180910390fd5b815160ff16600203612b2857506020908101515f90815260079091526040902055565b6116608260800151848460a001516001600160a01b0316612e439092919063ffffffff16565b5f5f612b59846133a5565b90508215612b84576020808501515f908152600690915260409020612b7e828261444e565b50610d7a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b19a437e7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c0f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c3391906143e0565b5f600285604051602001612c48929190614509565b60408051601f19818403018152908290526003547fffffffff0000000000000000000000000000000000000000000000000000000060e087901b168352612c98939260ff909116906004016142a3565b60206040518083038185885af1158015612cb4573d5f5f3e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612cd991906142d4565b91505061182b565b6060815f015182602001518360400151846060015185608001518660a001518760c001518860e00151604051602001612d8298979695949392919060f89890981b6001600160f81b0319168852600188019690965260f09490941b6001600160f01b031916602187015260238601929092526043850152606384015260c090811b6001600160c01b0319908116608385015291901b16608b82015260930190565b6040516020818303038152906040529050919050565b5f836001600160a01b0316836040515f6040518083038185875af1925050503d805f8114612de1576040519150601f19603f3d011682016040523d82523d5f602084013e612de6565b606091505b505090508115612e3d5780612e3d5760405162461bcd60e51b815260206004820152600e60248201527f7061796d656e74206661696c6564000000000000000000000000000000000000604482015260640161074e565b50505050565b6040516001600160a01b0383166024820152604481018290526116609084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613451565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f9182916001600160a01b03851691612f5c9161452d565b5f60405180830381855afa9150503d805f8114612f94576040519150601f19603f3d011682016040523d82523d5f602084013e612f99565b606091505b5091505080806020019051810190612fb19190614538565b9392505050565b5f60088260ff161115612fe857612fd0600883614553565b612fdb90600a61464f565b612fe5908461465d565b92505b5090919050565b5f612ffb8260016142ef565b8351101561304b5760405162461bcd60e51b815260206004820152601360248201527f746f55696e74385f6f75744f66426f756e647300000000000000000000000000604482015260640161074e565b50016001015190565b5f6130608260206142ef565b835110156130b05760405162461bcd60e51b815260206004820152601560248201527f746f427974657333325f6f75744f66426f756e64730000000000000000000000604482015260640161074e565b50016020015190565b5f6130c58260086142ef565b835110156131155760405162461bcd60e51b815260206004820152601460248201527f746f55696e7436345f6f75744f66426f756e6473000000000000000000000000604482015260640161074e565b50016008015190565b5f61312a8260026142ef565b8351101561317a5760405162461bcd60e51b815260206004820152601460248201527f746f55696e7431365f6f75744f66426f756e6473000000000000000000000000604482015260640161074e565b50016002015190565b5f61318f8260206142ef565b835110156130b05760405162461bcd60e51b815260206004820152601560248201527f746f55696e743235365f6f75744f66426f756e64730000000000000000000000604482015260640161074e565b6060806040519050835180825260208201818101602087015b818310156132105780518352602092830192016131f8565b50855184518101855292509050808201602086015b8183101561323d578051835260209283019201613225565b508651929092011591909101601f01601f191660405250905092915050565b6001600160a01b03831663d505accf8330843560208601356132846060880160408901613c5f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b1681526001600160a01b0395861660048201529490931660248501526044840191909152606483015260ff166084820152606084013560a4820152608084013560c482015260e4015f604051808303815f87803b15801561330c575f5ffd5b505af115801561331e573d5f5f3e3d5ffd5b50505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052612e3d9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612e88565b5f60088260ff161115612fe857613390600883614553565b61339b90600a61464f565b612fe59084614674565b606081602001518260400151836060015184608001518560a001518660c001518760e00151886101000151896101200151604051602001612d829998979695949392919098895260f09790971b6001600160f01b03191660208901526022880195909552604287019390935260f891821b6001600160f81b03199081166062880152911b1660638501526064840152608483015260c01b6001600160c01b03191660a482015260ac0190565b5f6134a5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166135379092919063ffffffff16565b905080515f14806134c55750808060200190518101906134c59190614693565b6116605760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161074e565b606061105f84845f85855f5f866001600160a01b0316858760405161355c919061452d565b5f6040518083038185875af1925050503d805f8114613596576040519150601f19603f3d011682016040523d82523d5f602084013e61359b565b606091505b50915091506135ac878383876135b7565b979650505050505050565b606083156136255782515f0361361e576001600160a01b0385163b61361e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161074e565b508161105f565b61105f838381511561363a5781518083602001fd5b8060405162461bcd60e51b815260040161074e9190613ab2565b50805461366090614246565b5f825580601f1061366f575050565b601f0160209004905f5260205f209081019061368b919061368e565b50565b5b8082111561259c575f815560010161368f565b634e487b7160e01b5f52604160045260245ffd5b6040516101c0810167ffffffffffffffff811182821017156136da576136da6136a2565b60405290565b6040516080810167ffffffffffffffff811182821017156136da576136da6136a2565b604051610160810167ffffffffffffffff811182821017156136da576136da6136a2565b604051601f8201601f1916810167ffffffffffffffff81118282101715613750576137506136a2565b604052919050565b5f67ffffffffffffffff821115613771576137716136a2565b50601f01601f191660200190565b5f82601f83011261378e575f5ffd5b81356137a161379c82613758565b613727565b8181528460208386010111156137b5575f5ffd5b816020850160208301375f918101602001919091529392505050565b60ff8116811461368b575f5ffd5b80356137ea816137d1565b919050565b61ffff8116811461368b575f5ffd5b80356137ea816137ef565b67ffffffffffffffff8116811461368b575f5ffd5b80356137ea81613809565b5f6101c0828403121561383a575f5ffd5b6138426136b6565b905061384d826137df565b8152602082810135908201526040808301359082015261386f606083016137fe565b60608201526080828101359082015260a0808301359082015261389460c0830161381e565b60c08201526138a560e0830161381e565b60e08201526138b7610100830161381e565b6101008201526138ca610120830161381e565b6101208201526138dd610140830161381e565b6101408201526138f061016083016137df565b61016082015261390361018083016137df565b6101808201526101a09182013591810191909152919050565b5f6080828403121561392c575f5ffd5b6139346136e0565b90508135613941816137ef565b815260208281013590820152604082013561395b816137d1565b604082015260609182013591810191909152919050565b801515811461368b575f5ffd5b5f6060828403121561398f575f5ffd5b6040516060810167ffffffffffffffff811182821017156139b2576139b26136a2565b6040908152833582526020808501359083015290915081908301356139d681613972565b6040919091015292915050565b5f60a082840312156139f3575f5ffd5b50919050565b5f5f5f5f5f5f6103808789031215613a0f575f5ffd5b86359550602087013567ffffffffffffffff811115613a2c575f5ffd5b613a3889828a0161377f565b955050613a488860408901613829565b9350613a5888610200890161391c565b9250613a6888610280890161397f565b9150613a78886102e089016139e3565b90509295509295509295565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f612fb16020830184613a84565b5f60208284031215613ad4575f5ffd5b5035919050565b80356001600160a01b03811681146137ea575f5ffd5b5f60208284031215613b01575f5ffd5b612fb182613adb565b5f67ffffffffffffffff821115613b2357613b236136a2565b5060051b60200190565b5f82601f830112613b3c575f5ffd5b8135613b4a61379c82613b0a565b8082825260208201915060208360051b860101925085831115613b6b575f5ffd5b602085015b83811015613b88578035835260209283019201613b70565b5095945050505050565b5f60208284031215613ba2575f5ffd5b813567ffffffffffffffff811115613bb8575f5ffd5b61105f84828501613b2d565b634e487b7160e01b5f52602160045260245ffd5b60068110613be857613be8613bc4565b9052565b602080825282518282018190525f918401906040840190835b81811015613c54578351613c1a848251613bd8565b67ffffffffffffffff602082015116602085015261ffff604082015116604085015250606083019250602084019350600181019050613c05565b509095945050505050565b5f60208284031215613c6f575f5ffd5b8135612fb1816137d1565b5f5f5f60608486031215613c8c575f5ffd5b613c9584613adb565b92506020840135613ca5816137ef565b929592945050506040919091013590565b5f5f5f5f6102808587031215613cca575f5ffd5b84359350613cdb8660208701613829565b9250613ceb866101e0870161391c565b939692955092936102600135925050565b5f60208284031215613d0c575f5ffd5b8135612fb181613809565b60608101613d258286613bd8565b67ffffffffffffffff8416602083015261ffff83166040830152949350505050565b5f60208284031215613d57575f5ffd5b8135612fb1816137ef565b5f5f60408385031215613d73575f5ffd5b823567ffffffffffffffff811115613d89575f5ffd5b8301601f81018513613d99575f5ffd5b8035613da761379c82613b0a565b8082825260208201915060208360051b850101925087831115613dc8575f5ffd5b6020840193505b82841015613df3578335613de2816137ef565b825260209384019390910190613dcf565b9450505050602083013567ffffffffffffffff811115613e11575f5ffd5b613e1d85828601613b2d565b9150509250929050565b5f5f6102408385031215613e39575f5ffd5b613e438484613829565b9150613e53846101c0850161391c565b90509250929050565b5f60208284031215613e6c575f5ffd5b8135612fb181613972565b5f60208284031215613e87575f5ffd5b813567ffffffffffffffff811115613e9d575f5ffd5b61105f8482850161377f565b5f5f5f5f5f5f6103808789031215613ebf575f5ffd5b8635955060208701359450613a488860408901613829565b5f60e08201905060ff835116825261ffff60208401511660208301526001600160a01b0360408401511660408301526060830151606083015260ff60808401511660808301526001600160a01b0360a08401511660a083015260c0830151610d7a60c084018267ffffffffffffffff169052565b80516137ea816137d1565b805163ffffffff811681146137ea575f5ffd5b80516137ea816137ef565b80516137ea81613809565b5f82601f830112613f8e575f5ffd5b8151602083015f613fa161379c84613758565b9050828152858383011115613fb4575f5ffd5b8282602083015e5f92810160200192909252509392505050565b5f82601f830112613fdd575f5ffd5b8151613feb61379c82613b0a565b8082825260208201915060208360071b86010192508583111561400c575f5ffd5b602085015b83811015613b885760808188031215614028575f5ffd5b6140306136e0565b8151815260208083015190820152604082015161404c816137d1565b6040820152606082015161405f816137d1565b60608201528352602090920191608001614011565b80516137ea81613972565b5f5f5f60608486031215614091575f5ffd5b835167ffffffffffffffff8111156140a7575f5ffd5b840161016081870312156140b9575f5ffd5b6140c1613703565b6140ca82613f4b565b81526140d860208301613f56565b60208201526140e960408301613f56565b60408201526140fa60608301613f69565b60608201526080828101519082015261411560a08301613f74565b60a082015261412660c08301613f4b565b60c082015260e082015167ffffffffffffffff811115614144575f5ffd5b61415088828501613f7f565b60e0830152506141636101008301613f56565b61010082015261012082015167ffffffffffffffff811115614183575f5ffd5b61418f88828501613fce565b61012083015250610140918201519181019190915292506141b260208501614074565b9150604084015167ffffffffffffffff8111156141cd575f5ffd5b6141d986828701613f7f565b9150509250925092565b5f602082840312156141f3575f5ffd5b8151612fb1816137ef565b634e487b7160e01b5f52601160045260245ffd5b67ffffffffffffffff828116828216039081111561182b5761182b6141fe565b634e487b7160e01b5f52603260045260245ffd5b600181811c9082168061425a57607f821691505b6020821081036139f357634e487b7160e01b5f52602260045260245ffd5b5f81518060208401855e5f93019283525090919050565b5f61105f61429d8386614278565b84614278565b63ffffffff84168152606060208201525f6142c16060830185613a84565b905060ff83166040830152949350505050565b5f602082840312156142e4575f5ffd5b8151612fb181613809565b8082018082111561182b5761182b6141fe565b6001600160f81b03198d60f81b1681528b60018201526001600160f01b03198b60f01b1660218201528960238201528860438201526001600160f01b03198860f01b166063820152866065820152614369608582018760c01b6001600160c01b0319169052565b614382608d82018660c01b6001600160c01b0319169052565b61439b609582018560c01b6001600160c01b0319169052565b6143b4609d82018460c01b6001600160c01b0319169052565b6143cd60a582018360c01b6001600160c01b0319169052565b60ad019c9b505050505050505050505050565b5f602082840312156143f0575f5ffd5b5051919050565b8181038181111561182b5761182b6141fe565b601f82111561166057805f5260205f20601f840160051c8101602085101561442f5750805b601f840160051c820191505b81811015611ca6575f815560010161443b565b815167ffffffffffffffff811115614468576144686136a2565b61447c816144768454614246565b8461440a565b6020601f8211600181146144ae575f83156144975750848201515b5f19600385901b1c1916600184901b178455611ca6565b5f84815260208120601f198516915b828110156144dd57878501518255602094850194600190920191016144bd565b50848210156144fa57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f6008841061451a5761451a613bc4565b8360f81b825261105f6001830184614278565b5f612fb18284614278565b5f60208284031215614548575f5ffd5b8151612fb1816137d1565b60ff828116828216039081111561182b5761182b6141fe565b6001815b60018411156145a75780850481111561458b5761458b6141fe565b600184161561459957908102905b60019390931c928002614570565b935093915050565b5f826145bd5750600161182b565b816145c957505f61182b565b81600181146145df57600281146145e957614605565b600191505061182b565b60ff8411156145fa576145fa6141fe565b50506001821b61182b565b5060208310610133831016604e8410600b8410161715614628575081810a61182b565b6146345f19848461456c565b805f1904821115614647576146476141fe565b029392505050565b5f612fb160ff8416836145af565b808202811582820484141761182b5761182b6141fe565b5f8261468e57634e487b7160e01b5f52601260045260245ffd5b500490565b5f602082840312156146a3575f5ffd5b8151612fb18161397256fea2646970667358221220889ff3fd923d06dca52714f39422ee0dffa296da4e3ef9bcf07e601d5462fb2464736f6c634300081c003300000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b0000000000000000000000002cba4739a9703ba57d5f50476d51c3a9bcc86de8000000000000000000000000000000000000000000000000000000000000a4550000000000000000000000000000000000000000000000000000000000004155000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071b6e467f549b367487a28ef07520147a90a5f3c
Deployed Bytecode
0x6080604052600436106101bd575f3560e01c80638a261c67116100f2578063cc8388d011610092578063f556882311610062578063f55688231461061d578063f620399014610630578063f85ae6361461065c578063fa6a6d361461067b575f5ffd5b8063cc8388d01461052f578063dae2fc1214610562578063e8dfd50814610581578063f1d3ac4f146105ac575f5ffd5b80639e70a740116100cd5780639e70a740146104a7578063b365b191146104d2578063b3f34dc7146104f1578063bedb86fb14610510575f5ffd5b80638a261c67146103e5578063919a1704146104195780639c3f1e9014610447575f5ffd5b80634a85d7881161015d578063814aa66911610138578063814aa6691461036157806381b152c014610380578063843bb5591461039f57806384acd1bb146103b2575f5ffd5b80634a85d788146102e6578063538ee295146103125780635c975abb14610331575f5ffd5b80633d474866116101985780633d4748661461024b578063452a932014610277578063459656ee146102b35780634818e84d146102c7575f5ffd5b806319535a54146101c85780632dd845c7146101f15780632fcb4f041461022a575f5ffd5b366101c457005b5f5ffd5b6101db6101d63660046139f9565b610690565b6040516101e89190613ab2565b60405180910390f35b3480156101fc575f5ffd5b5061021c61020b366004613ac4565b60076020525f908152604090205481565b6040519081526020016101e8565b348015610235575f5ffd5b50610249610244366004613af1565b610bea565b005b348015610256575f5ffd5b5061026a610265366004613b92565b610c48565b6040516101e89190613bec565b348015610282575f5ffd5b5060035461029b9061010090046001600160a01b031681565b6040516001600160a01b0390911681526020016101e8565b3480156102be575f5ffd5b50610249610d81565b3480156102d2575f5ffd5b5060045461029b906001600160a01b031681565b6102f96102f4366004613b92565b610ded565b60405167ffffffffffffffff90911681526020016101e8565b34801561031d575f5ffd5b5061024961032c366004613c5f565b611067565b34801561033c575f5ffd5b5060045461035190600160a01b900460ff1681565b60405190151581526020016101e8565b34801561036c575f5ffd5b5061024961037b366004613c7a565b6110ac565b34801561038b575f5ffd5b506101db61039a366004613ac4565b611170565b6102f96103ad366004613cb6565b611207565b3480156103bd575f5ffd5b5061029b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b81565b3480156103f0575f5ffd5b5060015461040690600160a01b900461ffff1681565b60405161ffff90911681526020016101e8565b348015610424575f5ffd5b50610351610433366004613cfc565b60096020525f908152604090205460ff1681565b348015610452575f5ffd5b50610498610461366004613ac4565b60056020525f908152604090205460ff811690610100810467ffffffffffffffff16906901000000000000000000900461ffff1683565b6040516101e893929190613d17565b3480156104b2575f5ffd5b5061021c6104c1366004613d47565b60086020525f908152604090205481565b3480156104dd575f5ffd5b506102496104ec366004613d62565b611513565b3480156104fc575f5ffd5b5061021c61050b366004613e27565b611665565b34801561051b575f5ffd5b5061024961052a366004613e5c565b611831565b34801561053a575f5ffd5b5061029b7f00000000000000000000000071b6e467f549b367487a28ef07520147a90a5f3c81565b34801561056d575f5ffd5b5061024961057c366004613e77565b611899565b34801561058c575f5ffd5b5060035461059a9060ff1681565b60405160ff90911681526020016101e8565b3480156105b7575f5ffd5b506105cb6105c6366004613e77565b611cad565b6040516101e891905f60a08201905060ff8351168252602083015160208301526040830151604083015267ffffffffffffffff606084015116606083015261ffff608084015116608083015292915050565b61024961062b366004613ea9565b611da0565b34801561063b575f5ffd5b5061064f61064a366004613e77565b61215e565b6040516101e89190613ed7565b348015610667575f5ffd5b5060015461029b906001600160a01b031681565b348015610686575f5ffd5b5061021c60025481565b606061069a61225c565b6001546040517fc0fd8bde0000000000000000000000000000000000000000000000000000000081525f91829182916001600160a01b03169063c0fd8bde906106e7908c90600401613ab2565b5f60405180830381865afa158015610701573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610728919081019061407f565b9250925092508181906107575760405162461bcd60e51b815260040161074e9190613ab2565b60405180910390fd5b50600154606084015161ffff908116600160a01b909204161461078d576040516327e8d62960e11b815260040160405180910390fd5b6002548360800151146107b35760405163d08bf9e160e01b815260040160405180910390fd5b5f6107c18460e00151611cad565b90507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa15801561081f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061084391906141e3565b61ffff1660608a0152602081015161086361085e8b8b6122b3565b612453565b80519060200120146108885760405163561a411d60e11b815260040160405180910390fd5b5f6108968a60a0015161254c565b90506001600160a01b038116156108b5576108b2818d896125a0565b9b505b326001600160a01b03166108cc836040015161254c565b6001600160a01b0316141580156109055750816080015161ffff168a61014001516108f79190614212565b67ffffffffffffffff164211155b15610922576040516282b42960e81b815260040160405180910390fd5b89610140015167ffffffffffffffff164210610951576040516354a36da760e11b815260040160405180910390fd5b5f6020808401515f908152600591829052604090205460ff169081111561097a5761097a613bc4565b1461099857604051632916ae3360e01b815260040160405180910390fd5b895160ff166002036109c7576020828101515f908152600590915260409020805460ff191660011790556109e6565b6020828101515f908152600590915260409020805460ff191660021790555b610a818c6040518061010001604052808d5f015160ff16815260200185602001518152602001856060015167ffffffffffffffff1681526020018d60c0015167ffffffffffffffff168152602001610a418e6040015161254c565b6001600160a01b03168152602001846001600160a01b031681526020018d60e0015167ffffffffffffffff1681526020018b60400151151581525061272f565b5f610b6e610b6484602001518d8d8d60408051610140810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081019190915260408051610140810190915280600260ff168152602001868152602001845f015161ffff168152602001846020015181526020018560800151815260200185610160015160ff168152602001846040015160ff168152602001835f01518152602001836020015181526020014267ffffffffffffffff168152509050949350505050565b8a60400151612b4e565b90507f6ec9b1b5a9f54d929394f18dac4ba1b1cc79823f2266c2d09cab8a3b4700b40b8360200151828f604051610bc29392919092835267ffffffffffffffff919091166020830152604082015260600190565b60405180910390a18560e001519650505050505050610be060015f55565b9695505050505050565b60035461010090046001600160a01b03163314610c19576040516282b42960e81b815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60605f825167ffffffffffffffff811115610c6557610c656136a2565b604051908082528060200260200182016040528015610cae57816020015b604080516060810182525f80825260208083018290529282015282525f19909201910181610c835790505b5090505f5b8351811015610d7a5760055f858381518110610cd157610cd1614232565b602002602001015181526020019081526020015f206040518060600160405290815f82015f9054906101000a900460ff166005811115610d1357610d13613bc4565b6005811115610d2457610d24613bc4565b81529054610100810467ffffffffffffffff1660208301526901000000000000000000900461ffff166040909101528251839083908110610d6757610d67614232565b6020908102919091010152600101610cb3565b5092915050565b6004546001600160a01b03163314610dab576040516282b42960e81b815260040160405180910390fd5b600454600380546001600160a01b03909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b5f6060815b8351811015610f69575f60065f868481518110610e1157610e11614232565b602002602001015181526020019081526020015f208054610e3190614246565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5d90614246565b8015610ea85780601f10610e7f57610100808354040283529160200191610ea8565b820191905f5260205f20905b815481529060010190602001808311610e8b57829003601f168201915b5050505050905060ac815114610f0757848281518110610eca57610eca614232565b60200260200101516040517f956fc85700000000000000000000000000000000000000000000000000000000815260040161074e91815260200190565b8281604051602001610f1a92919061428f565b604051602081830303815290604052925060065f868481518110610f4057610f40614232565b602002602001015181526020019081526020015f205f610f609190613654565b50600101610df2565b505f600584518380519060200120604051602001610fb69392919060f89390931b6001600160f81b031916835260f09190911b6001600160f01b0319166001830152600382015260230190565b60408051601f19818403018152908290526003546358cd21bf60e11b83529092506001600160a01b037f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b169163b19a437e91349161101e915f91879160ff16906004016142a3565b60206040518083038185885af115801561103a573d5f5f3e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061105f91906142d4565b949350505050565b60035461010090046001600160a01b03163314611096576040516282b42960e81b815260040160405180910390fd5b6003805460ff191660ff92909216919091179055565b60035461010090046001600160a01b031633146110db576040516282b42960e81b815260040160405180910390fd5b61ffff821615806110ea575080155b15611121576040517f453b7de000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805461ffff909316600160a01b027fffffffffffffffffffff000000000000000000000000000000000000000000009093166001600160a01b039094169390931791909117909155600255565b60066020525f90815260409020805461118890614246565b80601f01602080910402602001604051908101604052809291908181526020018280546111b490614246565b80156111ff5780601f106111d6576101008083540402835291602001916111ff565b820191905f5260205f20905b8154815290600101906020018083116111e257829003601f168201915b505050505081565b5f61121061225c565b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061129091906141e3565b61ffff1660608501525f6112a761085e86866122b3565b8051906020012090508581146112d05760405163561a411d60e11b815260040160405180910390fd5b5f868152600560208190526040808320815160608101909252805491929091839160ff9091169081111561130657611306613bc4565b600581111561131757611317613bc4565b81529054610100810467ffffffffffffffff9081166020840152690100000000000000000090910461ffff16604090920191909152610140880151919250164211611375576040516354a36da760e11b815260040160405180910390fd5b5f8151600581111561138957611389613bc4565b146113a757604051632916ae3360e01b815260040160405180910390fd5b5f878152600560209081526040808320805460ff1916600417905580516101008082018352600382528184018c9052895161ffff169282019290925288830151606082015291890151608083015260a0820187905288015167ffffffffffffffff90811660c08301526101208901511660e08201529061142682612ce1565b6003546040516358cd21bf60e11b81529192506001600160a01b037f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b169163b19a437e913491611480915f91879160ff16906004016142a3565b60206040518083038185885af115801561149c573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906114c191906142d4565b604080518b815267ffffffffffffffff831660208201529196507f45a58de39e77dfc9cd1d63970a706575668048121d822749d2298eb75125123e910160405180910390a15050505061105f60015f55565b60035461010090046001600160a01b03163314611542576040516282b42960e81b815260040160405180910390fd5b80518251146115935760405162461bcd60e51b815260206004820152601460248201527f696e76616c6964206172726179206c656e677468000000000000000000000000604482015260640161074e565b5f5b8251811015611660575f5f1b60085f8584815181106115b6576115b6614232565b602002602001015161ffff1661ffff1681526020019081526020015f20541461160b576040517f9a23a9de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81818151811061161d5761161d614232565b602002602001015160085f85848151811061163a5761163a614232565b60209081029190910181015161ffff1682528101919091526040015f2055600101611595565b505050565b5f61166e61225c565b825f015160ff1660021461169557604051634a7f394f60e01b815260040160405180910390fd5b336001600160a01b03166116ac846040015161254c565b6001600160a01b0316146116d2576040516282b42960e81b815260040160405180910390fd5b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa15801561172e573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061175291906141e3565b61ffff1660608401525f61176961085e85856122b3565b8051602090910120905060015f8281526005602081905260409091205460ff169081111561179957611799613bc4565b146117b757604051632916ae3360e01b815260040160405180910390fd5b5f818152600560209081526040808320805460ff19166002179055600790915281205460a08601519093506117eb9061254c565b90506001600160a01b03811661180c5761180733846001612d98565b611820565b6118206001600160a01b0382163385612e43565b505061182b60015f55565b92915050565b60035461010090046001600160a01b03163314611860576040516282b42960e81b815260040160405180910390fd5b60048054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b60035461010090046001600160a01b031633146118c8576040516282b42960e81b815260040160405180910390fd5b5f5f5f7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016119179190613ab2565b5f60405180830381865afa158015611931573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611958919081019061407f565b92509250925081819061197e5760405162461bcd60e51b815260040161074e9190613ab2565b5060a083015167ffffffffffffffff165f9081526009602052604090205460ff16156119d6576040517f7123717600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a083015167ffffffffffffffff165f908152600960205260409020805460ff19166001908117909155606084015161ffff1614611a27576040516327e8d62960e11b815260040160405180910390fd5b60015f5260086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f54608084015114611a755760405163d08bf9e160e01b815260040160405180910390fd5b5f611a838460e0015161215e565b90507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ae1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b0591906141e3565b61ffff16816020015161ffff1614611b49576040517f77d876fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408101516001600160a01b03163014611b8f576040517f5569851a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606081015115611bec57806080015160ff166005811115611bb257611bb2613bc4565b60608201515f9081526005602081905260409091208054909160ff19909116906001908490811115611be657611be6613bc4565b02179055505b60c081015167ffffffffffffffff1615611ca6575f611c258260c0015167ffffffffffffffff16611c208460a00151612eec565b612fb8565b60a08301519091506001600160a01b0316611c6b57611c667f00000000000000000000000071b6e467f549b367487a28ef07520147a90a5f3c826001612d98565b611ca4565b60a0820151611ca4906001600160a01b03167f00000000000000000000000071b6e467f549b367487a28ef07520147a90a5f3c83612e43565b505b5050505050565b6040805160a0810182525f80825260208201819052918101829052606081018290526080810182905290611ce18382612fef565b60ff168252611cf16001826142ef565b825190915060ff16600114611d1957604051634a7f394f60e01b815260040160405180910390fd5b611d238382613054565b602080840191909152611d3690826142ef565b9050611d4283826130b9565b67ffffffffffffffff166060830152611d5c6008826142ef565b9050611d688382613054565b6040830152611d786020826142ef565b9050611d84838261311e565b61ffff166080830152611d986002826142ef565b905050919050565b611da861225c565b61018084015160ff16600114611dea576040517ffd426f5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611df88560a0015161254c565b90506001600160a01b03811615611e1757611e148188846125a0565b96505b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e73573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e9791906141e3565b61ffff16606086015285611eae61085e87876122b3565b8051906020012014611ed35760405163561a411d60e11b815260040160405180910390fd5b84610140015167ffffffffffffffff16421115611f03576040516354a36da760e11b815260040160405180910390fd5b5f86815260056020819052604082205460ff1690811115611f2657611f26613bc4565b14611f4457604051632916ae3360e01b815260040160405180910390fd5b845160ff16600203611f6d575f868152600560205260409020805460ff19166001179055611f86565b5f868152600560205260409020805460ff191660021790555b61201d87604051806101000160405280885f015160ff1681526020018981526020018860c0015167ffffffffffffffff1681526020018860c0015167ffffffffffffffff168152602001611fdd896040015161254c565b6001600160a01b03168152602001846001600160a01b031681526020018860e0015167ffffffffffffffff1681526020018660400151151581525061272f565b5f6121066120fc8888888860408051610140810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081019190915260408051610140810190915280600260ff168152602001868152602001845f015161ffff168152602001846020015181526020018560800151815260200185610160015160ff168152602001846040015160ff168152602001835f01518152602001836020015181526020014267ffffffffffffffff168152509050949350505050565b8560400151612b4e565b6040805189815267ffffffffffffffff831660208201529081018a90529091507f6ec9b1b5a9f54d929394f18dac4ba1b1cc79823f2266c2d09cab8a3b4700b40b9060600160405180910390a15050611ca460015f55565b6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c08101829052906121a08382612fef565b60ff1682526121b06001826142ef565b825190915060ff166007146121d857604051634a7f394f60e01b815260040160405180910390fd5b6121e28382613054565b60608301526121f26020826142ef565b90506121fe8382612fef565b60ff1660808301526122116001826142ef565b905061221d8382613183565b6001600160a01b031660a08301526122366020826142ef565b905061224283826130b9565b67ffffffffffffffff1660c0830152611d986008826142ef565b60025f54036122ad5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161074e565b60025f55565b60408051610240810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081018290526102008101829052610220810191909152604051806102400160405280845f015160ff16815260200184602001518152602001835f015161ffff1681526020018360200151815260200184604001518152602001846060015161ffff1681526020018460a0015181526020018460c0015167ffffffffffffffff1681526020018460e0015167ffffffffffffffff16815260200184610100015167ffffffffffffffff16815260200184610120015167ffffffffffffffff16815260200184610140015167ffffffffffffffff1681526020018460800151815260200184610160015160ff168152602001836040015160ff16815260200184610180015160ff168152602001846101a0015181526020018360600151815250905092915050565b6060815f015182602001518360400151846060015185608001518660a001518760c001518860e001518961010001518a61012001518b61014001518c61016001516040516020016124af9c9b9a99989796959493929190614302565b60408051601f19818403018152908290526101808401516101a08501516101c08601516101e087015161020088015161022089015195975061182b96612535969060200195865260f894851b6001600160f81b0319908116602088015293851b841660218701529190931b90911660228401526023830191909152604382015260630190565b60408051601f1981840301815291905282906131df565b5f73ffffffffffffffffffffffffffffffffffffffff1982161561259c576040517ff652ddbc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201525f9081906001600160a01b0386169063dd62ed3e90604401602060405180830381865afa158015612605573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061262991906143e0565b90508381101561263e5761263e85338561325c565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015612682573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126a691906143e0565b90506126bd6001600160a01b038716333088613327565b6040516370a0823160e01b815230600482015281906001600160a01b038816906370a0823190602401602060405180830381865afa158015612701573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061272591906143e0565b610be091906143f7565b60a08101515f906001600160a01b031661274b5750601261275b565b6127588260a00151612eec565b90505b612773826040015167ffffffffffffffff1682612fb8565b8310156127ac576040517f5945ea5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816060015167ffffffffffffffff166127c58483613378565b10156127fd576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a08201516001600160a01b0316612912578160e0015180156128205750823414155b806128c157508160e001511580156128c157507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa15801561288f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128b391906143e0565b6128bd90846142ef565b3414155b156128df576040516317dfbee160e01b815260040160405180910390fd5b815160ff1660020361290257506020908101515f90815260079091526040902055565b6116608260800151846001612d98565b60c082015167ffffffffffffffff1615612a40575f6129408360c0015167ffffffffffffffff166012612fb8565b90508260e0015180156129535750803414155b806129f457508260e001511580156129f457507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129e691906143e0565b6129f090826142ef565b3414155b15612a2b576040517fdca3db9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3a8360800151825f612d98565b50612b05565b8160e001518015612a5057503415155b80612ae757508160e00151158015612ae757507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa158015612abf573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ae391906143e0565b3414155b15612b05576040516317dfbee160e01b815260040160405180910390fd5b815160ff16600203612b2857506020908101515f90815260079091526040902055565b6116608260800151848460a001516001600160a01b0316612e439092919063ffffffff16565b5f5f612b59846133a5565b90508215612b84576020808501515f908152600690915260409020612b7e828261444e565b50610d7a565b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b031663b19a437e7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c0f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c3391906143e0565b5f600285604051602001612c48929190614509565b60408051601f19818403018152908290526003547fffffffff0000000000000000000000000000000000000000000000000000000060e087901b168352612c98939260ff909116906004016142a3565b60206040518083038185885af1158015612cb4573d5f5f3e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612cd991906142d4565b91505061182b565b6060815f015182602001518360400151846060015185608001518660a001518760c001518860e00151604051602001612d8298979695949392919060f89890981b6001600160f81b0319168852600188019690965260f09490941b6001600160f01b031916602187015260238601929092526043850152606384015260c090811b6001600160c01b0319908116608385015291901b16608b82015260930190565b6040516020818303038152906040529050919050565b5f836001600160a01b0316836040515f6040518083038185875af1925050503d805f8114612de1576040519150601f19603f3d011682016040523d82523d5f602084013e612de6565b606091505b505090508115612e3d5780612e3d5760405162461bcd60e51b815260206004820152600e60248201527f7061796d656e74206661696c6564000000000000000000000000000000000000604482015260640161074e565b50505050565b6040516001600160a01b0383166024820152604481018290526116609084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613451565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f9182916001600160a01b03851691612f5c9161452d565b5f60405180830381855afa9150503d805f8114612f94576040519150601f19603f3d011682016040523d82523d5f602084013e612f99565b606091505b5091505080806020019051810190612fb19190614538565b9392505050565b5f60088260ff161115612fe857612fd0600883614553565b612fdb90600a61464f565b612fe5908461465d565b92505b5090919050565b5f612ffb8260016142ef565b8351101561304b5760405162461bcd60e51b815260206004820152601360248201527f746f55696e74385f6f75744f66426f756e647300000000000000000000000000604482015260640161074e565b50016001015190565b5f6130608260206142ef565b835110156130b05760405162461bcd60e51b815260206004820152601560248201527f746f427974657333325f6f75744f66426f756e64730000000000000000000000604482015260640161074e565b50016020015190565b5f6130c58260086142ef565b835110156131155760405162461bcd60e51b815260206004820152601460248201527f746f55696e7436345f6f75744f66426f756e6473000000000000000000000000604482015260640161074e565b50016008015190565b5f61312a8260026142ef565b8351101561317a5760405162461bcd60e51b815260206004820152601460248201527f746f55696e7431365f6f75744f66426f756e6473000000000000000000000000604482015260640161074e565b50016002015190565b5f61318f8260206142ef565b835110156130b05760405162461bcd60e51b815260206004820152601560248201527f746f55696e743235365f6f75744f66426f756e64730000000000000000000000604482015260640161074e565b6060806040519050835180825260208201818101602087015b818310156132105780518352602092830192016131f8565b50855184518101855292509050808201602086015b8183101561323d578051835260209283019201613225565b508651929092011591909101601f01601f191660405250905092915050565b6001600160a01b03831663d505accf8330843560208601356132846060880160408901613c5f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b1681526001600160a01b0395861660048201529490931660248501526044840191909152606483015260ff166084820152606084013560a4820152608084013560c482015260e4015f604051808303815f87803b15801561330c575f5ffd5b505af115801561331e573d5f5f3e3d5ffd5b50505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052612e3d9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612e88565b5f60088260ff161115612fe857613390600883614553565b61339b90600a61464f565b612fe59084614674565b606081602001518260400151836060015184608001518560a001518660c001518760e00151886101000151896101200151604051602001612d829998979695949392919098895260f09790971b6001600160f01b03191660208901526022880195909552604287019390935260f891821b6001600160f81b03199081166062880152911b1660638501526064840152608483015260c01b6001600160c01b03191660a482015260ac0190565b5f6134a5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166135379092919063ffffffff16565b905080515f14806134c55750808060200190518101906134c59190614693565b6116605760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161074e565b606061105f84845f85855f5f866001600160a01b0316858760405161355c919061452d565b5f6040518083038185875af1925050503d805f8114613596576040519150601f19603f3d011682016040523d82523d5f602084013e61359b565b606091505b50915091506135ac878383876135b7565b979650505050505050565b606083156136255782515f0361361e576001600160a01b0385163b61361e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161074e565b508161105f565b61105f838381511561363a5781518083602001fd5b8060405162461bcd60e51b815260040161074e9190613ab2565b50805461366090614246565b5f825580601f1061366f575050565b601f0160209004905f5260205f209081019061368b919061368e565b50565b5b8082111561259c575f815560010161368f565b634e487b7160e01b5f52604160045260245ffd5b6040516101c0810167ffffffffffffffff811182821017156136da576136da6136a2565b60405290565b6040516080810167ffffffffffffffff811182821017156136da576136da6136a2565b604051610160810167ffffffffffffffff811182821017156136da576136da6136a2565b604051601f8201601f1916810167ffffffffffffffff81118282101715613750576137506136a2565b604052919050565b5f67ffffffffffffffff821115613771576137716136a2565b50601f01601f191660200190565b5f82601f83011261378e575f5ffd5b81356137a161379c82613758565b613727565b8181528460208386010111156137b5575f5ffd5b816020850160208301375f918101602001919091529392505050565b60ff8116811461368b575f5ffd5b80356137ea816137d1565b919050565b61ffff8116811461368b575f5ffd5b80356137ea816137ef565b67ffffffffffffffff8116811461368b575f5ffd5b80356137ea81613809565b5f6101c0828403121561383a575f5ffd5b6138426136b6565b905061384d826137df565b8152602082810135908201526040808301359082015261386f606083016137fe565b60608201526080828101359082015260a0808301359082015261389460c0830161381e565b60c08201526138a560e0830161381e565b60e08201526138b7610100830161381e565b6101008201526138ca610120830161381e565b6101208201526138dd610140830161381e565b6101408201526138f061016083016137df565b61016082015261390361018083016137df565b6101808201526101a09182013591810191909152919050565b5f6080828403121561392c575f5ffd5b6139346136e0565b90508135613941816137ef565b815260208281013590820152604082013561395b816137d1565b604082015260609182013591810191909152919050565b801515811461368b575f5ffd5b5f6060828403121561398f575f5ffd5b6040516060810167ffffffffffffffff811182821017156139b2576139b26136a2565b6040908152833582526020808501359083015290915081908301356139d681613972565b6040919091015292915050565b5f60a082840312156139f3575f5ffd5b50919050565b5f5f5f5f5f5f6103808789031215613a0f575f5ffd5b86359550602087013567ffffffffffffffff811115613a2c575f5ffd5b613a3889828a0161377f565b955050613a488860408901613829565b9350613a5888610200890161391c565b9250613a6888610280890161397f565b9150613a78886102e089016139e3565b90509295509295509295565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f612fb16020830184613a84565b5f60208284031215613ad4575f5ffd5b5035919050565b80356001600160a01b03811681146137ea575f5ffd5b5f60208284031215613b01575f5ffd5b612fb182613adb565b5f67ffffffffffffffff821115613b2357613b236136a2565b5060051b60200190565b5f82601f830112613b3c575f5ffd5b8135613b4a61379c82613b0a565b8082825260208201915060208360051b860101925085831115613b6b575f5ffd5b602085015b83811015613b88578035835260209283019201613b70565b5095945050505050565b5f60208284031215613ba2575f5ffd5b813567ffffffffffffffff811115613bb8575f5ffd5b61105f84828501613b2d565b634e487b7160e01b5f52602160045260245ffd5b60068110613be857613be8613bc4565b9052565b602080825282518282018190525f918401906040840190835b81811015613c54578351613c1a848251613bd8565b67ffffffffffffffff602082015116602085015261ffff604082015116604085015250606083019250602084019350600181019050613c05565b509095945050505050565b5f60208284031215613c6f575f5ffd5b8135612fb1816137d1565b5f5f5f60608486031215613c8c575f5ffd5b613c9584613adb565b92506020840135613ca5816137ef565b929592945050506040919091013590565b5f5f5f5f6102808587031215613cca575f5ffd5b84359350613cdb8660208701613829565b9250613ceb866101e0870161391c565b939692955092936102600135925050565b5f60208284031215613d0c575f5ffd5b8135612fb181613809565b60608101613d258286613bd8565b67ffffffffffffffff8416602083015261ffff83166040830152949350505050565b5f60208284031215613d57575f5ffd5b8135612fb1816137ef565b5f5f60408385031215613d73575f5ffd5b823567ffffffffffffffff811115613d89575f5ffd5b8301601f81018513613d99575f5ffd5b8035613da761379c82613b0a565b8082825260208201915060208360051b850101925087831115613dc8575f5ffd5b6020840193505b82841015613df3578335613de2816137ef565b825260209384019390910190613dcf565b9450505050602083013567ffffffffffffffff811115613e11575f5ffd5b613e1d85828601613b2d565b9150509250929050565b5f5f6102408385031215613e39575f5ffd5b613e438484613829565b9150613e53846101c0850161391c565b90509250929050565b5f60208284031215613e6c575f5ffd5b8135612fb181613972565b5f60208284031215613e87575f5ffd5b813567ffffffffffffffff811115613e9d575f5ffd5b61105f8482850161377f565b5f5f5f5f5f5f6103808789031215613ebf575f5ffd5b8635955060208701359450613a488860408901613829565b5f60e08201905060ff835116825261ffff60208401511660208301526001600160a01b0360408401511660408301526060830151606083015260ff60808401511660808301526001600160a01b0360a08401511660a083015260c0830151610d7a60c084018267ffffffffffffffff169052565b80516137ea816137d1565b805163ffffffff811681146137ea575f5ffd5b80516137ea816137ef565b80516137ea81613809565b5f82601f830112613f8e575f5ffd5b8151602083015f613fa161379c84613758565b9050828152858383011115613fb4575f5ffd5b8282602083015e5f92810160200192909252509392505050565b5f82601f830112613fdd575f5ffd5b8151613feb61379c82613b0a565b8082825260208201915060208360071b86010192508583111561400c575f5ffd5b602085015b83811015613b885760808188031215614028575f5ffd5b6140306136e0565b8151815260208083015190820152604082015161404c816137d1565b6040820152606082015161405f816137d1565b60608201528352602090920191608001614011565b80516137ea81613972565b5f5f5f60608486031215614091575f5ffd5b835167ffffffffffffffff8111156140a7575f5ffd5b840161016081870312156140b9575f5ffd5b6140c1613703565b6140ca82613f4b565b81526140d860208301613f56565b60208201526140e960408301613f56565b60408201526140fa60608301613f69565b60608201526080828101519082015261411560a08301613f74565b60a082015261412660c08301613f4b565b60c082015260e082015167ffffffffffffffff811115614144575f5ffd5b61415088828501613f7f565b60e0830152506141636101008301613f56565b61010082015261012082015167ffffffffffffffff811115614183575f5ffd5b61418f88828501613fce565b61012083015250610140918201519181019190915292506141b260208501614074565b9150604084015167ffffffffffffffff8111156141cd575f5ffd5b6141d986828701613f7f565b9150509250925092565b5f602082840312156141f3575f5ffd5b8151612fb1816137ef565b634e487b7160e01b5f52601160045260245ffd5b67ffffffffffffffff828116828216039081111561182b5761182b6141fe565b634e487b7160e01b5f52603260045260245ffd5b600181811c9082168061425a57607f821691505b6020821081036139f357634e487b7160e01b5f52602260045260245ffd5b5f81518060208401855e5f93019283525090919050565b5f61105f61429d8386614278565b84614278565b63ffffffff84168152606060208201525f6142c16060830185613a84565b905060ff83166040830152949350505050565b5f602082840312156142e4575f5ffd5b8151612fb181613809565b8082018082111561182b5761182b6141fe565b6001600160f81b03198d60f81b1681528b60018201526001600160f01b03198b60f01b1660218201528960238201528860438201526001600160f01b03198860f01b166063820152866065820152614369608582018760c01b6001600160c01b0319169052565b614382608d82018660c01b6001600160c01b0319169052565b61439b609582018560c01b6001600160c01b0319169052565b6143b4609d82018460c01b6001600160c01b0319169052565b6143cd60a582018360c01b6001600160c01b0319169052565b60ad019c9b505050505050505050505050565b5f602082840312156143f0575f5ffd5b5051919050565b8181038181111561182b5761182b6141fe565b601f82111561166057805f5260205f20601f840160051c8101602085101561442f5750805b601f840160051c820191505b81811015611ca6575f815560010161443b565b815167ffffffffffffffff811115614468576144686136a2565b61447c816144768454614246565b8461440a565b6020601f8211600181146144ae575f83156144975750848201515b5f19600385901b1c1916600184901b178455611ca6565b5f84815260208120601f198516915b828110156144dd57878501518255602094850194600190920191016144bd565b50848210156144fa57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f6008841061451a5761451a613bc4565b8360f81b825261105f6001830184614278565b5f612fb18284614278565b5f60208284031215614548575f5ffd5b8151612fb1816137d1565b60ff828116828216039081111561182b5761182b6141fe565b6001815b60018411156145a75780850481111561458b5761458b6141fe565b600184161561459957908102905b60019390931c928002614570565b935093915050565b5f826145bd5750600161182b565b816145c957505f61182b565b81600181146145df57600281146145e957614605565b600191505061182b565b60ff8411156145fa576145fa6141fe565b50506001821b61182b565b5060208310610133831016604e8410600b8410161715614628575081810a61182b565b6146345f19848461456c565b805f1904821115614647576146476141fe565b029392505050565b5f612fb160ff8416836145af565b808202811582820484141761182b5761182b6141fe565b5f8261468e57634e487b7160e01b5f52601260045260245ffd5b500490565b5f602082840312156146a3575f5ffd5b8151612fb18161397256fea2646970667358221220889ff3fd923d06dca52714f39422ee0dffa296da4e3ef9bcf07e601d5462fb2464736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b0000000000000000000000002cba4739a9703ba57d5f50476d51c3a9bcc86de8000000000000000000000000000000000000000000000000000000000000a4550000000000000000000000000000000000000000000000000000000000004155000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071b6e467f549b367487a28ef07520147a90a5f3c
-----Decoded View---------------
Arg [0] : _wormhole (address): 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B
Arg [1] : _auctionVerifier (address): 0x2cba4739a9703bA57D5f50476D51c3a9bCc86dE8
Arg [2] : _auctionChainId (uint16): 42069
Arg [3] : _auctionAddr (bytes32): 0x0000000000000000000000000000000000000000000000000000000000004155
Arg [4] : _consistencyLevel (uint8): 0
Arg [5] : _rescueVault (address): 0x71b6E467F549B367487a28eF07520147a90a5f3C
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b
Arg [1] : 0000000000000000000000002cba4739a9703ba57d5f50476d51c3a9bcc86de8
Arg [2] : 000000000000000000000000000000000000000000000000000000000000a455
Arg [3] : 0000000000000000000000000000000000000000000000000000000000004155
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 00000000000000000000000071b6e467f549b367487a28ef07520147a90a5f3c
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.