Latest 25 from a total of 31,143 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Batch Update Rem... | 30199780 | 2 days ago | IN | 0 ETH | 0.00000098 | ||||
| Batch Update Rem... | 30199780 | 2 days ago | IN | 0 ETH | 0.00000097 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000125 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000125 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000125 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000125 | ||||
| Batch Update Rem... | 30199631 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199630 | 2 days ago | IN | 0 ETH | 0.00000126 | ||||
| Batch Update Rem... | 30199499 | 2 days ago | IN | 0 ETH | 0.00000121 | ||||
| Batch Update Rem... | 30199499 | 2 days ago | IN | 0 ETH | 0.00000121 | ||||
| Batch Update Rem... | 30199499 | 2 days ago | IN | 0 ETH | 0.00000121 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 8885181 | 495 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PaymentHelper
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
import { IPaymentHelperV2 as IPaymentHelper } from "src/interfaces/IPaymentHelperV2.sol";
import { ISuperRBAC } from "src/interfaces/ISuperRBAC.sol";
import { ISuperRegistry } from "src/interfaces/ISuperRegistry.sol";
import { ISuperformFactory } from "src/interfaces/ISuperformFactory.sol";
import { IBaseStateRegistry } from "src/interfaces/IBaseStateRegistry.sol";
import { IAmbImplementation } from "src/interfaces/IAmbImplementation.sol";
import { Error } from "src/libraries/Error.sol";
import { DataLib } from "src/libraries/DataLib.sol";
import { ProofLib } from "src/libraries/ProofLib.sol";
import { ArrayCastLib } from "src/libraries/ArrayCastLib.sol";
import {
SingleDirectSingleVaultStateReq,
SingleXChainSingleVaultStateReq,
SingleDirectMultiVaultStateReq,
SingleXChainMultiVaultStateReq,
MultiDstSingleVaultStateReq,
MultiDstMultiVaultStateReq,
LiqRequest,
AMBMessage,
MultiVaultSFData,
SingleVaultSFData,
AMBExtraData,
InitMultiVaultData,
InitSingleVaultData,
ReturnMultiData,
ReturnSingleData
} from "src/types/DataTypes.sol";
import { AggregatorV3Interface } from "src/vendor/chainlink/AggregatorV3Interface.sol";
/// @dev interface to read public variable from state registry
interface ReadOnlyBaseRegistry is IBaseStateRegistry {
function payloadsCount() external view returns (uint256);
}
/// @title PaymentHelper
/// @dev Helps estimate the cost for the entire transaction lifecycle
/// @author ZeroPoint Labs
contract PaymentHelper is IPaymentHelper {
using DataLib for uint256;
using ArrayCastLib for LiqRequest;
using ArrayCastLib for bool;
using ProofLib for bytes;
using ProofLib for AMBMessage;
//////////////////////////////////////////////////////////////
// CONSTANTS //
//////////////////////////////////////////////////////////////
uint256 private constant PROOF_LENGTH = 160;
uint8 private constant MIN_FEED_PRECISION = 8;
uint8 private constant MAX_FEED_PRECISION = 18;
uint32 private constant TIMELOCK_FORM_ID = 2;
uint256 private constant MAX_UINT256 = type(uint256).max;
ISuperRegistry public immutable superRegistry;
uint64 public immutable CHAIN_ID;
//////////////////////////////////////////////////////////////
// STATE VARIABLES //
//////////////////////////////////////////////////////////////
/// @dev xchain params
mapping(uint64 chainId => AggregatorV3Interface) public nativeFeedOracle;
mapping(uint64 chainId => AggregatorV3Interface) public gasPriceOracle;
mapping(uint64 chainId => uint256 gasForSwap) public swapGasUsed;
mapping(uint64 chainId => uint256 gasForUpdateDeposit) public updateDepositGasUsed;
mapping(uint64 chainId => uint256 gasForUpdateWithdraw) public updateWithdrawGasUsed;
mapping(uint64 chainId => uint256 gasForDeposit) public depositGasUsed;
mapping(uint64 chainId => uint256 gasForWithdraw) public withdrawGasUsed;
mapping(uint64 chainId => uint256 defaultNativePrice) public nativePrice;
mapping(uint64 chainId => uint256 defaultGasPrice) public gasPrice;
mapping(uint64 chainId => uint256 gasPerByte) public gasPerByte;
mapping(uint64 chainId => uint256 gasForAck) public ackGasCost;
mapping(uint64 chainId => uint256 gasForTimelock) public timelockCost;
mapping(uint64 chainId => uint256 gasForEmergency) public emergencyCost;
/// @dev register transmuter params
bytes public extraDataForTransmuter;
//////////////////////////////////////////////////////////////
// STRUCTS //
//////////////////////////////////////////////////////////////
struct EstimateAckCostVars {
uint256 currPayloadId;
uint256 payloadHeader;
uint8 callbackType;
bytes payloadBody;
uint8[] ackAmbIds;
uint8 isMulti;
uint64 srcChainId;
bytes message;
}
struct LocalEstimateVars {
uint256 len;
uint256 superformIdsLen;
uint256 totalGas;
uint256 ambFees;
bool paused;
}
struct CalculateAmountsReq {
uint256 i;
uint64[] dstChainIds;
uint8[] ambIds;
MultiVaultSFData[] superformsData;
SingleVaultSFData[] superformData;
ISuperformFactory factory;
bool isDeposit;
}
//////////////////////////////////////////////////////////////
// MODIFIERS //
//////////////////////////////////////////////////////////////
modifier onlyProtocolAdmin() {
if (!ISuperRBAC(_getAddress(keccak256("SUPER_RBAC"))).hasProtocolAdminRole(msg.sender)) {
revert Error.NOT_PROTOCOL_ADMIN();
}
_;
}
modifier onlyPaymentAdmin() {
if (
!ISuperRBAC(superRegistry.getAddress(keccak256("SUPER_RBAC"))).hasRole(
keccak256("PAYMENT_ADMIN_ROLE"), msg.sender
)
) {
revert Error.NOT_PAYMENT_ADMIN();
}
_;
}
//////////////////////////////////////////////////////////////
// CONSTRUCTOR //
//////////////////////////////////////////////////////////////
constructor(address superRegistry_) {
if (superRegistry_ == address(0)) {
revert Error.ZERO_ADDRESS();
}
if (block.chainid > type(uint64).max) {
revert Error.BLOCK_CHAIN_ID_OUT_OF_BOUNDS();
}
CHAIN_ID = uint64(block.chainid);
superRegistry = ISuperRegistry(superRegistry_);
}
//////////////////////////////////////////////////////////////
// EXTERNAL VIEW FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @inheritdoc IPaymentHelper
function calculateAMBData(
uint64 dstChainId_,
uint8[] calldata ambIds_,
bytes memory message_
)
external
view
override
returns (uint256 totalFees, bytes memory extraData)
{
(uint256[] memory gasPerAMB, bytes[] memory extraDataPerAMB, uint256 fees) =
_estimateAMBFeesReturnExtraData(dstChainId_, ambIds_, message_);
extraData = abi.encode(AMBExtraData(gasPerAMB, extraDataPerAMB));
totalFees = fees;
}
/// @inheritdoc IPaymentHelper
function getRegisterTransmuterAMBData() external view override returns (bytes memory) {
return extraDataForTransmuter;
}
/// @inheritdoc IPaymentHelper
function estimateMultiDstMultiVault(
MultiDstMultiVaultStateReq calldata req_,
bool isDeposit_
)
external
view
override
returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount)
{
uint256 len = req_.dstChainIds.length;
uint256 liqAmountIndex;
uint256 srcAmountIndex;
uint256 dstAmountIndex;
ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY")));
SingleVaultSFData[] memory temp;
for (uint256 i; i < len; ++i) {
(liqAmountIndex, srcAmountIndex, dstAmountIndex) = _calculateAmounts(
CalculateAmountsReq(i, req_.dstChainIds, req_.ambIds[i], req_.superformsData, temp, factory, isDeposit_)
);
liqAmount += liqAmountIndex;
srcAmount += srcAmountIndex;
dstAmount += dstAmountIndex;
}
totalAmount = srcAmount + dstAmount + liqAmount;
}
/// @inheritdoc IPaymentHelper
function estimateMultiDstSingleVault(
MultiDstSingleVaultStateReq calldata req_,
bool isDeposit_
)
external
view
override
returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount)
{
uint256 len = req_.dstChainIds.length;
uint256 liqAmountIndex;
uint256 srcAmountIndex;
uint256 dstAmountIndex;
ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY")));
MultiVaultSFData[] memory temp;
for (uint256 i; i < len; ++i) {
(liqAmountIndex, srcAmountIndex, dstAmountIndex) = _calculateAmounts(
CalculateAmountsReq(i, req_.dstChainIds, req_.ambIds[i], temp, req_.superformsData, factory, isDeposit_)
);
liqAmount += liqAmountIndex;
srcAmount += srcAmountIndex;
dstAmount += dstAmountIndex;
}
totalAmount = srcAmount + dstAmount + liqAmount;
}
/// @inheritdoc IPaymentHelper
function estimateSingleXChainMultiVault(
SingleXChainMultiVaultStateReq calldata req_,
bool isDeposit_
)
external
view
override
returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount)
{
ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY")));
uint64[] memory dstChainIds = new uint64[](1);
dstChainIds[0] = req_.dstChainId;
SingleVaultSFData[] memory temp;
MultiVaultSFData[] memory sfData = new MultiVaultSFData[](1);
sfData[0] = req_.superformsData;
(liqAmount, srcAmount, dstAmount) =
_calculateAmounts(CalculateAmountsReq(0, dstChainIds, req_.ambIds, sfData, temp, factory, isDeposit_));
totalAmount = srcAmount + dstAmount + liqAmount;
}
/// @inheritdoc IPaymentHelper
function estimateSingleXChainSingleVault(
SingleXChainSingleVaultStateReq calldata req_,
bool isDeposit_
)
external
view
override
returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount)
{
ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY")));
uint64[] memory dstChainIds = new uint64[](1);
dstChainIds[0] = req_.dstChainId;
MultiVaultSFData[] memory temp;
SingleVaultSFData[] memory sfData = new SingleVaultSFData[](1);
sfData[0] = req_.superformData;
(liqAmount, srcAmount, dstAmount) =
_calculateAmounts(CalculateAmountsReq(0, dstChainIds, req_.ambIds, temp, sfData, factory, isDeposit_));
totalAmount = srcAmount + dstAmount + liqAmount;
}
/// @inheritdoc IPaymentHelper
function estimateSingleDirectSingleVault(
SingleDirectSingleVaultStateReq calldata req_,
bool isDeposit_
)
external
view
override
returns (uint256 liqAmount, uint256 dstOrSameChainAmt, uint256 totalAmount)
{
ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY")));
uint64[] memory dstChainIds = new uint64[](1);
dstChainIds[0] = CHAIN_ID;
SingleVaultSFData[] memory sfData = new SingleVaultSFData[](1);
sfData[0] = req_.superformData;
MultiVaultSFData[] memory temp;
uint8[] memory ambIds;
(liqAmount,, dstOrSameChainAmt) =
_calculateAmounts(CalculateAmountsReq(0, dstChainIds, ambIds, temp, sfData, factory, isDeposit_));
totalAmount = liqAmount + dstOrSameChainAmt;
}
/// @inheritdoc IPaymentHelper
function estimateSingleDirectMultiVault(
SingleDirectMultiVaultStateReq calldata req_,
bool isDeposit_
)
external
view
override
returns (uint256 liqAmount, uint256 dstOrSameChainAmt, uint256 totalAmount)
{
ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY")));
uint64[] memory dstChainIds = new uint64[](1);
dstChainIds[0] = CHAIN_ID;
SingleVaultSFData[] memory temp;
MultiVaultSFData[] memory sfData = new MultiVaultSFData[](1);
sfData[0] = req_.superformData;
uint8[] memory ambIds;
(liqAmount,, dstOrSameChainAmt) =
_calculateAmounts(CalculateAmountsReq(0, dstChainIds, ambIds, sfData, temp, factory, isDeposit_));
totalAmount = liqAmount + dstOrSameChainAmt;
}
/// @inheritdoc IPaymentHelper
function estimateAMBFees(
uint8[] memory ambIds_,
uint64 dstChainId_,
bytes memory message_,
bytes[] memory extraData_
)
public
view
override
returns (uint256 totalFees, uint256[] memory)
{
uint256 len = ambIds_.length;
uint256[] memory fees = new uint256[](len);
/// @dev just checks the estimate for sending message from src -> dst
if (CHAIN_ID != dstChainId_) {
for (uint256 i; i < len; ++i) {
fees[i] = IAmbImplementation(superRegistry.getAmbAddress(ambIds_[i])).estimateFees(
dstChainId_, message_, extraData_[i]
);
totalFees += fees[i];
}
}
return (totalFees, fees);
}
/// @inheritdoc IPaymentHelper
function estimateAckCost(uint256 payloadId_) external view override returns (uint256 totalFees) {
EstimateAckCostVars memory v;
IBaseStateRegistry coreStateRegistry = IBaseStateRegistry(_getAddress(keccak256("CORE_STATE_REGISTRY")));
v.currPayloadId = coreStateRegistry.payloadsCount();
if (payloadId_ > v.currPayloadId) revert Error.INVALID_PAYLOAD_ID();
v.payloadHeader = coreStateRegistry.payloadHeader(payloadId_);
v.payloadBody = coreStateRegistry.payloadBody(payloadId_);
(, v.callbackType, v.isMulti,,, v.srcChainId) = DataLib.decodeTxInfo(v.payloadHeader);
/// if callback type is return then return 0
if (v.callbackType != 0) return 0;
if (v.isMulti == 1) {
InitMultiVaultData memory data = abi.decode(v.payloadBody, (InitMultiVaultData));
v.payloadBody = abi.encode(ReturnMultiData(v.currPayloadId, data.superformIds, data.amounts));
} else {
InitSingleVaultData memory data = abi.decode(v.payloadBody, (InitSingleVaultData));
v.payloadBody = abi.encode(ReturnSingleData(v.currPayloadId, data.superformId, data.amount));
}
v.ackAmbIds = coreStateRegistry.getMessageAMB(payloadId_);
v.message = abi.encode(AMBMessage(coreStateRegistry.payloadHeader(payloadId_), v.payloadBody));
return _estimateAMBFees(v.ackAmbIds, v.srcChainId, v.message);
}
/// @inheritdoc IPaymentHelper
function estimateAckCostDefault(
bool multi,
uint8[] memory ackAmbIds,
uint64 srcChainId
)
public
view
override
returns (uint256 totalFees)
{
bytes memory payloadBody;
if (multi) {
uint256 vaultLimitPerDst = superRegistry.getVaultLimitPerDestination(srcChainId);
uint256[] memory maxUints = new uint256[](vaultLimitPerDst);
for (uint256 i; i < vaultLimitPerDst; ++i) {
maxUints[i] = type(uint256).max;
}
payloadBody = abi.encode(ReturnMultiData(type(uint256).max, maxUints, maxUints));
} else {
payloadBody = abi.encode(ReturnSingleData(type(uint256).max, type(uint256).max, type(uint256).max));
}
return _estimateAMBFees(ackAmbIds, srcChainId, abi.encode(AMBMessage(type(uint256).max, payloadBody)));
}
/// @inheritdoc IPaymentHelper
function estimateAckCostDefaultNativeSource(
bool multi,
uint8[] memory ackAmbIds,
uint64 srcChainId
)
external
view
override
returns (uint256)
{
return _convertToSrcNativeAmount(srcChainId, estimateAckCostDefault(multi, ackAmbIds, srcChainId));
}
//////////////////////////////////////////////////////////////
// EXTERNAL WRITE FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @inheritdoc IPaymentHelper
function addRemoteChain(uint64 chainId_, PaymentHelperConfig calldata config_) public override onlyProtocolAdmin {
_addRemoteChain(chainId_, config_);
}
/// @inheritdoc IPaymentHelper
function addRemoteChains(
uint64[] calldata chainIds_,
PaymentHelperConfig[] calldata configs_
)
external
override
onlyProtocolAdmin
{
uint256 len = chainIds_.length;
if (len == 0) revert Error.ZERO_INPUT_VALUE();
if (len != configs_.length) revert Error.ARRAY_LENGTH_MISMATCH();
for (uint256 i; i < len; ++i) {
_addRemoteChain(chainIds_[i], configs_[i]);
}
}
/// @inheritdoc IPaymentHelper
function updateRemoteChain(
uint64 chainId_,
uint256 configType_,
bytes memory config_
)
external
override
onlyPaymentAdmin
{
_updateRemoteChain(chainId_, configType_, config_);
}
/// @inheritdoc IPaymentHelper
function batchUpdateRemoteChain(
uint64 chainId_,
uint256[] calldata configTypes_,
bytes[] calldata configs_
)
external
override
onlyPaymentAdmin
{
_batchUpdateRemoteChain(chainId_, configTypes_, configs_);
}
/// @inheritdoc IPaymentHelper
function batchUpdateRemoteChains(
uint64[] calldata chainIds_,
uint256[][] calldata configTypes_,
bytes[][] calldata configs_
)
external
override
onlyPaymentAdmin
{
uint256 len = chainIds_.length;
if (len == 0) revert Error.ZERO_INPUT_VALUE();
if (!(len == configTypes_.length && len == configs_.length)) revert Error.ARRAY_LENGTH_MISMATCH();
for (uint256 i; i < len; ++i) {
_batchUpdateRemoteChain(chainIds_[i], configTypes_[i], configs_[i]);
}
}
/// @inheritdoc IPaymentHelper
function updateRegisterAERC20Params(bytes memory extraDataForTransmuter_) external onlyPaymentAdmin {
extraDataForTransmuter = extraDataForTransmuter_;
}
//////////////////////////////////////////////////////////////
// INTERNAL FUNCTIONS //
//////////////////////////////////////////////////////////////
function _getOracleDecimals(AggregatorV3Interface oracle_) internal view returns (uint8) {
return oracle_.decimals();
}
/// @dev PROTOCOL_ADMIN can perform the configuration of a remote chain for the first time
function _addRemoteChain(uint64 chainId_, PaymentHelperConfig calldata config_) internal {
if (config_.nativeFeedOracle != address(0)) {
AggregatorV3Interface nativeFeedOracleContract = AggregatorV3Interface(config_.nativeFeedOracle);
uint256 oraclePrecision = _getOracleDecimals(nativeFeedOracleContract);
if (oraclePrecision < MIN_FEED_PRECISION || oraclePrecision > MAX_FEED_PRECISION) {
revert Error.CHAINLINK_UNSUPPORTED_DECIMAL();
}
nativeFeedOracle[chainId_] = nativeFeedOracleContract;
}
if (config_.gasPriceOracle != address(0)) {
AggregatorV3Interface gasPriceOracleContract = AggregatorV3Interface(config_.gasPriceOracle);
uint256 oraclePrecision = _getOracleDecimals(gasPriceOracleContract);
if (oraclePrecision < MIN_FEED_PRECISION || oraclePrecision > MAX_FEED_PRECISION) {
revert Error.CHAINLINK_UNSUPPORTED_DECIMAL();
}
gasPriceOracle[chainId_] = gasPriceOracleContract;
}
swapGasUsed[chainId_] = config_.swapGasUsed;
updateDepositGasUsed[chainId_] = config_.updateDepositGasUsed;
depositGasUsed[chainId_] = config_.depositGasUsed;
withdrawGasUsed[chainId_] = config_.withdrawGasUsed;
nativePrice[chainId_] = config_.defaultNativePrice;
gasPrice[chainId_] = config_.defaultGasPrice;
gasPerByte[chainId_] = config_.dstGasPerByte;
ackGasCost[chainId_] = config_.ackGasCost;
timelockCost[chainId_] = config_.timelockCost;
emergencyCost[chainId_] = config_.emergencyCost;
updateWithdrawGasUsed[chainId_] = config_.updateWithdrawGasUsed;
emit ChainConfigAdded(chainId_, config_);
}
/// @dev PAYMENT_ADMIN can update the configuration of a remote chain on a need basis
function _updateRemoteChain(uint64 chainId_, uint256 configType_, bytes memory config_) internal {
/// @dev Type 1: DST TOKEN PRICE FEED ORACLE
if (configType_ == 1) {
AggregatorV3Interface nativeFeedOracleContract = AggregatorV3Interface(abi.decode(config_, (address)));
/// @dev allows setting price feed to address(0), equivalent for resetting native price
if (address(nativeFeedOracleContract) != address(0)) {
uint256 oraclePrecision = _getOracleDecimals(nativeFeedOracleContract);
if (oraclePrecision < MIN_FEED_PRECISION || oraclePrecision > MAX_FEED_PRECISION) {
revert Error.CHAINLINK_UNSUPPORTED_DECIMAL();
}
}
nativeFeedOracle[chainId_] = nativeFeedOracleContract;
}
/// @dev Type 2: DST GAS PRICE ORACLE
if (configType_ == 2) {
AggregatorV3Interface gasPriceOracleContract = AggregatorV3Interface(abi.decode(config_, (address)));
/// @dev allows setting gas price to address(0), equivalent for resetting gas price
if (address(gasPriceOracleContract) != address(0)) {
uint256 oraclePrecision = _getOracleDecimals(gasPriceOracleContract);
if (oraclePrecision < MIN_FEED_PRECISION || oraclePrecision > MAX_FEED_PRECISION) {
revert Error.CHAINLINK_UNSUPPORTED_DECIMAL();
}
}
gasPriceOracle[chainId_] = gasPriceOracleContract;
}
/// @dev Type 3: SWAP GAS USED
if (configType_ == 3) {
swapGasUsed[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 4: PAYLOAD UPDATE DEPOSIT GAS COST PER TX
if (configType_ == 4) {
updateDepositGasUsed[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 5: DEPOSIT GAS COST PER TX
if (configType_ == 5) {
depositGasUsed[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 6: WITHDRAW GAS COST PER TX
if (configType_ == 6) {
withdrawGasUsed[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 7: DEFAULT NATIVE PRICE
if (configType_ == 7) {
nativePrice[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 8: DEFAULT GAS PRICE
if (configType_ == 8) {
gasPrice[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 9: GAS PRICE PER Byte of Message
if (configType_ == 9) {
gasPerByte[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 10: ACK GAS COST
if (configType_ == 10) {
ackGasCost[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 11: TIMELOCK PROCESSING COST
if (configType_ == 11) {
timelockCost[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 12: EMERGENCY PROCESSING COST
if (configType_ == 12) {
emergencyCost[chainId_] = abi.decode(config_, (uint256));
}
/// @dev Type 13: PAYLOAD UPDATE WITHDRAW GAS COST PER TX
if (configType_ == 13) {
updateWithdrawGasUsed[chainId_] = abi.decode(config_, (uint256));
}
emit ChainConfigUpdated(chainId_, configType_, config_);
}
/// @dev batch updates the configuration of a remote chain. Performed by PAYMENT_ADMIN
function _batchUpdateRemoteChain(
uint64 chainId_,
uint256[] calldata configTypes_,
bytes[] calldata configs_
)
internal
{
uint256 len = configTypes_.length;
if (len == 0) revert Error.ZERO_INPUT_VALUE();
if (len != configs_.length) revert Error.ARRAY_LENGTH_MISMATCH();
for (uint256 i; i < len; ++i) {
_updateRemoteChain(chainId_, configTypes_[i], configs_[i]);
}
}
/// @dev helps generate extra data per amb
function _generateExtraData(
uint64 dstChainId_,
uint8[] memory ambIds_,
bytes memory message_
)
internal
view
returns (bytes[] memory extraDataPerAMB)
{
AMBMessage memory ambIdEncodedMessage = abi.decode(message_, (AMBMessage));
ambIdEncodedMessage.params = abi.encode(ambIds_, ambIdEncodedMessage.params);
uint256 len = ambIds_.length;
uint256 gasReqPerByte = gasPerByte[dstChainId_];
uint256 totalDstGasReqInWei = abi.encode(ambIdEncodedMessage).length * gasReqPerByte;
/// @dev proof length is always of fixed length
uint256 totalDstGasReqInWeiForProof = PROOF_LENGTH * gasReqPerByte;
extraDataPerAMB = new bytes[](len);
for (uint256 i; i < len; ++i) {
uint256 gasReq = i != 0 ? totalDstGasReqInWeiForProof : totalDstGasReqInWei;
extraDataPerAMB[i] = IAmbImplementation(superRegistry.getAmbAddress(ambIds_[i])).generateExtraData(gasReq);
}
}
/// @dev helps estimate the cross-chain message costs
function _estimateAMBFees(
uint8[] memory ambIds_,
uint64 dstChainId_,
bytes memory message_
)
internal
view
returns (uint256 totalFees)
{
uint256 len = ambIds_.length;
bytes[] memory extraDataPerAMB = _generateExtraData(dstChainId_, ambIds_, message_);
AMBMessage memory ambIdEncodedMessage = abi.decode(message_, (AMBMessage));
ambIdEncodedMessage.params = abi.encode(ambIds_, ambIdEncodedMessage.params);
bytes memory proof_ = abi.encode(AMBMessage(MAX_UINT256, abi.encode(keccak256(message_))));
/// @dev just checks the estimate for sending message from src -> dst
/// @dev only ambIds_[0] = primary amb (rest of the ambs send only the proof)
if (CHAIN_ID != dstChainId_) {
for (uint256 i; i < len; ++i) {
uint256 tempFee = IAmbImplementation(superRegistry.getAmbAddress(ambIds_[i])).estimateFees(
dstChainId_, i != 0 ? proof_ : abi.encode(ambIdEncodedMessage), extraDataPerAMB[i]
);
totalFees += tempFee;
}
}
}
/// @dev helps estimate the cross-chain message costs
function _estimateAMBFeesReturnExtraData(
uint64 dstChainId_,
uint8[] calldata ambIds_,
bytes memory message_
)
internal
view
returns (uint256[] memory feeSplitUp, bytes[] memory extraDataPerAMB, uint256 totalFees)
{
AMBMessage memory ambIdEncodedMessage = abi.decode(message_, (AMBMessage));
ambIdEncodedMessage.params = abi.encode(ambIds_, ambIdEncodedMessage.params);
uint256 len = ambIds_.length;
extraDataPerAMB = _generateExtraData(dstChainId_, ambIds_, message_);
feeSplitUp = new uint256[](len);
bytes memory proof_ = abi.encode(AMBMessage(MAX_UINT256, abi.encode(keccak256(message_))));
/// @dev just checks the estimate for sending message from src -> dst
if (CHAIN_ID != dstChainId_) {
for (uint256 i; i < len; ++i) {
uint256 tempFee = IAmbImplementation(superRegistry.getAmbAddress(ambIds_[i])).estimateFees(
dstChainId_, i != 0 ? proof_ : abi.encode(ambIdEncodedMessage), extraDataPerAMB[i]
);
totalFees += tempFee;
feeSplitUp[i] = tempFee;
}
}
}
/// @dev helps estimate the liq amount involved in the tx
function _estimateLiqAmount(LiqRequest[] memory req_) internal pure returns (uint256 liqAmount) {
uint256 len = req_.length;
for (uint256 i; i < len; ++i) {
liqAmount += req_[i].nativeAmount;
}
}
/// @dev helps estimate the dst chain swap gas limit (if multi-tx is involved)
function _estimateSwapFees(
uint64 dstChainId_,
bool[] memory hasDstSwaps_
)
internal
view
returns (uint256 gasUsed)
{
uint256 totalSwaps;
if (CHAIN_ID == dstChainId_) {
return 0;
}
uint256 len = hasDstSwaps_.length;
for (uint256 i; i < len; ++i) {
/// @dev checks if hasDstSwap is true
if (hasDstSwaps_[i]) {
++totalSwaps;
}
}
if (totalSwaps == 0) {
return 0;
}
return totalSwaps * swapGasUsed[dstChainId_];
}
/// @dev helps estimate the dst chain update payload gas limit
function _estimateUpdateDepositCost(
uint64 dstChainId_,
uint256 vaultsCount_
)
internal
view
returns (uint256 gasUsed)
{
return vaultsCount_ * updateDepositGasUsed[dstChainId_];
}
/// @dev helps estimate the dst chain update payload gas limit
function _estimateUpdateWithdrawCost(
uint64 dstChainId_,
LiqRequest[] memory liqRequests_
)
internal
view
returns (uint256 gasUsed)
{
uint256 len = liqRequests_.length;
for (uint256 i; i < len; i++) {
/// @dev liqRequests[i].token on withdraws is the desired token
/// @dev if token is address(0) -> user wants settlement without any liq data
/// @dev this means that if no txData is present and token is different than address(0) an update is
/// required in destination
if (liqRequests_[i].txData.length == 0 && liqRequests_[i].token != address(0)) {
gasUsed += updateWithdrawGasUsed[dstChainId_];
}
}
}
/// @dev helps estimate the dst chain processing cost including the dst->src message cost
/// @dev assumes that withdrawals optimisically succeed
function _estimateDstExecutionCost(
bool isDeposit_,
uint64 dstChainId_,
uint256 vaultsCount_
)
internal
view
returns (uint256 gasUsed)
{
uint256 executionGasPerVault = isDeposit_ ? depositGasUsed[dstChainId_] : withdrawGasUsed[dstChainId_];
gasUsed = executionGasPerVault * vaultsCount_;
}
/// @dev helps estimate the src chain processing fee
function _estimateAckProcessingCost(uint256 vaultsCount_) internal view returns (uint256 nativeFee) {
uint256 gasCost = vaultsCount_ * ackGasCost[CHAIN_ID];
return gasCost * _getGasPrice(CHAIN_ID);
}
/// @dev generates the amb message for single vault data
function _generateSingleVaultMessage(SingleVaultSFData memory sfData_)
internal
view
returns (bytes memory message_)
{
bytes memory ambData = abi.encode(
InitSingleVaultData(
_getNextPayloadId(),
sfData_.superformId,
sfData_.amount,
sfData_.outputAmount,
sfData_.maxSlippage,
sfData_.liqRequest,
sfData_.hasDstSwap,
sfData_.retain4626,
sfData_.receiverAddress,
sfData_.extraFormData
)
);
message_ = abi.encode(AMBMessage(MAX_UINT256, ambData));
}
/// @dev generates the amb message for multi vault data
function _generateMultiVaultMessage(MultiVaultSFData memory sfData_)
internal
view
returns (bytes memory message_)
{
bytes memory ambData = abi.encode(
InitMultiVaultData(
_getNextPayloadId(),
sfData_.superformIds,
sfData_.amounts,
sfData_.outputAmounts,
sfData_.maxSlippages,
sfData_.liqRequests,
sfData_.hasDstSwaps,
sfData_.retain4626s,
sfData_.receiverAddress,
sfData_.extraFormData
)
);
message_ = abi.encode(AMBMessage(MAX_UINT256, ambData));
}
/// @dev helps convert the dst gas fee into src chain native fee
/// @dev https://docs.soliditylang.org/en/v0.8.4/units-and-global-variables.html#ether-units
/// @dev all native tokens should be 18 decimals across all EVMs
function _convertToNativeFee(
uint64 dstChainId_,
uint256 dstGas_,
bool xChain_
)
internal
view
returns (uint256 nativeFee)
{
/// @dev gas fee * gas price (to get the gas amounts in dst chain's native token)
/// @dev gas price is 9 decimal (in gwei)
/// @dev assumption: all evm native tokens are 18 decimals
uint256 dstNativeFee = dstGas_ * _getGasPrice(dstChainId_);
if (dstNativeFee == 0) {
return 0;
}
if (!xChain_) {
return dstNativeFee;
}
/// @dev converts the gas to pay in terms of native token to usd value
/// @dev native token price is 8 decimal
uint256 dstUsdValue = dstNativeFee * _getNativeTokenPrice(dstChainId_); // native token price - 8 decimal
if (dstUsdValue == 0) {
return 0;
}
/// @dev converts the usd value to source chain's native token
/// @dev native token price is 8 decimal which cancels the 8 decimal multiplied in previous step
uint256 nativeTokenPrice = _getNativeTokenPrice(CHAIN_ID); // native token price - 8 decimal
if (nativeTokenPrice == 0) revert Error.INVALID_NATIVE_TOKEN_PRICE();
nativeFee = (dstUsdValue) / nativeTokenPrice;
}
/// @dev helps convert a native token of one chain to another
/// @dev https://docs.soliditylang.org/en/v0.8.4/units-and-global-variables.html#ether-units
/// @dev all native tokens should be 18 decimals across all EVMs
function _convertToSrcNativeAmount(
uint64 srcChainId_,
uint256 dstAmount_
)
internal
view
returns (uint256 nativeFee)
{
if (dstAmount_ == 0) {
return 0;
}
/// @dev converts the native token value to usd value
/// @dev dstAmount_ is 18 decimal
/// @dev native token price is 8 decimal
uint256 dstUsdValue = dstAmount_ * _getNativeTokenPrice(CHAIN_ID);
if (dstUsdValue == 0) {
return 0;
}
/// @dev converts the usd value to source chain's native token
/// @dev native token price is 8 decimal which cancels the 8 decimal multiplied in previous step
uint256 nativeTokenPrice = _getNativeTokenPrice(srcChainId_);
if (nativeTokenPrice == 0) revert Error.INVALID_NATIVE_TOKEN_PRICE();
nativeFee = dstUsdValue / nativeTokenPrice;
}
/// @dev helps generate the new payload id
/// @dev next payload id = current payload id + 1
function _getNextPayloadId() internal view returns (uint256 nextPayloadId) {
nextPayloadId = ReadOnlyBaseRegistry(_getAddress(keccak256("CORE_STATE_REGISTRY"))).payloadsCount();
++nextPayloadId;
}
/// @dev helps return the current gas price of different networks
/// @return native token price
function _getGasPrice(uint64 chainId_) internal view returns (uint256) {
address oracleAddr = address(gasPriceOracle[chainId_]);
if (oracleAddr != address(0)) {
try AggregatorV3Interface(oracleAddr).latestRoundData() returns (
uint80, int256 value, uint256, uint256 updatedAt, uint80
) {
if (value <= 0) revert Error.CHAINLINK_MALFUNCTION();
if (updatedAt == 0) revert Error.CHAINLINK_INCOMPLETE_ROUND();
uint256 oraclePrecision = _getOracleDecimals(AggregatorV3Interface(oracleAddr));
if (oraclePrecision == MIN_FEED_PRECISION) return uint256(value);
else return uint256(value) / (10 ** (oraclePrecision - MIN_FEED_PRECISION));
} catch {
/// @dev do nothing and return the default price at the end of the function
}
}
return gasPrice[chainId_];
}
/// @dev helps return the dst chain token price of different networks
/// @return native token price
function _getNativeTokenPrice(uint64 chainId_) internal view returns (uint256) {
address oracleAddr = address(nativeFeedOracle[chainId_]);
if (oracleAddr != address(0)) {
try AggregatorV3Interface(oracleAddr).latestRoundData() returns (
uint80, int256 dstTokenPrice, uint256, uint256 updatedAt, uint80
) {
if (dstTokenPrice <= 0) revert Error.CHAINLINK_MALFUNCTION();
if (updatedAt == 0) revert Error.CHAINLINK_INCOMPLETE_ROUND();
uint256 oraclePrecision = _getOracleDecimals(AggregatorV3Interface(oracleAddr));
if (oraclePrecision == MIN_FEED_PRECISION) return uint256(dstTokenPrice);
else return uint256(dstTokenPrice) / (10 ** (oraclePrecision - MIN_FEED_PRECISION));
} catch {
/// @dev do nothing and return the default price at the end of the function
}
}
return nativePrice[chainId_];
}
/// @dev returns the address from super registry
function _getAddress(bytes32 id_) internal view returns (address) {
return superRegistry.getAddress(id_);
}
/// @dev calculates different cost amounts involved in the tx
function _calculateAmounts(CalculateAmountsReq memory req_)
internal
view
returns (uint256 liqAmount, uint256 srcAmount, uint256 dstOrSameChainAmt)
{
LocalEstimateVars memory v;
bool xChain = req_.dstChainIds[req_.i] != CHAIN_ID;
/// @dev in xChain this is gas on the destination chain and in !xChain this is gas on the same chain
v.totalGas = 0;
bool multiVaults = req_.superformsData.length > 0;
bytes memory message = multiVaults
? _generateMultiVaultMessage(req_.superformsData[req_.i])
: _generateSingleVaultMessage(req_.superformData[req_.i]);
/// @dev step 1: estimate amb costs
v.ambFees = xChain ? _estimateAMBFees(req_.ambIds, req_.dstChainIds[req_.i], message) : 0;
v.superformIdsLen = multiVaults ? req_.superformsData[req_.i].superformIds.length : 1;
srcAmount += v.ambFees;
LiqRequest[] memory liqRequests = multiVaults
? req_.superformsData[req_.i].liqRequests
: req_.superformData[req_.i].liqRequest.castLiqRequestToArray();
if (req_.isDeposit) {
/// @dev step 2: estimate liq amount
liqAmount += _estimateLiqAmount(liqRequests);
if (xChain) {
/// @dev step 3: estimate update cost (only for deposit)
v.totalGas += _estimateUpdateDepositCost(req_.dstChainIds[req_.i], v.superformIdsLen);
uint256 ackLen;
if (multiVaults) {
for (uint256 j; j < v.superformIdsLen; ++j) {
if (!req_.superformsData[req_.i].retain4626s[j]) ++ackLen;
}
} else {
if (!req_.superformData[req_.i].retain4626) ++ackLen;
}
/// @dev step 4: estimation processing cost of acknowledgement on source
srcAmount += _estimateAckProcessingCost(ackLen);
bool[] memory hasDstSwaps = multiVaults
? req_.superformsData[req_.i].hasDstSwaps
: req_.superformData[req_.i].hasDstSwap.castBoolToArray();
/// @dev step 5: estimate dst swap cost if it exists
v.totalGas += _estimateSwapFees(req_.dstChainIds[req_.i], hasDstSwaps);
}
} else {
if (multiVaults) {
/// @dev step 6: estimate if timelock form processing costs are involved
for (uint256 j; j < v.superformIdsLen; ++j) {
v.totalGas += _calculateTotalDstGasTimelockEmergency(
req_.superformsData[req_.i].superformIds[j], req_.dstChainIds[req_.i], req_.factory
);
}
} else {
v.totalGas += _calculateTotalDstGasTimelockEmergency(
req_.superformData[req_.i].superformId, req_.dstChainIds[req_.i], req_.factory
);
}
if (xChain) {
/// @dev step 7: estimate update withdraw cost if no txData is present
v.totalGas += _estimateUpdateWithdrawCost(req_.dstChainIds[req_.i], liqRequests);
}
}
/// @dev step 7: estimate execution costs in destination including sending acknowledgement to source
/// @dev ensure that acknowledgement costs from dst to src are not double counted
v.totalGas +=
xChain ? _estimateDstExecutionCost(req_.isDeposit, req_.dstChainIds[req_.i], v.superformIdsLen) : 0;
/// @dev step 8: convert all dst/same chain gas estimates to src chain estimate (withdraw / deposit)
dstOrSameChainAmt += _convertToNativeFee(req_.dstChainIds[req_.i], v.totalGas, xChain);
}
/// @dev calculates the srcAmount cost for single direct withdrawal
function _calculateTotalDstGasTimelockEmergency(
uint256 superformId_,
uint64 dstChainId_,
ISuperformFactory factory_
)
internal
view
returns (uint256 totalDstGas)
{
(, uint32 formId,) = superformId_.getSuperform();
bool paused = factory_.isFormImplementationPaused(formId);
if (!paused && formId == TIMELOCK_FORM_ID) {
totalDstGas += timelockCost[dstChainId_];
} else if (paused) {
totalDstGas += emergencyCost[dstChainId_];
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
import {
MultiDstMultiVaultStateReq,
MultiDstSingleVaultStateReq,
SingleXChainMultiVaultStateReq,
SingleXChainSingleVaultStateReq,
SingleDirectSingleVaultStateReq,
SingleDirectMultiVaultStateReq
} from "src/types/DataTypes.sol";
/// @title IPaymentHelper
/// @dev Interface for PaymentHelper
/// @author ZeroPoint Labs
interface IPaymentHelperV2 {
//////////////////////////////////////////////////////////////
// STRUCTS //
//////////////////////////////////////////////////////////////
/// @param nativeFeedOracle is the native price feed oracle
/// @param gasPriceOracle is the gas price oracle
/// @param swapGasUsed is the swap gas params
/// @param updateDepositGasUsed is the update gas params
/// @param depositGasUsed is the deposit per vault gas on the chain
/// @param withdrawGasUsed is the withdraw per vault gas on the chain
/// @param defaultNativePrice is the native price on the specified chain
/// @param defaultGasPrice is the gas price on the specified chain
/// @param dstGasPerByte is the gas per size of data on the specified chain
/// @param ackGasCost is the gas cost for sending and processing from dst->src
/// @param timelockCost is the extra cost for processing timelocked payloads
/// @param emergencyCost is the extra cost for processing emergency payloads
/// @param updateWithdrawGasUsed is the update gas params for withdraws
struct PaymentHelperConfig {
address nativeFeedOracle;
address gasPriceOracle;
uint256 swapGasUsed;
uint256 updateDepositGasUsed;
uint256 depositGasUsed;
uint256 withdrawGasUsed;
uint256 defaultNativePrice;
uint256 defaultGasPrice;
uint256 dstGasPerByte;
uint256 ackGasCost;
uint256 timelockCost;
uint256 emergencyCost;
uint256 updateWithdrawGasUsed;
}
//////////////////////////////////////////////////////////////
// EVENTS //
//////////////////////////////////////////////////////////////
event ChainConfigUpdated(uint64 indexed chainId_, uint256 indexed configType_, bytes config_);
event ChainConfigAdded(uint64 chainId_, PaymentHelperConfig config_);
//////////////////////////////////////////////////////////////
// EXTERNAL VIEW FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev returns the amb overrides & gas to be used
/// @param dstChainId_ is the unique dst chain identifier
/// @param ambIds_ is the identifiers of arbitrary message bridges to be used
/// @param message_ is the encoded cross-chain payload
function calculateAMBData(
uint64 dstChainId_,
uint8[] calldata ambIds_,
bytes memory message_
)
external
view
returns (uint256 totalFees, bytes memory extraData);
/// @dev returns the amb overrides & gas to be used
/// @return extraData the amb specific override information
function getRegisterTransmuterAMBData() external view returns (bytes memory extraData);
/// @dev estimates the gas fees for multiple destination and multi vault operation
/// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter
/// @param isDeposit_ indicated if the datatype will be used for a deposit
/// @return liqAmount is the amount of liquidity to be provided in native tokens
/// @return srcAmount is the gas expense on source chain in native tokens
/// @return dstAmount is the gas expense on dst chain in terms of src chain's native tokens
/// @return totalAmount is the native_tokens to be sent along the transaction
function estimateMultiDstMultiVault(
MultiDstMultiVaultStateReq calldata req_,
bool isDeposit_
)
external
view
returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount);
/// @dev estimates the gas fees for multiple destination and single vault operation
/// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter
/// @param isDeposit_ indicated if the datatype will be used for a deposit
/// @return liqAmount is the amount of liquidity to be provided in native tokens
/// @return srcAmount is the gas expense on source chain in native tokens
/// @return dstAmount is the gas expense on dst chain in terms of src chain's native tokens
/// @return totalAmount is the native_tokens to be sent along the transaction
function estimateMultiDstSingleVault(
MultiDstSingleVaultStateReq calldata req_,
bool isDeposit_
)
external
view
returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount);
/// @dev estimates the gas fees for single destination and multi vault operation
/// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter
/// @param isDeposit_ indicated if the datatype will be used for a deposit
/// @return liqAmount is the amount of liquidity to be provided in native tokens
/// @return srcAmount is the gas expense on source chain in native tokens
/// @return dstAmount is the gas expense on dst chain in terms of src chain's native tokens
/// @return totalAmount is the native_tokens to be sent along the transaction
function estimateSingleXChainMultiVault(
SingleXChainMultiVaultStateReq calldata req_,
bool isDeposit_
)
external
view
returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount);
/// @dev estimates the gas fees for single destination and single vault operation
/// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter
/// @param isDeposit_ indicated if the datatype will be used for a deposit
/// @return liqAmount is the amount of liquidity to be provided in native tokens
/// @return srcAmount is the gas expense on source chain in native tokens
/// @return dstAmount is the gas expense on dst chain in terms of src chain's native tokens
/// @return totalAmount is the native_tokens to be sent along the transaction
function estimateSingleXChainSingleVault(
SingleXChainSingleVaultStateReq calldata req_,
bool isDeposit_
)
external
view
returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount);
/// @dev estimates the gas fees for same chain operation
/// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter
/// @param isDeposit_ indicated if the datatype will be used for a deposit
/// @return liqAmount is the amount of liquidity to be provided in native tokens
/// @return srcAmount is the gas expense on source chain in native tokens
/// @return totalAmount is the native_tokens to be sent along the transaction
function estimateSingleDirectSingleVault(
SingleDirectSingleVaultStateReq calldata req_,
bool isDeposit_
)
external
view
returns (uint256 liqAmount, uint256 srcAmount, uint256 totalAmount);
/// @dev estimates the gas fees for multiple same chain operation
/// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter
/// @param isDeposit_ indicated if the datatype will be used for a deposit
/// @return liqAmount is the amount of liquidity to be provided in native tokens
/// @return srcAmount is the gas expense on source chain in native tokens
/// @return totalAmount is the native_tokens to be sent along the transaction
function estimateSingleDirectMultiVault(
SingleDirectMultiVaultStateReq calldata req_,
bool isDeposit_
)
external
view
returns (uint256 liqAmount, uint256 srcAmount, uint256 totalAmount);
/// @dev returns the gas fees estimation in native tokens if we send message through a combination of AMBs
/// @param ambIds_ is the identifier of different AMBs
/// @param dstChainId_ is the identifier of the destination chain
/// @param message_ is the cross-chain message
/// @param extraData_ is any amb-specific information
/// @return ambFees is the native_tokens to be sent along the transaction for all the ambIds_ included
function estimateAMBFees(
uint8[] memory ambIds_,
uint64 dstChainId_,
bytes memory message_,
bytes[] memory extraData_
)
external
view
returns (uint256 ambFees, uint256[] memory);
/// @dev helps estimate the acknowledgement costs for amb processing
/// @param payloadId_ is the payload identifier
/// @return totalFees is the total fees to be paid in native tokens
function estimateAckCost(uint256 payloadId_) external view returns (uint256 totalFees);
/// @dev helps estimate the acknowledgement costs for amb processing without relying on payloadId (using max values)
/// @param multi is the flag indicating if the payload is multi or single
/// @param ackAmbIds is the list of ambIds to be used for acknowledgement
/// @param srcChainId is the source chain identifier
/// @return totalFees is the total fees to be paid in native tokens
function estimateAckCostDefault(
bool multi,
uint8[] memory ackAmbIds,
uint64 srcChainId
)
external
view
returns (uint256 totalFees);
/// @dev helps estimate the acknowledgement costs for amb processing without relying on payloadId (using max values)
/// with source native amounts
/// @param multi is the flag indicating if the payload is multi or single
/// @param ackAmbIds is the list of ambIds to be used for acknowledgement
/// @param srcChainId is the source chain identifier
/// @return totalFees is the total fees to be paid in native tokens
function estimateAckCostDefaultNativeSource(
bool multi,
uint8[] memory ackAmbIds,
uint64 srcChainId
)
external
view
returns (uint256 totalFees);
//////////////////////////////////////////////////////////////
// EXTERNAL WRITE FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev admin can configure a remote chain for the first time
/// @param chainId_ is the identifier of new chain id
/// @param config_ is the chain config
function addRemoteChain(uint64 chainId_, PaymentHelperConfig calldata config_) external;
/// @dev admin can configure various remote chain for the first time in a single call
/// @param chainIds_ is the identifier of new chain id
/// @param configs_ is the chain config
function addRemoteChains(uint64[] calldata chainIds_, PaymentHelperConfig[] calldata configs_) external;
/// @dev admin can specifically configure/update certain configuration of a remote chain
/// @param chainId_ is the remote chain's identifier
/// @param configType_ is the type of config from 1 -> 6
/// @param config_ is the encoded new configuration
function updateRemoteChain(uint64 chainId_, uint256 configType_, bytes memory config_) external;
/// @dev admin can specifically configure/update certain configurations on a single remote chain
/// @param chainId_ are the remote chain's identifier
/// @param configTypes_ are the type of config from 1 -> 6 for the given chain
/// @param configs_ are the encoded new configurations for each config type for the given chain
function batchUpdateRemoteChain(
uint64 chainId_,
uint256[] calldata configTypes_,
bytes[] calldata configs_
)
external;
/// @dev admin can specifically configure/update certain configurations on various remote chains at the same time
/// @param chainIds_ are the remote chain's identifier
/// @param configTypes_ are the type of config from 1 -> 6 for each chain
/// @param configs_ are the encoded new configurations for each config type and chains
function batchUpdateRemoteChains(
uint64[] calldata chainIds_,
uint256[][] calldata configTypes_,
bytes[][] calldata configs_
)
external;
/// @dev admin updates config for register transmuter amb params
/// @param extraDataForTransmuter_ is the broadcast extra data
function updateRegisterAERC20Params(bytes memory extraDataForTransmuter_) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
import { IAccessControl } from "openzeppelin-contracts/contracts/access/IAccessControl.sol";
/// @title ISuperRBAC
/// @dev Interface for SuperRBAC
/// @author Zeropoint Labs
interface ISuperRBAC is IAccessControl {
//////////////////////////////////////////////////////////////
// STRUCTS //
//////////////////////////////////////////////////////////////
struct InitialRoleSetup {
address admin;
address emergencyAdmin;
address paymentAdmin;
address csrProcessor;
address tlProcessor;
address brProcessor;
address csrUpdater;
address srcVaaRelayer;
address dstSwapper;
address csrRescuer;
address csrDisputer;
}
//////////////////////////////////////////////////////////////
// EVENTS //
//////////////////////////////////////////////////////////////
/// @dev is emitted when superRegistry is set
event SuperRegistrySet(address indexed superRegistry);
/// @dev is emitted when an admin is set for a role
event RoleAdminSet(bytes32 role, bytes32 adminRole);
//////////////////////////////////////////////////////////////
// EXTERNAL VIEW FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev returns the id of the protocol admin role
function PROTOCOL_ADMIN_ROLE() external view returns (bytes32);
/// @dev returns the id of the emergency admin role
function EMERGENCY_ADMIN_ROLE() external view returns (bytes32);
/// @dev returns the id of the payment admin role
function PAYMENT_ADMIN_ROLE() external view returns (bytes32);
/// @dev returns the id of the broadcaster role
function BROADCASTER_ROLE() external view returns (bytes32);
/// @dev returns the id of the core state registry processor role
function CORE_STATE_REGISTRY_PROCESSOR_ROLE() external view returns (bytes32);
/// @dev returns the id of the timelock state registry processor role
function TIMELOCK_STATE_REGISTRY_PROCESSOR_ROLE() external view returns (bytes32);
/// @dev returns the id of the broadcast state registry processor role
function BROADCAST_STATE_REGISTRY_PROCESSOR_ROLE() external view returns (bytes32);
/// @dev returns the id of the core state registry updater role
function CORE_STATE_REGISTRY_UPDATER_ROLE() external view returns (bytes32);
/// @dev returns the id of the dst swapper role
function DST_SWAPPER_ROLE() external view returns (bytes32);
/// @dev returns the id of the core state registry rescuer role
function CORE_STATE_REGISTRY_RESCUER_ROLE() external view returns (bytes32);
/// @dev returns the id of the core state registry rescue disputer role
function CORE_STATE_REGISTRY_DISPUTER_ROLE() external view returns (bytes32);
/// @dev returns the id of wormhole vaa relayer role
function WORMHOLE_VAA_RELAYER_ROLE() external view returns (bytes32);
/// @dev returns whether the given address has the protocol admin role
/// @param admin_ the address to check
function hasProtocolAdminRole(address admin_) external view returns (bool);
/// @dev returns whether the given address has the emergency admin role
/// @param admin_ the address to check
function hasEmergencyAdminRole(address admin_) external view returns (bool);
//////////////////////////////////////////////////////////////
// EXTERNAL WRITE FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev updates the super registry address
function setSuperRegistry(address superRegistry_) external;
/// @dev configures a new role in superForm
/// @param role_ the role to set
/// @param adminRole_ the admin role to set as admin
function setRoleAdmin(bytes32 role_, bytes32 adminRole_) external;
/// @dev revokes the role_ from superRegistryAddressId_ on all chains
/// @param role_ the role to revoke
/// @param extraData_ amb config if broadcasting is required
/// @param superRegistryAddressId_ the super registry address id
function revokeRoleSuperBroadcast(
bytes32 role_,
bytes memory extraData_,
bytes32 superRegistryAddressId_
)
external
payable;
/// @dev allows sync of global roles from different chains using broadcast registry
/// @notice may not work for all roles
function stateSyncBroadcast(bytes memory data_) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
/// @title ISuperRegistry
/// @dev Interface for SuperRegistry
/// @author Zeropoint Labs
interface ISuperRegistry {
//////////////////////////////////////////////////////////////
// EVENTS //
//////////////////////////////////////////////////////////////
/// @dev emitted when permit2 is set.
event SetPermit2(address indexed permit2);
/// @dev is emitted when an address is set.
event AddressUpdated(
bytes32 indexed protocolAddressId, uint64 indexed chainId, address indexed oldAddress, address newAddress
);
/// @dev is emitted when a new token bridge is configured.
event SetBridgeAddress(uint256 indexed bridgeId, address indexed bridgeAddress);
/// @dev is emitted when a new bridge validator is configured.
event SetBridgeValidator(uint256 indexed bridgeId, address indexed bridgeValidator);
/// @dev is emitted when a new amb is configured.
event SetAmbAddress(uint8 indexed ambId_, address indexed ambAddress_, bool indexed isBroadcastAMB_);
/// @dev is emitted when a new state registry is configured.
event SetStateRegistryAddress(uint8 indexed registryId_, address indexed registryAddress_);
/// @dev is emitted when a new delay is configured.
event SetDelay(uint256 indexed oldDelay_, uint256 indexed newDelay_);
/// @dev is emitted when a new vault limit is configured
event SetVaultLimitPerDestination(uint64 indexed chainId_, uint256 indexed vaultLimit_);
//////////////////////////////////////////////////////////////
// EXTERNAL VIEW FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev gets the deposit rescue delay
function delay() external view returns (uint256);
/// @dev returns the permit2 address
function PERMIT2() external view returns (address);
/// @dev returns the id of the superform router module
function SUPERFORM_ROUTER() external view returns (bytes32);
/// @dev returns the id of the superform factory module
function SUPERFORM_FACTORY() external view returns (bytes32);
/// @dev returns the id of the superform paymaster contract
function PAYMASTER() external view returns (bytes32);
/// @dev returns the id of the superform payload helper contract
function PAYMENT_HELPER() external view returns (bytes32);
/// @dev returns the id of the core state registry module
function CORE_STATE_REGISTRY() external view returns (bytes32);
/// @dev returns the id of the timelock form state registry module
function TIMELOCK_STATE_REGISTRY() external view returns (bytes32);
/// @dev returns the id of the broadcast state registry module
function BROADCAST_REGISTRY() external view returns (bytes32);
/// @dev returns the id of the super positions module
function SUPER_POSITIONS() external view returns (bytes32);
/// @dev returns the id of the super rbac module
function SUPER_RBAC() external view returns (bytes32);
/// @dev returns the id of the payload helper module
function PAYLOAD_HELPER() external view returns (bytes32);
/// @dev returns the id of the dst swapper keeper
function DST_SWAPPER() external view returns (bytes32);
/// @dev returns the id of the emergency queue
function EMERGENCY_QUEUE() external view returns (bytes32);
/// @dev returns the id of the superform receiver
function SUPERFORM_RECEIVER() external view returns (bytes32);
/// @dev returns the id of the payment admin keeper
function PAYMENT_ADMIN() external view returns (bytes32);
/// @dev returns the id of the core state registry processor keeper
function CORE_REGISTRY_PROCESSOR() external view returns (bytes32);
/// @dev returns the id of the broadcast registry processor keeper
function BROADCAST_REGISTRY_PROCESSOR() external view returns (bytes32);
/// @dev returns the id of the timelock form state registry processor keeper
function TIMELOCK_REGISTRY_PROCESSOR() external view returns (bytes32);
/// @dev returns the id of the core state registry updater keeper
function CORE_REGISTRY_UPDATER() external view returns (bytes32);
/// @dev returns the id of the core state registry updater keeper
function CORE_REGISTRY_RESCUER() external view returns (bytes32);
/// @dev returns the id of the core state registry updater keeper
function CORE_REGISTRY_DISPUTER() external view returns (bytes32);
/// @dev returns the id of the core state registry updater keeper
function DST_SWAPPER_PROCESSOR() external view returns (bytes32);
/// @dev gets the address of a contract on current chain
/// @param id_ is the id of the contract
function getAddress(bytes32 id_) external view returns (address);
/// @dev gets the address of a contract on a target chain
/// @param id_ is the id of the contract
/// @param chainId_ is the chain id of that chain
function getAddressByChainId(bytes32 id_, uint64 chainId_) external view returns (address);
/// @dev gets the address of a bridge
/// @param bridgeId_ is the id of a bridge
/// @return bridgeAddress_ is the address of the form
function getBridgeAddress(uint8 bridgeId_) external view returns (address bridgeAddress_);
/// @dev gets the address of a bridge validator
/// @param bridgeId_ is the id of a bridge
/// @return bridgeValidator_ is the address of the form
function getBridgeValidator(uint8 bridgeId_) external view returns (address bridgeValidator_);
/// @dev gets the address of a amb
/// @param ambId_ is the id of a bridge
/// @return ambAddress_ is the address of the form
function getAmbAddress(uint8 ambId_) external view returns (address ambAddress_);
/// @dev gets the id of the amb
/// @param ambAddress_ is the address of an amb
/// @return ambId_ is the identifier of an amb
function getAmbId(address ambAddress_) external view returns (uint8 ambId_);
/// @dev gets the address of the registry
/// @param registryId_ is the id of the state registry
/// @return registryAddress_ is the address of the state registry
function getStateRegistry(uint8 registryId_) external view returns (address registryAddress_);
/// @dev gets the id of the registry
/// @notice reverts if the id is not found
/// @param registryAddress_ is the address of the state registry
/// @return registryId_ is the id of the state registry
function getStateRegistryId(address registryAddress_) external view returns (uint8 registryId_);
/// @dev gets the safe vault limit
/// @param chainId_ is the id of the remote chain
/// @return vaultLimitPerDestination_ is the safe number of vaults to deposit
/// without hitting out of gas error
function getVaultLimitPerDestination(uint64 chainId_) external view returns (uint256 vaultLimitPerDestination_);
/// @dev helps validate if an address is a valid state registry
/// @param registryAddress_ is the address of the state registry
/// @return valid_ a flag indicating if its valid.
function isValidStateRegistry(address registryAddress_) external view returns (bool valid_);
/// @dev helps validate if an address is a valid amb implementation
/// @param ambAddress_ is the address of the amb implementation
/// @return valid_ a flag indicating if its valid.
function isValidAmbImpl(address ambAddress_) external view returns (bool valid_);
/// @dev helps validate if an address is a valid broadcast amb implementation
/// @param ambAddress_ is the address of the broadcast amb implementation
/// @return valid_ a flag indicating if its valid.
function isValidBroadcastAmbImpl(address ambAddress_) external view returns (bool valid_);
//////////////////////////////////////////////////////////////
// EXTERNAL WRITE FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev sets the deposit rescue delay
/// @param delay_ the delay in seconds before the deposit rescue can be finalized
function setDelay(uint256 delay_) external;
/// @dev sets the permit2 address
/// @param permit2_ the address of the permit2 contract
function setPermit2(address permit2_) external;
/// @dev sets the safe vault limit
/// @param chainId_ is the remote chain identifier
/// @param vaultLimit_ is the max limit of vaults per transaction
function setVaultLimitPerDestination(uint64 chainId_, uint256 vaultLimit_) external;
/// @dev sets new addresses on specific chains.
/// @param ids_ are the identifiers of the address on that chain
/// @param newAddresses_ are the new addresses on that chain
/// @param chainIds_ are the chain ids of that chain
function batchSetAddress(
bytes32[] calldata ids_,
address[] calldata newAddresses_,
uint64[] calldata chainIds_
)
external;
/// @dev sets a new address on a specific chain.
/// @param id_ the identifier of the address on that chain
/// @param newAddress_ the new address on that chain
/// @param chainId_ the chain id of that chain
function setAddress(bytes32 id_, address newAddress_, uint64 chainId_) external;
/// @dev allows admin to set the bridge address for an bridge id.
/// @notice this function operates in an APPEND-ONLY fashion.
/// @param bridgeId_ represents the bridge unique identifier.
/// @param bridgeAddress_ represents the bridge address.
/// @param bridgeValidator_ represents the bridge validator address.
function setBridgeAddresses(
uint8[] memory bridgeId_,
address[] memory bridgeAddress_,
address[] memory bridgeValidator_
)
external;
/// @dev allows admin to set the amb address for an amb id.
/// @notice this function operates in an APPEND-ONLY fashion.
/// @param ambId_ represents the bridge unique identifier.
/// @param ambAddress_ represents the bridge address.
/// @param isBroadcastAMB_ represents whether the amb implementation supports broadcasting
function setAmbAddress(
uint8[] memory ambId_,
address[] memory ambAddress_,
bool[] memory isBroadcastAMB_
)
external;
/// @dev allows admin to set the state registry address for an state registry id.
/// @notice this function operates in an APPEND-ONLY fashion.
/// @param registryId_ represents the state registry's unique identifier.
/// @param registryAddress_ represents the state registry's address.
function setStateRegistryAddress(uint8[] memory registryId_, address[] memory registryAddress_) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
/// @title ISuperformFactory
/// @dev Interface for SuperformFactory
/// @author ZeroPoint Labs
interface ISuperformFactory {
//////////////////////////////////////////////////////////////
// CONSTANTS //
//////////////////////////////////////////////////////////////
enum PauseStatus {
NON_PAUSED,
PAUSED
}
//////////////////////////////////////////////////////////////
// EVENTS //
//////////////////////////////////////////////////////////////
/// @dev emitted when a new formImplementation is entered into the factory
/// @param formImplementation is the address of the new form implementation
/// @param formImplementationId is the id of the formImplementation
/// @param formStateRegistryId is any additional state registry id of the formImplementation
event FormImplementationAdded(
address indexed formImplementation, uint256 indexed formImplementationId, uint8 indexed formStateRegistryId
);
/// @dev emitted when a new Superform is created
/// @param formImplementationId is the id of the form implementation
/// @param vault is the address of the vault
/// @param superformId is the id of the superform
/// @param superform is the address of the superform
event SuperformCreated(
uint256 indexed formImplementationId, address indexed vault, uint256 indexed superformId, address superform
);
/// @dev emitted when a new SuperRegistry is set
/// @param superRegistry is the address of the super registry
event SuperRegistrySet(address indexed superRegistry);
/// @dev emitted when a form implementation is paused
/// @param formImplementationId is the id of the form implementation
/// @param paused is the new paused status
event FormImplementationPaused(uint256 indexed formImplementationId, PauseStatus indexed paused);
//////////////////////////////////////////////////////////////
// EXTERNAL VIEW FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev returns the number of forms
/// @return forms_ is the number of forms
function getFormCount() external view returns (uint256 forms_);
/// @dev returns the number of superforms
/// @return superforms_ is the number of superforms
function getSuperformCount() external view returns (uint256 superforms_);
/// @dev returns the address of a form implementation
/// @param formImplementationId_ is the id of the form implementation
/// @return formImplementation_ is the address of the form implementation
function getFormImplementation(uint32 formImplementationId_) external view returns (address formImplementation_);
/// @dev returns the form state registry id of a form implementation
/// @param formImplementationId_ is the id of the form implementation
/// @return stateRegistryId_ is the additional state registry id of the form
function getFormStateRegistryId(uint32 formImplementationId_) external view returns (uint8 stateRegistryId_);
/// @dev returns the paused status of form implementation
/// @param formImplementationId_ is the id of the form implementation
/// @return paused_ is the current paused status of the form formImplementationId_
function isFormImplementationPaused(uint32 formImplementationId_) external view returns (bool paused_);
/// @dev returns the address of a superform
/// @param superformId_ is the id of the superform
/// @return superform_ is the address of the superform
/// @return formImplementationId_ is the id of the form implementation
/// @return chainId_ is the chain id
function getSuperform(uint256 superformId_)
external
pure
returns (address superform_, uint32 formImplementationId_, uint64 chainId_);
/// @dev returns if an address has been added to a Form
/// @param superformId_ is the id of the superform
/// @return isSuperform_ bool if it exists
function isSuperform(uint256 superformId_) external view returns (bool isSuperform_);
/// @dev Reverse query of getSuperform, returns all superforms for a given vault
/// @param vault_ is the address of a vault
/// @return superformIds_ is the id of the superform
/// @return superforms_ is the address of the superform
function getAllSuperformsFromVault(address vault_)
external
view
returns (uint256[] memory superformIds_, address[] memory superforms_);
//////////////////////////////////////////////////////////////
// EXTERNAL WRITE FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev allows an admin to add a Form implementation to the factory
/// @param formImplementation_ is the address of a form implementation
/// @param formImplementationId_ is the id of the form implementation (generated off-chain and equal in all chains)
/// @param formStateRegistryId_ is the id of any additional state registry for that form
/// @dev formStateRegistryId_ 1 is default for all form implementations, pass in formStateRegistryId_ only if an
/// additional state registry is required
function addFormImplementation(
address formImplementation_,
uint32 formImplementationId_,
uint8 formStateRegistryId_
)
external;
/// @dev To add new vaults to Form implementations, fusing them together into Superforms
/// @param formImplementationId_ is the form implementation we want to attach the vault to
/// @param vault_ is the address of the vault
/// @return superformId_ is the id of the created superform
/// @return superform_ is the address of the created superform
function createSuperform(
uint32 formImplementationId_,
address vault_
)
external
returns (uint256 superformId_, address superform_);
/// @dev to synchronize superforms added to different chains using broadcast registry
/// @param data_ is the cross-chain superform id
function stateSyncBroadcast(bytes memory data_) external payable;
/// @dev allows an admin to change the status of a form
/// @param formImplementationId_ is the id of the form implementation
/// @param status_ is the new status
/// @param extraData_ is optional & passed when broadcasting of status is needed
function changeFormImplementationPauseStatus(
uint32 formImplementationId_,
PauseStatus status_,
bytes memory extraData_
)
external
payable;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
import { PayloadState } from "src/types/DataTypes.sol";
/// @title IBaseStateRegistry
/// @dev Interface for BaseStateRegistry
/// @author ZeroPoint Labs
interface IBaseStateRegistry {
//////////////////////////////////////////////////////////////
// EVENTS //
//////////////////////////////////////////////////////////////
/// @dev is emitted when a cross-chain payload is received in the state registry
event PayloadReceived(uint64 indexed srcChainId, uint64 indexed dstChainId, uint256 indexed payloadId);
/// @dev is emitted when a cross-chain proof is received in the state registry
/// NOTE: comes handy if quorum required is more than 0
event ProofReceived(bytes32 indexed proof);
/// @dev is emitted when a payload id gets updated
event PayloadUpdated(uint256 indexed payloadId);
/// @dev is emitted when a payload id gets processed
event PayloadProcessed(uint256 indexed payloadId);
/// @dev is emitted when the super registry address is updated
event SuperRegistryUpdated(address indexed superRegistry);
//////////////////////////////////////////////////////////////
// EXTERNAL VIEW FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev allows users to read the total payloads received by the registry
function payloadsCount() external view returns (uint256);
/// @dev allows user to read the payload state
/// uint256 payloadId_ is the unique payload identifier allocated on the destination chain
function payloadTracking(uint256 payloadId_) external view returns (PayloadState payloadState_);
/// @dev allows users to read the bytes payload_ stored per payloadId_
/// @param payloadId_ is the unique payload identifier allocated on the destination chain
/// @return payloadBody_ the crosschain data received
function payloadBody(uint256 payloadId_) external view returns (bytes memory payloadBody_);
/// @dev allows users to read the uint256 payloadHeader stored per payloadId_
/// @param payloadId_ is the unique payload identifier allocated on the destination chain
/// @return payloadHeader_ the crosschain header received
function payloadHeader(uint256 payloadId_) external view returns (uint256 payloadHeader_);
/// @dev allows users to read the ambs that delivered the payload id
/// @param payloadId_ is the unique payload identifier allocated on the destination chain
/// @return ambIds_ is the identifier of ambs that delivered the message and proof
function getMessageAMB(uint256 payloadId_) external view returns (uint8[] memory ambIds_);
//////////////////////////////////////////////////////////////
// EXTERNAL WRITE FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev allows core contracts to send payload to a destination chain.
/// @param srcSender_ is the caller of the function (used for gas refunds).
/// @param ambIds_ is the identifier of the arbitrary message bridge to be used
/// @param dstChainId_ is the internal chainId used throughout the protocol
/// @param message_ is the crosschain payload to be sent
/// @param extraData_ defines all the message bridge related overrides
/// NOTE: dstChainId_ is mapped to message bridge's destination id inside it's implementation contract
/// NOTE: ambIds_ are superform assigned unique identifier for arbitrary message bridges
function dispatchPayload(
address srcSender_,
uint8[] memory ambIds_,
uint64 dstChainId_,
bytes memory message_,
bytes memory extraData_
)
external
payable;
/// @dev allows state registry to receive messages from message bridge implementations
/// @param srcChainId_ is the superform chainId from which the payload is dispatched/sent
/// @param message_ is the crosschain payload received
/// NOTE: Only {IMPLEMENTATION_CONTRACT} role can call this function.
function receivePayload(uint64 srcChainId_, bytes memory message_) external;
/// @dev allows privileged actors to process cross-chain payloads
/// @param payloadId_ is the identifier of the cross-chain payload
/// NOTE: Only {CORE_STATE_REGISTRY_PROCESSOR_ROLE} role can call this function
/// NOTE: this should handle reverting the state on source chain in-case of failure
/// (or) can implement scenario based reverting like in coreStateRegistry
function processPayload(uint256 payloadId_) external payable;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
/// @title IAmbImplementation
/// @dev Interface for arbitrary message bridge (AMB) implementations
/// @author ZeroPoint Labs
interface IAmbImplementation {
//////////////////////////////////////////////////////////////
// EVENTS //
//////////////////////////////////////////////////////////////
event ChainAdded(uint64 indexed superChainId);
event AuthorizedImplAdded(uint64 indexed superChainId, address indexed authImpl);
//////////////////////////////////////////////////////////////
// EXTERNAL VIEW FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev returns the gas fees estimation in native tokens
/// @notice not all AMBs will have on-chain estimation for which this function will return 0
/// @param dstChainId_ is the identifier of the destination chain
/// @param message_ is the cross-chain message
/// @param extraData_ is any amb-specific information
/// @return fees is the native_tokens to be sent along the transaction
function estimateFees(
uint64 dstChainId_,
bytes memory message_,
bytes memory extraData_
)
external
view
returns (uint256 fees);
/// @dev returns the extra data for the given gas request
/// @param gasLimit is the amount of gas limit in wei to override
/// @return extraData is the bytes encoded extra data
/// NOTE: this process is unique to the message bridge
function generateExtraData(uint256 gasLimit) external pure returns (bytes memory extraData);
//////////////////////////////////////////////////////////////
// EXTERNAL WRITE FUNCTIONS //
//////////////////////////////////////////////////////////////
/// @dev allows state registry to send message via implementation.
/// @param srcSender_ is the caller (used for gas refunds)
/// @param dstChainId_ is the identifier of the destination chain
/// @param message_ is the cross-chain message to be sent
/// @param extraData_ is message amb specific override information
function dispatchPayload(
address srcSender_,
uint64 dstChainId_,
bytes memory message_,
bytes memory extraData_
)
external
payable;
/// @dev allows for the permissionless calling of the retry mechanism for encoded data
/// @param data_ is the encoded retry data (different per AMB implementation)
function retryPayload(bytes memory data_) external payable;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
library Error {
//////////////////////////////////////////////////////////////
// CONFIGURATION ERRORS //
//////////////////////////////////////////////////////////////
///@notice errors thrown in protocol setup
/// @dev thrown if chain id exceeds max(uint64)
error BLOCK_CHAIN_ID_OUT_OF_BOUNDS();
/// @dev thrown if not possible to revoke a role in broadcasting
error CANNOT_REVOKE_NON_BROADCASTABLE_ROLES();
/// @dev thrown if not possible to revoke last admin
error CANNOT_REVOKE_LAST_ADMIN();
/// @dev thrown if trying to set again pseudo immutables in super registry
error DISABLED();
/// @dev thrown if rescue delay is not yet set for a chain
error DELAY_NOT_SET();
/// @dev thrown if get native token price estimate in paymentHelper is 0
error INVALID_NATIVE_TOKEN_PRICE();
/// @dev thrown if wormhole refund chain id is not set
error REFUND_CHAIN_ID_NOT_SET();
/// @dev thrown if wormhole relayer is not set
error RELAYER_NOT_SET();
/// @dev thrown if a role to be revoked is not assigned
error ROLE_NOT_ASSIGNED();
//////////////////////////////////////////////////////////////
// AUTHORIZATION ERRORS //
//////////////////////////////////////////////////////////////
///@notice errors thrown if functions cannot be called
/// COMMON AUTHORIZATION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if caller is not address(this), internal call
error INVALID_INTERNAL_CALL();
/// @dev thrown if msg.sender is not a valid amb implementation
error NOT_AMB_IMPLEMENTATION();
/// @dev thrown if msg.sender is not an allowed broadcaster
error NOT_ALLOWED_BROADCASTER();
/// @dev thrown if msg.sender is not broadcast amb implementation
error NOT_BROADCAST_AMB_IMPLEMENTATION();
/// @dev thrown if msg.sender is not broadcast state registry
error NOT_BROADCAST_REGISTRY();
/// @dev thrown if msg.sender is not core state registry
error NOT_CORE_STATE_REGISTRY();
/// @dev thrown if msg.sender is not emergency admin
error NOT_EMERGENCY_ADMIN();
/// @dev thrown if msg.sender is not emergency queue
error NOT_EMERGENCY_QUEUE();
/// @dev thrown if msg.sender is not minter
error NOT_MINTER();
/// @dev thrown if msg.sender is not minter state registry
error NOT_MINTER_STATE_REGISTRY_ROLE();
/// @dev thrown if msg.sender is not paymaster
error NOT_PAYMASTER();
/// @dev thrown if msg.sender is not payment admin
error NOT_PAYMENT_ADMIN();
/// @dev thrown if msg.sender is not protocol admin
error NOT_PROTOCOL_ADMIN();
/// @dev thrown if msg.sender is not state registry
error NOT_STATE_REGISTRY();
/// @dev thrown if msg.sender is not super registry
error NOT_SUPER_REGISTRY();
/// @dev thrown if msg.sender is not superform router
error NOT_SUPERFORM_ROUTER();
/// @dev thrown if msg.sender is not a superform
error NOT_SUPERFORM();
/// @dev thrown if msg.sender is not superform factory
error NOT_SUPERFORM_FACTORY();
/// @dev thrown if msg.sender is not timelock form
error NOT_TIMELOCK_SUPERFORM();
/// @dev thrown if msg.sender is not timelock state registry
error NOT_TIMELOCK_STATE_REGISTRY();
/// @dev thrown if msg.sender is not user or disputer
error NOT_VALID_DISPUTER();
/// @dev thrown if the msg.sender is not privileged caller
error NOT_PRIVILEGED_CALLER(bytes32 role);
/// STATE REGISTRY AUTHORIZATION ERRORS
/// ---------------------------------------------------------
/// @dev layerzero adapter specific error, thrown if caller not layerzero endpoint
error CALLER_NOT_ENDPOINT();
/// @dev hyperlane adapter specific error, thrown if caller not hyperlane mailbox
error CALLER_NOT_MAILBOX();
/// @dev wormhole relayer specific error, thrown if caller not wormhole relayer
error CALLER_NOT_RELAYER();
/// @dev thrown if src chain sender is not valid
error INVALID_SRC_SENDER();
//////////////////////////////////////////////////////////////
// INPUT VALIDATION ERRORS //
//////////////////////////////////////////////////////////////
///@notice errors thrown if input variables are not valid
/// COMMON INPUT VALIDATION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if there is an array length mismatch
error ARRAY_LENGTH_MISMATCH();
/// @dev thrown if payload id does not exist
error INVALID_PAYLOAD_ID();
/// @dev error thrown when msg value should be zero in certain payable functions
error MSG_VALUE_NOT_ZERO();
/// @dev thrown if amb ids length is 0
error ZERO_AMB_ID_LENGTH();
/// @dev thrown if address input is address 0
error ZERO_ADDRESS();
/// @dev thrown if amount input is 0
error ZERO_AMOUNT();
/// @dev thrown if final token is address 0
error ZERO_FINAL_TOKEN();
/// @dev thrown if value input is 0
error ZERO_INPUT_VALUE();
/// SUPERFORM ROUTER INPUT VALIDATION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if the vaults data is invalid
error INVALID_SUPERFORMS_DATA();
/// @dev thrown if receiver address is not set
error RECEIVER_ADDRESS_NOT_SET();
/// SUPERFORM FACTORY INPUT VALIDATION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if a form is not ERC165 compatible
error ERC165_UNSUPPORTED();
/// @dev thrown if a form is not form interface compatible
error FORM_INTERFACE_UNSUPPORTED();
/// @dev error thrown if form implementation address already exists
error FORM_IMPLEMENTATION_ALREADY_EXISTS();
/// @dev error thrown if form implementation id already exists
error FORM_IMPLEMENTATION_ID_ALREADY_EXISTS();
/// @dev thrown if a form does not exist
error FORM_DOES_NOT_EXIST();
/// @dev thrown if form id is larger than max uint16
error INVALID_FORM_ID();
/// @dev thrown if superform not on factory
error SUPERFORM_ID_NONEXISTENT();
/// @dev thrown if same vault and form implementation is used to create new superform
error VAULT_FORM_IMPLEMENTATION_COMBINATION_EXISTS();
/// FORM INPUT VALIDATION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if in case of no txData, if liqData.token != vault.asset()
/// in case of txData, if token output of swap != vault.asset()
error DIFFERENT_TOKENS();
/// @dev thrown if the amount in direct withdraw is not correct
error DIRECT_WITHDRAW_INVALID_LIQ_REQUEST();
/// @dev thrown if the amount in xchain withdraw is not correct
error XCHAIN_WITHDRAW_INVALID_LIQ_REQUEST();
/// LIQUIDITY BRIDGE INPUT VALIDATION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if route id is blacklisted in socket
error BLACKLISTED_ROUTE_ID();
/// @dev thrown if route id is not blacklisted in socket
error NOT_BLACKLISTED_ROUTE_ID();
/// @dev error thrown when txData selector of lifi bridge is a blacklisted selector
error BLACKLISTED_SELECTOR();
/// @dev error thrown when txData selector of lifi bridge is not a blacklisted selector
error NOT_BLACKLISTED_SELECTOR();
/// @dev thrown if a certain action of the user is not allowed given the txData provided
error INVALID_ACTION();
/// @dev thrown if in deposits, the liqDstChainId doesn't match the stateReq dstChainId
error INVALID_DEPOSIT_LIQ_DST_CHAIN_ID();
/// @dev thrown if index is invalid
error INVALID_INDEX();
/// @dev thrown if the chain id in the txdata is invalid
error INVALID_TXDATA_CHAIN_ID();
/// @dev thrown if the validation of bridge txData fails due to a destination call present
error INVALID_TXDATA_NO_DESTINATIONCALL_ALLOWED();
/// @dev thrown if the validation of bridge txData fails due to wrong receiver
error INVALID_TXDATA_RECEIVER();
/// @dev thrown if the validation of bridge txData fails due to wrong token
error INVALID_TXDATA_TOKEN();
/// @dev thrown if txData is not present (in case of xChain actions)
error NO_TXDATA_PRESENT();
/// STATE REGISTRY INPUT VALIDATION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if payload is being updated with final amounts length different than amounts length
error DIFFERENT_PAYLOAD_UPDATE_AMOUNTS_LENGTH();
/// @dev thrown if payload is being updated with tx data length different than liq data length
error DIFFERENT_PAYLOAD_UPDATE_TX_DATA_LENGTH();
/// @dev thrown if keeper update final token is different than the vault underlying
error INVALID_UPDATE_FINAL_TOKEN();
/// @dev thrown if broadcast finality for wormhole is invalid
error INVALID_BROADCAST_FINALITY();
/// @dev thrown if amb id is not valid leading to an address 0 of the implementation
error INVALID_BRIDGE_ID();
/// @dev thrown if chain id involved in xchain message is invalid
error INVALID_CHAIN_ID();
/// @dev thrown if payload update amount isn't equal to dst swapper amount
error INVALID_DST_SWAP_AMOUNT();
/// @dev thrown if message amb and proof amb are the same
error INVALID_PROOF_BRIDGE_ID();
/// @dev thrown if order of proof AMBs is incorrect, either duplicated or not incrementing
error INVALID_PROOF_BRIDGE_IDS();
/// @dev thrown if rescue data lengths are invalid
error INVALID_RESCUE_DATA();
/// @dev thrown if delay is invalid
error INVALID_TIMELOCK_DELAY();
/// @dev thrown if amounts being sent in update payload mean a negative slippage
error NEGATIVE_SLIPPAGE();
/// @dev thrown if slippage is outside of bounds
error SLIPPAGE_OUT_OF_BOUNDS();
/// SUPERPOSITION INPUT VALIDATION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if src senders mismatch in state sync
error SRC_SENDER_MISMATCH();
/// @dev thrown if src tx types mismatch in state sync
error SRC_TX_TYPE_MISMATCH();
//////////////////////////////////////////////////////////////
// EXECUTION ERRORS //
//////////////////////////////////////////////////////////////
///@notice errors thrown due to function execution logic
/// COMMON EXECUTION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if the swap in a direct deposit resulted in insufficient tokens
error DIRECT_DEPOSIT_SWAP_FAILED();
/// @dev thrown if payload is not unique
error DUPLICATE_PAYLOAD();
/// @dev thrown if native tokens fail to be sent to superform contracts
error FAILED_TO_SEND_NATIVE();
/// @dev thrown if allowance is not correct to deposit
error INSUFFICIENT_ALLOWANCE_FOR_DEPOSIT();
/// @dev thrown if contract has insufficient balance for operations
error INSUFFICIENT_BALANCE();
/// @dev thrown if native amount is not at least equal to the amount in the request
error INSUFFICIENT_NATIVE_AMOUNT();
/// @dev thrown if payload cannot be decoded
error INVALID_PAYLOAD();
/// @dev thrown if payload status is invalid
error INVALID_PAYLOAD_STATUS();
/// @dev thrown if payload type is invalid
error INVALID_PAYLOAD_TYPE();
/// LIQUIDITY BRIDGE EXECUTION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if we try to decode the final swap output token in a xChain liquidity bridging action
error CANNOT_DECODE_FINAL_SWAP_OUTPUT_TOKEN();
/// @dev thrown if liquidity bridge fails for erc20 or native tokens
error FAILED_TO_EXECUTE_TXDATA(address token);
/// @dev thrown if asset being used for deposit mismatches in multivault deposits
error INVALID_DEPOSIT_TOKEN();
/// STATE REGISTRY EXECUTION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if bridge tokens haven't arrived to destination
error BRIDGE_TOKENS_PENDING();
/// @dev thrown if withdrawal tx data cannot be updated
error CANNOT_UPDATE_WITHDRAW_TX_DATA();
/// @dev thrown if rescue passed dispute deadline
error DISPUTE_TIME_ELAPSED();
/// @dev thrown if message failed to reach the specified level of quorum needed
error INSUFFICIENT_QUORUM();
/// @dev thrown if broadcast payload is invalid
error INVALID_BROADCAST_PAYLOAD();
/// @dev thrown if broadcast fee is invalid
error INVALID_BROADCAST_FEE();
/// @dev thrown if retry fees is less than required
error INVALID_RETRY_FEE();
/// @dev thrown if broadcast message type is wrong
error INVALID_MESSAGE_TYPE();
/// @dev thrown if payload hash is invalid during `retryMessage` on Layezero implementation
error INVALID_PAYLOAD_HASH();
/// @dev thrown if update payload function was called on a wrong payload
error INVALID_PAYLOAD_UPDATE_REQUEST();
/// @dev thrown if a state registry id is 0
error INVALID_REGISTRY_ID();
/// @dev thrown if a form state registry id is 0
error INVALID_FORM_REGISTRY_ID();
/// @dev thrown if trying to finalize the payload but the withdraw is still locked
error LOCKED();
/// @dev thrown if payload is already updated (during xChain deposits)
error PAYLOAD_ALREADY_UPDATED();
/// @dev thrown if payload is already processed
error PAYLOAD_ALREADY_PROCESSED();
/// @dev thrown if payload is not in UPDATED state
error PAYLOAD_NOT_UPDATED();
/// @dev thrown if rescue is still in timelocked state
error RESCUE_LOCKED();
/// @dev thrown if rescue is already proposed
error RESCUE_ALREADY_PROPOSED();
/// @dev thrown if payload hash is zero during `retryMessage` on Layezero implementation
error ZERO_PAYLOAD_HASH();
/// DST SWAPPER EXECUTION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if process dst swap is tried for processed payload id
error DST_SWAP_ALREADY_PROCESSED();
/// @dev thrown if indices have duplicates
error DUPLICATE_INDEX();
/// @dev thrown if failed dst swap is already updated
error FAILED_DST_SWAP_ALREADY_UPDATED();
/// @dev thrown if indices are out of bounds
error INDEX_OUT_OF_BOUNDS();
/// @dev thrown if failed swap token amount is 0
error INVALID_DST_SWAPPER_FAILED_SWAP();
/// @dev thrown if failed swap token amount is not 0 and if token balance is less than amount (non zero)
error INVALID_DST_SWAPPER_FAILED_SWAP_NO_TOKEN_BALANCE();
/// @dev thrown if failed swap token amount is not 0 and if native amount is less than amount (non zero)
error INVALID_DST_SWAPPER_FAILED_SWAP_NO_NATIVE_BALANCE();
/// @dev forbid xChain deposits with destination swaps without interim token set (for user protection)
error INVALID_INTERIM_TOKEN();
/// @dev thrown if dst swap output is less than minimum expected
error INVALID_SWAP_OUTPUT();
/// FORM EXECUTION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if try to forward 4626 share from the superform
error CANNOT_FORWARD_4646_TOKEN();
/// @dev thrown in KYCDAO form if no KYC token is present
error NO_VALID_KYC_TOKEN();
/// @dev thrown in forms where a certain functionality is not allowed or implemented
error NOT_IMPLEMENTED();
/// @dev thrown if form implementation is PAUSED, users cannot perform any action
error PAUSED();
/// @dev thrown if shares != deposit output or assets != redeem output when minting SuperPositions
error VAULT_IMPLEMENTATION_FAILED();
/// @dev thrown if withdrawal tx data is not updated
error WITHDRAW_TOKEN_NOT_UPDATED();
/// @dev thrown if withdrawal tx data is not updated
error WITHDRAW_TX_DATA_NOT_UPDATED();
/// @dev thrown when redeeming from vault yields zero collateral
error WITHDRAW_ZERO_COLLATERAL();
/// PAYMENT HELPER EXECUTION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if chainlink is reporting an improper price
error CHAINLINK_MALFUNCTION();
/// @dev thrown if chainlink is reporting an incomplete round
error CHAINLINK_INCOMPLETE_ROUND();
/// @dev thrown if feed decimals is not 8
error CHAINLINK_UNSUPPORTED_DECIMAL();
/// EMERGENCY QUEUE EXECUTION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if emergency withdraw is not queued
error EMERGENCY_WITHDRAW_NOT_QUEUED();
/// @dev thrown if emergency withdraw is already processed
error EMERGENCY_WITHDRAW_PROCESSED_ALREADY();
/// SUPERPOSITION EXECUTION ERRORS
/// ---------------------------------------------------------
/// @dev thrown if uri cannot be updated
error DYNAMIC_URI_FROZEN();
/// @dev thrown if tx history is not found while state sync
error TX_HISTORY_NOT_FOUND();
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
import { Error } from "src/libraries/Error.sol";
library DataLib {
function packTxInfo(
uint8 txType_,
uint8 callbackType_,
uint8 multi_,
uint8 registryId_,
address srcSender_,
uint64 srcChainId_
)
internal
pure
returns (uint256 txInfo)
{
txInfo = uint256(txType_);
txInfo |= uint256(callbackType_) << 8;
txInfo |= uint256(multi_) << 16;
txInfo |= uint256(registryId_) << 24;
txInfo |= uint256(uint160(srcSender_)) << 32;
txInfo |= uint256(srcChainId_) << 192;
}
function decodeTxInfo(uint256 txInfo_)
internal
pure
returns (uint8 txType, uint8 callbackType, uint8 multi, uint8 registryId, address srcSender, uint64 srcChainId)
{
txType = uint8(txInfo_);
callbackType = uint8(txInfo_ >> 8);
multi = uint8(txInfo_ >> 16);
registryId = uint8(txInfo_ >> 24);
srcSender = address(uint160(txInfo_ >> 32));
srcChainId = uint64(txInfo_ >> 192);
}
/// @dev returns the vault-form-chain pair of a superform
/// @param superformId_ is the id of the superform
/// @return superform_ is the address of the superform
/// @return formImplementationId_ is the form id
/// @return chainId_ is the chain id
function getSuperform(uint256 superformId_)
internal
pure
returns (address superform_, uint32 formImplementationId_, uint64 chainId_)
{
superform_ = address(uint160(superformId_));
formImplementationId_ = uint32(superformId_ >> 160);
chainId_ = uint64(superformId_ >> 192);
if (chainId_ == 0) {
revert Error.INVALID_CHAIN_ID();
}
}
/// @dev returns the vault-form-chain pair of an array of superforms
/// @param superformIds_ array of superforms
/// @return superforms_ are the address of the vaults
function getSuperforms(uint256[] memory superformIds_) internal pure returns (address[] memory superforms_) {
uint256 len = superformIds_.length;
superforms_ = new address[](len);
for (uint256 i; i < len; ++i) {
(superforms_[i],,) = getSuperform(superformIds_[i]);
}
}
/// @dev returns the destination chain of a given superform
/// @param superformId_ is the id of the superform
/// @return chainId_ is the chain id
function getDestinationChain(uint256 superformId_) internal pure returns (uint64 chainId_) {
chainId_ = uint64(superformId_ >> 192);
if (chainId_ == 0) {
revert Error.INVALID_CHAIN_ID();
}
}
/// @dev generates the superformId
/// @param superform_ is the address of the superform
/// @param formImplementationId_ is the type of the form
/// @param chainId_ is the chain id on which the superform is deployed
function packSuperform(
address superform_,
uint32 formImplementationId_,
uint64 chainId_
)
internal
pure
returns (uint256 superformId_)
{
superformId_ = uint256(uint160(superform_));
superformId_ |= uint256(formImplementationId_) << 160;
superformId_ |= uint256(chainId_) << 192;
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
import { AMBMessage } from "src/types/DataTypes.sol";
/// @dev generates proof for amb message and bytes encoded message
library ProofLib {
function computeProof(AMBMessage memory message_) internal pure returns (bytes32) {
return keccak256(abi.encode(message_));
}
function computeProofBytes(AMBMessage memory message_) internal pure returns (bytes memory) {
return abi.encode(keccak256(abi.encode(message_)));
}
function computeProof(bytes memory message_) internal pure returns (bytes32) {
return keccak256(message_);
}
function computeProofBytes(bytes memory message_) internal pure returns (bytes memory) {
return abi.encode(keccak256(message_));
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
import { InitSingleVaultData, InitMultiVaultData, LiqRequest } from "src/types/DataTypes.sol";
/// @dev library to cast single values into array for streamlining helper functions
/// @notice not gas optimized, suggested for usage only in view/pure functions
library ArrayCastLib {
function castLiqRequestToArray(LiqRequest memory value_) internal pure returns (LiqRequest[] memory values) {
values = new LiqRequest[](1);
values[0] = value_;
}
function castBoolToArray(bool value_) internal pure returns (bool[] memory values) {
values = new bool[](1);
values[0] = value_;
}
function castToMultiVaultData(InitSingleVaultData memory data_)
internal
pure
returns (InitMultiVaultData memory castedData_)
{
uint256[] memory superformIds = new uint256[](1);
superformIds[0] = data_.superformId;
uint256[] memory amounts = new uint256[](1);
amounts[0] = data_.amount;
uint256[] memory outputAmounts = new uint256[](1);
outputAmounts[0] = data_.outputAmount;
uint256[] memory maxSlippage = new uint256[](1);
maxSlippage[0] = data_.maxSlippage;
LiqRequest[] memory liqData = new LiqRequest[](1);
liqData[0] = data_.liqData;
castedData_ = InitMultiVaultData(
data_.payloadId,
superformIds,
amounts,
outputAmounts,
maxSlippage,
liqData,
castBoolToArray(data_.hasDstSwap),
castBoolToArray(data_.retain4626),
data_.receiverAddress,
data_.extraFormData
);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
/// @dev contains all the common struct and enums used for data communication between chains.
/// @dev There are two transaction types in Superform Protocol
enum TransactionType {
DEPOSIT,
WITHDRAW
}
/// @dev Message types can be INIT, RETURN (for successful Deposits) and FAIL (for failed withdraws)
enum CallbackType {
INIT,
RETURN,
FAIL
}
/// @dev Payloads are stored, updated (deposits) or processed (finalized)
enum PayloadState {
STORED,
UPDATED,
PROCESSED
}
/// @dev contains all the common struct used for interchain token transfers.
struct LiqRequest {
/// @dev generated data
bytes txData;
/// @dev input token for deposits, desired output token on target liqDstChainId for withdraws. Must be set for
/// txData to be updated on destination for withdraws
address token;
/// @dev intermediary token on destination. Relevant for xChain deposits where a destination swap is needed for
/// validation purposes
address interimToken;
/// @dev what bridge to use to move tokens
uint8 bridgeId;
/// @dev dstChainId = liqDstchainId for deposits. For withdraws it is the target chain id for where the underlying
/// is to be delivered
uint64 liqDstChainId;
/// @dev currently this amount is used as msg.value in the txData call.
uint256 nativeAmount;
}
/// @dev main struct that holds required multi vault data for an action
struct MultiVaultSFData {
// superformids must have same destination. Can have different underlyings
uint256[] superformIds;
uint256[] amounts; // on deposits, amount of token to deposit on dst, on withdrawals, superpositions to burn
uint256[] outputAmounts; // on deposits, amount of shares to receive, on withdrawals, amount of assets to receive
uint256[] maxSlippages;
LiqRequest[] liqRequests; // if length = 1; amount = sum(amounts) | else amounts must match the amounts being sent
bytes permit2data;
bool[] hasDstSwaps;
bool[] retain4626s; // if true, we don't mint SuperPositions, and send the 4626 back to the user instead
address receiverAddress;
/// this address must always be an EOA otherwise funds may be lost
address receiverAddressSP;
/// this address can be a EOA or a contract that implements onERC1155Receiver. must always be set for deposits
bytes extraFormData; // extraFormData
}
/// @dev main struct that holds required single vault data for an action
struct SingleVaultSFData {
// superformids must have same destination. Can have different underlyings
uint256 superformId;
uint256 amount;
uint256 outputAmount; // on deposits, amount of shares to receive, on withdrawals, amount of assets to receive
uint256 maxSlippage;
LiqRequest liqRequest; // if length = 1; amount = sum(amounts)| else amounts must match the amounts being sent
bytes permit2data;
bool hasDstSwap;
bool retain4626; // if true, we don't mint SuperPositions, and send the 4626 back to the user instead
address receiverAddress;
/// this address must always be an EOA otherwise funds may be lost
address receiverAddressSP;
/// this address can be a EOA or a contract that implements onERC1155Receiver. must always be set for deposits
bytes extraFormData; // extraFormData
}
/// @dev overarching struct for multiDst requests with multi vaults
struct MultiDstMultiVaultStateReq {
uint8[][] ambIds;
uint64[] dstChainIds;
MultiVaultSFData[] superformsData;
}
/// @dev overarching struct for single cross chain requests with multi vaults
struct SingleXChainMultiVaultStateReq {
uint8[] ambIds;
uint64 dstChainId;
MultiVaultSFData superformsData;
}
/// @dev overarching struct for multiDst requests with single vaults
struct MultiDstSingleVaultStateReq {
uint8[][] ambIds;
uint64[] dstChainIds;
SingleVaultSFData[] superformsData;
}
/// @dev overarching struct for single cross chain requests with single vaults
struct SingleXChainSingleVaultStateReq {
uint8[] ambIds;
uint64 dstChainId;
SingleVaultSFData superformData;
}
/// @dev overarching struct for single direct chain requests with single vaults
struct SingleDirectSingleVaultStateReq {
SingleVaultSFData superformData;
}
/// @dev overarching struct for single direct chain requests with multi vaults
struct SingleDirectMultiVaultStateReq {
MultiVaultSFData superformData;
}
/// @dev struct for SuperRouter with re-arranged data for the message (contains the payloadId)
/// @dev realize that receiverAddressSP is not passed, only needed on source chain to mint
struct InitMultiVaultData {
uint256 payloadId;
uint256[] superformIds;
uint256[] amounts;
uint256[] outputAmounts;
uint256[] maxSlippages;
LiqRequest[] liqData;
bool[] hasDstSwaps;
bool[] retain4626s;
address receiverAddress;
bytes extraFormData;
}
/// @dev struct for SuperRouter with re-arranged data for the message (contains the payloadId)
struct InitSingleVaultData {
uint256 payloadId;
uint256 superformId;
uint256 amount;
uint256 outputAmount;
uint256 maxSlippage;
LiqRequest liqData;
bool hasDstSwap;
bool retain4626;
address receiverAddress;
bytes extraFormData;
}
/// @dev struct for Emergency Queue
struct QueuedWithdrawal {
address receiverAddress;
uint256 superformId;
uint256 amount;
uint256 srcPayloadId;
bool isProcessed;
}
/// @dev all statuses of the timelock payload
enum TimelockStatus {
UNAVAILABLE,
PENDING,
PROCESSED
}
/// @dev holds information about the timelock payload
struct TimelockPayload {
uint8 isXChain;
uint64 srcChainId;
uint256 lockedTill;
InitSingleVaultData data;
TimelockStatus status;
}
/// @dev struct that contains the type of transaction, callback flags and other identification, as well as the vaults
/// data in params
struct AMBMessage {
uint256 txInfo; // tight packing of TransactionType txType, CallbackType flag if multi/single vault, registry id,
// srcSender and srcChainId
bytes params; // decoding txInfo will point to the right datatype of params. Refer PayloadHelper.sol
}
/// @dev struct that contains the information required for broadcasting changes
struct BroadcastMessage {
bytes target;
bytes32 messageType;
bytes message;
}
/// @dev struct that contains info on returned data from destination
struct ReturnMultiData {
uint256 payloadId;
uint256[] superformIds;
uint256[] amounts;
}
/// @dev struct that contains info on returned data from destination
struct ReturnSingleData {
uint256 payloadId;
uint256 superformId;
uint256 amount;
}
/// @dev struct that contains the data on the fees to pay to the AMBs
struct AMBExtraData {
uint256[] gasPerAMB;
bytes[] extraDataPerAMB;
}
/// @dev struct that contains the data on the fees to pay to the AMBs on broadcasts
struct BroadCastAMBExtraData {
uint256[] gasPerDst;
bytes[] extraDataPerDst;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(uint80 _roundId)
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
function latestRoundData()
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}{
"remappings": [
"solmate/=lib/ERC1155A/lib/solmate/src/",
"ERC1155A/=lib/ERC1155A/src/",
"@openzeppelin/contracts/=lib/ERC1155A/lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/ds-test/src/",
"erc4626-tests/=lib/ERC1155A/lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts/=lib/ERC1155A/lib/openzeppelin-contracts/",
"pigeon/=lib/pigeon/src/",
"solady/=lib/pigeon/lib/solady/",
"super-vaults/=lib/super-vaults/src/",
"v2-core/=lib/super-vaults/lib/v2-core/contracts/",
"v2-periphery/=lib/super-vaults/lib/v2-periphery/contracts/",
"v3-core/=lib/super-vaults/lib/v3-core/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"superRegistry_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ARRAY_LENGTH_MISMATCH","type":"error"},{"inputs":[],"name":"BLOCK_CHAIN_ID_OUT_OF_BOUNDS","type":"error"},{"inputs":[],"name":"CHAINLINK_INCOMPLETE_ROUND","type":"error"},{"inputs":[],"name":"CHAINLINK_MALFUNCTION","type":"error"},{"inputs":[],"name":"CHAINLINK_UNSUPPORTED_DECIMAL","type":"error"},{"inputs":[],"name":"INVALID_CHAIN_ID","type":"error"},{"inputs":[],"name":"INVALID_NATIVE_TOKEN_PRICE","type":"error"},{"inputs":[],"name":"INVALID_PAYLOAD_ID","type":"error"},{"inputs":[],"name":"NOT_PAYMENT_ADMIN","type":"error"},{"inputs":[],"name":"NOT_PROTOCOL_ADMIN","type":"error"},{"inputs":[],"name":"ZERO_ADDRESS","type":"error"},{"inputs":[],"name":"ZERO_INPUT_VALUE","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"chainId_","type":"uint64"},{"components":[{"internalType":"address","name":"nativeFeedOracle","type":"address"},{"internalType":"address","name":"gasPriceOracle","type":"address"},{"internalType":"uint256","name":"swapGasUsed","type":"uint256"},{"internalType":"uint256","name":"updateDepositGasUsed","type":"uint256"},{"internalType":"uint256","name":"depositGasUsed","type":"uint256"},{"internalType":"uint256","name":"withdrawGasUsed","type":"uint256"},{"internalType":"uint256","name":"defaultNativePrice","type":"uint256"},{"internalType":"uint256","name":"defaultGasPrice","type":"uint256"},{"internalType":"uint256","name":"dstGasPerByte","type":"uint256"},{"internalType":"uint256","name":"ackGasCost","type":"uint256"},{"internalType":"uint256","name":"timelockCost","type":"uint256"},{"internalType":"uint256","name":"emergencyCost","type":"uint256"},{"internalType":"uint256","name":"updateWithdrawGasUsed","type":"uint256"}],"indexed":false,"internalType":"struct IPaymentHelperV2.PaymentHelperConfig","name":"config_","type":"tuple"}],"name":"ChainConfigAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId_","type":"uint64"},{"indexed":true,"internalType":"uint256","name":"configType_","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"config_","type":"bytes"}],"name":"ChainConfigUpdated","type":"event"},{"inputs":[],"name":"CHAIN_ID","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"ackGasCost","outputs":[{"internalType":"uint256","name":"gasForAck","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId_","type":"uint64"},{"components":[{"internalType":"address","name":"nativeFeedOracle","type":"address"},{"internalType":"address","name":"gasPriceOracle","type":"address"},{"internalType":"uint256","name":"swapGasUsed","type":"uint256"},{"internalType":"uint256","name":"updateDepositGasUsed","type":"uint256"},{"internalType":"uint256","name":"depositGasUsed","type":"uint256"},{"internalType":"uint256","name":"withdrawGasUsed","type":"uint256"},{"internalType":"uint256","name":"defaultNativePrice","type":"uint256"},{"internalType":"uint256","name":"defaultGasPrice","type":"uint256"},{"internalType":"uint256","name":"dstGasPerByte","type":"uint256"},{"internalType":"uint256","name":"ackGasCost","type":"uint256"},{"internalType":"uint256","name":"timelockCost","type":"uint256"},{"internalType":"uint256","name":"emergencyCost","type":"uint256"},{"internalType":"uint256","name":"updateWithdrawGasUsed","type":"uint256"}],"internalType":"struct IPaymentHelperV2.PaymentHelperConfig","name":"config_","type":"tuple"}],"name":"addRemoteChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"chainIds_","type":"uint64[]"},{"components":[{"internalType":"address","name":"nativeFeedOracle","type":"address"},{"internalType":"address","name":"gasPriceOracle","type":"address"},{"internalType":"uint256","name":"swapGasUsed","type":"uint256"},{"internalType":"uint256","name":"updateDepositGasUsed","type":"uint256"},{"internalType":"uint256","name":"depositGasUsed","type":"uint256"},{"internalType":"uint256","name":"withdrawGasUsed","type":"uint256"},{"internalType":"uint256","name":"defaultNativePrice","type":"uint256"},{"internalType":"uint256","name":"defaultGasPrice","type":"uint256"},{"internalType":"uint256","name":"dstGasPerByte","type":"uint256"},{"internalType":"uint256","name":"ackGasCost","type":"uint256"},{"internalType":"uint256","name":"timelockCost","type":"uint256"},{"internalType":"uint256","name":"emergencyCost","type":"uint256"},{"internalType":"uint256","name":"updateWithdrawGasUsed","type":"uint256"}],"internalType":"struct IPaymentHelperV2.PaymentHelperConfig[]","name":"configs_","type":"tuple[]"}],"name":"addRemoteChains","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId_","type":"uint64"},{"internalType":"uint256[]","name":"configTypes_","type":"uint256[]"},{"internalType":"bytes[]","name":"configs_","type":"bytes[]"}],"name":"batchUpdateRemoteChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"chainIds_","type":"uint64[]"},{"internalType":"uint256[][]","name":"configTypes_","type":"uint256[][]"},{"internalType":"bytes[][]","name":"configs_","type":"bytes[][]"}],"name":"batchUpdateRemoteChains","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"dstChainId_","type":"uint64"},{"internalType":"uint8[]","name":"ambIds_","type":"uint8[]"},{"internalType":"bytes","name":"message_","type":"bytes"}],"name":"calculateAMBData","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"depositGasUsed","outputs":[{"internalType":"uint256","name":"gasForDeposit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"emergencyCost","outputs":[{"internalType":"uint256","name":"gasForEmergency","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"ambIds_","type":"uint8[]"},{"internalType":"uint64","name":"dstChainId_","type":"uint64"},{"internalType":"bytes","name":"message_","type":"bytes"},{"internalType":"bytes[]","name":"extraData_","type":"bytes[]"}],"name":"estimateAMBFees","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"payloadId_","type":"uint256"}],"name":"estimateAckCost","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"multi","type":"bool"},{"internalType":"uint8[]","name":"ackAmbIds","type":"uint8[]"},{"internalType":"uint64","name":"srcChainId","type":"uint64"}],"name":"estimateAckCostDefault","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"multi","type":"bool"},{"internalType":"uint8[]","name":"ackAmbIds","type":"uint8[]"},{"internalType":"uint64","name":"srcChainId","type":"uint64"}],"name":"estimateAckCostDefaultNativeSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8[][]","name":"ambIds","type":"uint8[][]"},{"internalType":"uint64[]","name":"dstChainIds","type":"uint64[]"},{"components":[{"internalType":"uint256[]","name":"superformIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"outputAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maxSlippages","type":"uint256[]"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest[]","name":"liqRequests","type":"tuple[]"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool[]","name":"hasDstSwaps","type":"bool[]"},{"internalType":"bool[]","name":"retain4626s","type":"bool[]"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct MultiVaultSFData[]","name":"superformsData","type":"tuple[]"}],"internalType":"struct MultiDstMultiVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateMultiDstMultiVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8[][]","name":"ambIds","type":"uint8[][]"},{"internalType":"uint64[]","name":"dstChainIds","type":"uint64[]"},{"components":[{"internalType":"uint256","name":"superformId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"maxSlippage","type":"uint256"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest","name":"liqRequest","type":"tuple"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool","name":"hasDstSwap","type":"bool"},{"internalType":"bool","name":"retain4626","type":"bool"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct SingleVaultSFData[]","name":"superformsData","type":"tuple[]"}],"internalType":"struct MultiDstSingleVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateMultiDstSingleVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint256[]","name":"superformIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"outputAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maxSlippages","type":"uint256[]"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest[]","name":"liqRequests","type":"tuple[]"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool[]","name":"hasDstSwaps","type":"bool[]"},{"internalType":"bool[]","name":"retain4626s","type":"bool[]"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct MultiVaultSFData","name":"superformData","type":"tuple"}],"internalType":"struct SingleDirectMultiVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateSingleDirectMultiVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"dstOrSameChainAmt","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"superformId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"maxSlippage","type":"uint256"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest","name":"liqRequest","type":"tuple"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool","name":"hasDstSwap","type":"bool"},{"internalType":"bool","name":"retain4626","type":"bool"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct SingleVaultSFData","name":"superformData","type":"tuple"}],"internalType":"struct SingleDirectSingleVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateSingleDirectSingleVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"dstOrSameChainAmt","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8[]","name":"ambIds","type":"uint8[]"},{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"components":[{"internalType":"uint256[]","name":"superformIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"outputAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maxSlippages","type":"uint256[]"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest[]","name":"liqRequests","type":"tuple[]"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool[]","name":"hasDstSwaps","type":"bool[]"},{"internalType":"bool[]","name":"retain4626s","type":"bool[]"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct MultiVaultSFData","name":"superformsData","type":"tuple"}],"internalType":"struct SingleXChainMultiVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateSingleXChainMultiVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8[]","name":"ambIds","type":"uint8[]"},{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"components":[{"internalType":"uint256","name":"superformId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"maxSlippage","type":"uint256"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest","name":"liqRequest","type":"tuple"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool","name":"hasDstSwap","type":"bool"},{"internalType":"bool","name":"retain4626","type":"bool"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct SingleVaultSFData","name":"superformData","type":"tuple"}],"internalType":"struct SingleXChainSingleVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateSingleXChainSingleVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"extraDataForTransmuter","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"gasPerByte","outputs":[{"internalType":"uint256","name":"gasPerByte","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"gasPrice","outputs":[{"internalType":"uint256","name":"defaultGasPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"gasPriceOracle","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegisterTransmuterAMBData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"nativeFeedOracle","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"nativePrice","outputs":[{"internalType":"uint256","name":"defaultNativePrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"superRegistry","outputs":[{"internalType":"contract ISuperRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"swapGasUsed","outputs":[{"internalType":"uint256","name":"gasForSwap","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"timelockCost","outputs":[{"internalType":"uint256","name":"gasForTimelock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"updateDepositGasUsed","outputs":[{"internalType":"uint256","name":"gasForUpdateDeposit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"extraDataForTransmuter_","type":"bytes"}],"name":"updateRegisterAERC20Params","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId_","type":"uint64"},{"internalType":"uint256","name":"configType_","type":"uint256"},{"internalType":"bytes","name":"config_","type":"bytes"}],"name":"updateRemoteChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"updateWithdrawGasUsed","outputs":[{"internalType":"uint256","name":"gasForUpdateWithdraw","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"withdrawGasUsed","outputs":[{"internalType":"uint256","name":"gasForWithdraw","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c06040523480156200001157600080fd5b5060405162006101380380620061018339810160408190526200003491620000a4565b6001600160a01b0381166200005c5760405163538ba4f960e01b815260040160405180910390fd5b6001600160401b034611156200008557604051637ecdf93360e01b815260040160405180910390fd5b6001600160401b03461660a0526001600160a01b0316608052620000d6565b600060208284031215620000b757600080fd5b81516001600160a01b0381168114620000cf57600080fd5b9392505050565b60805160a051615f726200018f600039600081816104a7015281816106600152818161110c01528181611f98015281816121cf0152818161248101528181612714015281816132be015281816138de01528181613920015281816139a80152613cad0152600081816102e50152818161069a015281816108b50152818161124901528181611590015281816116cd01528181611bcf0152818161220b015281816124bd0152818161265e015261352c0152615f726000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80637abae2511161011a578063b9694b52116100ad578063d8bb4f4e1161007c578063d8bb4f4e146105a6578063da163637146105c6578063ea7a8392146105ce578063f3afdd88146105e1578063f3d80846146105f457600080fd5b8063b9694b521461055a578063c2085f461461056d578063c97c55b014610580578063d70139741461059357600080fd5b80639d57d64e116100e95780639d57d64e14610501578063a8a0838914610514578063a9ce464814610527578063b1752d591461054757600080fd5b80637abae2511461046d5780637f7aecb51461048257806385e1f4d0146104a2578063904b1a28146104e157600080fd5b80634545fc311161019d57806353d69edc1161016c57806353d69edc146103c4578063596703e7146103d957806361d26cae146103ec5780637504988b1461041f578063786c69f31461044d57600080fd5b80634545fc311461033b5780634786b4241461035b57806349c3af451461037b5780634c75c0d8146103a457600080fd5b80631f864be3116101d95780631f864be3146102bf57806324c73dda146102e05780633283166a1461030757806336c7fe1d1461032857600080fd5b80630292540b1461020b57806310c5fbe41461023e57806312c4da861461025e5780631f5ae58f1461029f575b600080fd5b61022b61021936600461414e565b600c6020526000908152604090205481565b6040519081526020015b60405180910390f35b61022b61024c36600461414e565b60046020526000908152604090205481565b61028761026c36600461414e565b6000602081905290815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610235565b61022b6102ad36600461414e565b600b6020526000908152604090205481565b6102d26102cd366004614341565b610607565b604051610235929190614449565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b61031a6103153660046144e4565b61082b565b6040516102359291906145af565b61022b6103363660046145e6565b61088a565b61022b61034936600461414e565b60076020526000908152604090205481565b61022b61036936600461414e565b60086020526000908152604090205481565b61028761038936600461414e565b6001602052600090815260409020546001600160a01b031681565b61022b6103b236600461414e565b60056020526000908152604090205481565b6103cc610a7b565b6040516102359190614649565b61022b6103e736600461465c565b610b0d565b6103ff6103fa36600461468d565b610f28565b604080519485526020850193909352918301526060820152608001610235565b61043261042d3660046146f0565b6110c7565b60408051938452602084019290925290820152606001610235565b61022b61045b36600461414e565b60036020526000908152604090205481565b61048061047b366004614725565b611226565b005b61022b61049036600461414e565b60066020526000908152604090205481565b6104c97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160401b039091168152602001610235565b61022b6104ef36600461414e565b60096020526000908152604090205481565b61048061050f36600461477d565b611367565b610480610522366004614817565b6114ab565b61022b61053536600461414e565b60026020526000908152604090205481565b61022b6105553660046145e6565b611557565b61048061056836600461485a565b61156d565b61048061057b36600461488e565b6116aa565b6103ff61058e36600461468d565b6117ef565b6103ff6105a136600461468d565b611963565b61022b6105b436600461414e565b600a6020526000908152604090205481565b6103cc611b1e565b6104806105dc366004614910565b611bac565b6103ff6105ef36600461468d565b611dbf565b6104326106023660046146f0565b611f53565b835160009060609082816001600160401b038111156106285761062861416b565b604051908082528060200260200182016040528015610651578160200160208202803683370190505b509050866001600160401b03167f00000000000000000000000000000000000000000000000000000000000000006001600160401b03161461081f5760005b8281101561081d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630eff125d8a83815181106106d9576106d96149a9565b60200260200101516040518263ffffffff1660e01b8152600401610706919060ff91909116815260200190565b602060405180830381865afa158015610723573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074791906149df565b6001600160a01b031663ea98b1478989898581518110610769576107696149a9565b60200260200101516040518463ffffffff1660e01b815260040161078f939291906149fc565b602060405180830381865afa1580156107ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d09190614a3a565b8282815181106107e2576107e26149a9565b602002602001018181525050818181518110610800576108006149a9565b6020026020010151856108139190614a69565b9450600101610690565b505b91505094509492505050565b60006060600080600061084089898989612092565b92509250925060405180604001604052808481526020018381525060405160200161086b9190614ab8565b60408051601f1981840301815291905290999098509650505050505050565b6000606084156109e95760405163bffc1e1360e01b81526001600160401b03841660048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bffc1e1390602401602060405180830381865afa158015610904573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109289190614a3a565b90506000816001600160401b038111156109445761094461416b565b60405190808252806020026020018201604052801561096d578160200160208202803683370190505b50905060005b828110156109a357600019828281518110610990576109906149a9565b6020908102919091010152600101610973565b5060405180606001604052806000198152602001828152602001828152506040516020016109d19190614b3b565b60405160208183030381529060405292505050610a30565b506040805160608082018352600019808352602080840182815293850182815285519182019290925292518385015251828201528251808303909101815260809091019091525b610a7084846040518060400160405280600019815260200185815250604051602001610a5c9190614b7e565b6040516020818303038152906040526123bc565b9150505b9392505050565b6060600d8054610a8a90614ba3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab690614ba3565b8015610b035780601f10610ad857610100808354040283529160200191610b03565b820191906000526020600020905b815481529060010190602001808311610ae657829003601f168201915b5050505050905090565b604080516101008101825260008082526020820181905291810182905260608082018190526080820181905260a0820183905260c0820183905260e08201526000610b777f55b101fc856aff484166c46ad33bc74831c135693c159b0092bb3b72254ffb6b612645565b9050806001600160a01b03166313c02a596040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdb9190614a3a565b808352841115610bfe576040516355da2ca360e11b815260040160405180910390fd5b6040516336445ffd60e01b8152600481018590526001600160a01b038216906336445ffd90602401602060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c679190614a3a565b602083015260405163361ad42b60e01b8152600481018590526001600160a01b0382169063361ad42b90602401600060405180830381865afa158015610cb1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cd99190810190614c1c565b6060830152602082015160c081811c9084015260ff601082901c811660a085015260089190911c166040830181905215610d17575060009392505050565b8160a0015160ff16600103610d8c5760008260600151806020019051810190610d409190614e40565b60408051606081018252855181526020808401518183015282840151828401529151929350610d7192909101614b3b565b60408051601f19818403018152919052606084015250610df7565b60008260600151806020019051810190610da69190614fc9565b60408051606080820183528651808352602085810151818501908152958501519385019384528451908101919091529351848401529051838201528151808403820181526080909301909152840152505b604051636c181b2760e11b8152600481018590526001600160a01b0382169063d830364e90602401600060405180830381865afa158015610e3c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e64919081019061508f565b608083015260408051808201918290526336445ffd60e01b90915260448101859052806001600160a01b0383166336445ffd60648301602060405180830381865afa158015610eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610edb9190614a3a565b81526060840151602091820152604051610ef6929101614b7e565b60408051601f1981840301815291905260e08301819052608083015160c0840151610f20926123bc565b949350505050565b6000806000806000610f47600080516020615f1d833981519152612645565b6040805160018082528183019092529192506000919060208083019080368337019050509050610f7d6040890160208a0161414e565b81600081518110610f9057610f906149a9565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b610fc961403b565b815260200190600190039081610fc1579050509050610feb60408b018b61511d565b610ff4906152f0565b81600081518110611007576110076149a9565b602002602001018190525061109c6040518060e00160405280600081526020018581526020018c806000019061103d91906152fc565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060208101859052604081018490526001600160a01b03871660608201528b15156080909101526126d7565b91995097509550876110ae8789614a69565b6110b89190614a69565b94505050505092959194509250565b6000806000806110e4600080516020615f1d833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000008160008151811061113e5761113e6149a9565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b6111776140ca565b81526020019060019003908161116f579050509050611196898061511d565b61119f906155cb565b816000815181106111b2576111b26149a9565b602002602001018190525060606112066040518060e0016040528060008152602001868152602001838152602001848152602001858152602001876001600160a01b031681526020018b15158152506126d7565b91995090975061121890508789614a69565b955050505050509250925092565b6040516321f8a72160e01b8152600080516020615edd83398151915260048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa158015611298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bc91906149df565b604051632474521560e21b8152600080516020615efd83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133a91906155d7565b61135757604051633108430360e11b815260040160405180910390fd5b611362838383612c86565b505050565b61137e600080516020615edd833981519152612645565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa1580156113c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e891906155d7565b61140557604051633721555560e21b815260040160405180910390fd5b8260008190036114285760405163021b4ea160e01b815260040160405180910390fd5b80821461144857604051634456f5e960e11b815260040160405180910390fd5b60005b818110156114a35761149b868683818110611468576114686149a9565b905060200201602081019061147d919061414e565b85858481811061148f5761148f6149a9565b90506101a00201613069565b60010161144b565b505050505050565b6114c2600080516020615edd833981519152612645565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa158015611508573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152c91906155d7565b61154957604051633721555560e21b815260040160405180910390fd5b6115538282613069565b5050565b6000610f208261156886868661088a565b6132a5565b6040516321f8a72160e01b8152600080516020615edd83398151915260048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa1580156115df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160391906149df565b604051632474521560e21b8152600080516020615efd83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa15801561165d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168191906155d7565b61169e57604051633108430360e11b815260040160405180910390fd5b600d611553828261563c565b6040516321f8a72160e01b8152600080516020615edd83398151915260048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174091906149df565b604051632474521560e21b8152600080516020615efd83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa15801561179a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117be91906155d7565b6117db57604051633108430360e11b815260040160405180910390fd5b6117e88585858585613341565b5050505050565b600080600080600061180e600080516020615f1d833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090506118446040890160208a0161414e565b81600081518110611857576118576149a9565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b6118906140ca565b8152602001906001900390816118885790505090506118b260408b018b61511d565b6118bb906155cb565b816000815181106118ce576118ce6149a9565b602002602001018190525061109c6040518060e00160405280600081526020018581526020018c806000019061190491906152fc565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060208101849052604081018590526001600160a01b03871660608201528b15156080909101526126d7565b60008080808061197660208801886152fc565b90509050600080600080611997600080516020615f1d833981519152612645565b9050606060005b86811015611af757611ac46040518060e001604052808381526020018f80602001906119ca91906152fc565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060000190611a1f91906152fc565b85818110611a2f57611a2f6149a9565b9050602002810190611a4191906152fc565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018481526020018f8060400190611a9c91906152fc565b611aa5916156fb565b8152602001856001600160a01b031681526020018e15158152506126d7565b91975095509350611ad5868c614a69565b9a50611ae1858b614a69565b9950611aed848a614a69565b985060010161199e565b5089611b03898b614a69565b611b0d9190614a69565b965050505050505092959194509250565b600d8054611b2b90614ba3565b80601f0160208091040260200160405190810160405280929190818152602001828054611b5790614ba3565b8015611ba45780601f10611b7957610100808354040283529160200191611ba4565b820191906000526020600020905b815481529060010190602001808311611b8757829003601f168201915b505050505081565b6040516321f8a72160e01b8152600080516020615edd83398151915260048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa158015611c1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4291906149df565b604051632474521560e21b8152600080516020615efd83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc091906155d7565b611cdd57604051633108430360e11b815260040160405180910390fd5b846000819003611d005760405163021b4ea160e01b815260040160405180910390fd5b8084148015611d0e57508082145b611d2b57604051634456f5e960e11b815260040160405180910390fd5b60005b81811015611db557611dad888883818110611d4b57611d4b6149a9565b9050602002016020810190611d60919061414e565b878784818110611d7257611d726149a9565b9050602002810190611d8491906152fc565b878786818110611d9657611d966149a9565b9050602002810190611da891906152fc565b613341565b600101611d2e565b5050505050505050565b600080808080611dd260208801886152fc565b90509050600080600080611df3600080516020615f1d833981519152612645565b9050606060005b86811015611af757611f206040518060e001604052808381526020018f8060200190611e2691906152fc565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060000190611e7b91906152fc565b85818110611e8b57611e8b6149a9565b9050602002810190611e9d91906152fc565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060400190611ef291906152fc565b611efb9161576e565b8152602001848152602001856001600160a01b031681526020018e15158152506126d7565b91975095509350611f31868c614a69565b9a50611f3d858b614a69565b9950611f49848a614a69565b9850600101611dfa565b600080600080611f70600080516020615f1d833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600081518110611fca57611fca6149a9565b6001600160401b039290921660209283029190910190910152604080516001808252818301909252600091816020015b61200261403b565b815260200190600190039081611ffa579050509050612021888061511d565b61202a906152f0565b8160008151811061203d5761203d6149a9565b60200260200101819052506060806112066040518060e0016040528060008152602001868152602001838152602001848152602001858152602001876001600160a01b031681526020018b15158152506126d7565b606080600080848060200190518101906120ac91906157d5565b9050868682602001516040516020016120c793929190615861565b60408051601f1981840301815291815260208381019290925280518883028181018401909252888152889261211d928c92918c9186918291908501908490808284376000920191909152508b925061341b915050565b9350806001600160401b038111156121375761213761416b565b604051908082528060200260200182016040528015612160578160200160208202803683370190505b509450600060405180604001604052806000198152602001888051906020012060405160200161219291815260200190565b60408051601f198184030181529181529152516121b29190602001614b7e565b6040516020818303038152906040529050896001600160401b03167f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316146123af5760005b828110156123ad5760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630eff125d8c8c8581811061224a5761224a6149a9565b905060200201602081019061225f91906158b1565b6040516001600160e01b031960e084901b16815260ff9091166004820152602401602060405180830381865afa15801561229d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c191906149df565b6001600160a01b031663ea98b1478d846000036122fd57876040516020016122e99190614b7e565b6040516020818303038152906040526122ff565b855b8a8681518110612311576123116149a9565b60200260200101516040518463ffffffff1660e01b8152600401612337939291906149fc565b602060405180830381865afa158015612354573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123789190614a3a565b90506123848187614a69565b955080888381518110612399576123996149a9565b6020908102919091010152506001016121ff565b505b5050509450945094915050565b8251600090816123cd85878661341b565b90506000848060200190518101906123e591906157d5565b90508681602001516040516020016123fe9291906158ce565b6040516020818303038152906040528160200181905250600060405180604001604052806000198152602001878051906020012060405160200161244491815260200190565b60408051601f198184030181529181529152516124649190602001614b7e565b6040516020818303038152906040529050866001600160401b03167f00000000000000000000000000000000000000000000000000000000000000006001600160401b03161461263a5760005b848110156126385760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630eff125d8b84815181106124fc576124fc6149a9565b60200260200101516040518263ffffffff1660e01b8152600401612529919060ff91909116815260200190565b602060405180830381865afa158015612546573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256a91906149df565b6001600160a01b031663ea98b1478a846000036125a657866040516020016125929190614b7e565b6040516020818303038152906040526125a8565b855b8886815181106125ba576125ba6149a9565b60200260200101516040518463ffffffff1660e01b81526004016125e0939291906149fc565b602060405180830381865afa1580156125fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126219190614a3a565b905061262d8188614a69565b9650506001016124b1565b505b505050509392505050565b6040516321f8a72160e01b8152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa1580156126ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d191906149df565b92915050565b60008060006127106040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160401b03168660200151876000015181518110612756576127566149a9565b60200260200101516001600160401b03161415905060008260400181815250506000808760600151511190506000816127b8576127b388608001518960000151815181106127a6576127a66149a9565b602002602001015161367e565b6127e2565b6127e288606001518960000151815181106127d5576127d56149a9565b6020026020010151613758565b9050826127f0576000612820565b612820886040015189602001518a6000015181518110612812576128126149a9565b6020026020010151836123bc565b606085015281612831576001612856565b6060880151885181518110612848576128486149a9565b602002602001015160000151515b6020850152606084015161286a9087614a69565b95506000826128a6576128a189608001518a6000015181518110612890576128906149a9565b6020026020010151608001516137e8565b6128ca565b60608901518951815181106128bd576128bd6149a9565b6020026020010151608001515b90508860c0015115612a96576128df81613868565b6128e99089614a69565b97508315612a915761292089602001518a600001518151811061290e5761290e6149a9565b602002602001015186602001516138b1565b856040018181516129319190614a69565b905250600083156129a55760005b866020015181101561299f5760608b01518b5181518110612962576129626149a9565b602002602001015160e00151818151811061297f5761297f6149a9565b6020026020010151612997576129948261591f565b91505b60010161293f565b506129d8565b60808a01518a51815181106129bc576129bc6149a9565b602002602001015160e001516129d8576129d58161591f565b90505b6129e1816138d4565b6129eb9089614a69565b9750600084612a2957612a248b608001518c6000015181518110612a1157612a116149a9565b602002602001015160c00151151561394e565b612a4d565b60608b01518b5181518110612a4057612a406149a9565b602002602001015160c001515b9050612a7a8b602001518c6000015181518110612a6c57612a6c6149a9565b602002602001015182613999565b87604001818151612a8b9190614a69565b90525050505b612beb565b8215612b3b5760005b8560200151811015612b3557612b198a606001518b6000015181518110612ac857612ac86149a9565b6020026020010151600001518281518110612ae557612ae56149a9565b60200260200101518b602001518c6000015181518110612b0757612b076149a9565b60200260200101518c60a00151613a56565b86604001818151612b2a9190614a69565b905250600101612a9f565b50612ba5565b612b9089608001518a6000015181518110612b5857612b586149a9565b6020026020010151600001518a602001518b6000015181518110612b7e57612b7e6149a9565b60200260200101518b60a00151613a56565b85604001818151612ba19190614a69565b9052505b8315612beb57612bd689602001518a6000015181518110612bc857612bc86149a9565b602002602001015182613b52565b85604001818151612be79190614a69565b9052505b83612bf7576000612c2b565b612c2b8960c001518a602001518b6000015181518110612c1957612c196149a9565b60200260200101518760200151613bfa565b85604001818151612c3c9190614a69565b905250602089015189518151612c6f9291908110612c5c57612c5c6149a9565b6020026020010151866040015186613c46565b612c799087614a69565b9799969850505050505050565b81600103612d2b57600081806020019051810190612ca491906149df565b90506001600160a01b03811615612cf4576000612cc082613d09565b60ff1690506008811080612cd45750601281115b15612cf2576040516333339aa360e11b815260040160405180910390fd5b505b6001600160401b038416600090815260208190526040902080546001600160a01b0319166001600160a01b03929092169190911790555b81600203612dd057600081806020019051810190612d4991906149df565b90506001600160a01b03811615612d99576000612d6582613d09565b60ff1690506008811080612d795750601281115b15612d97576040516333339aa360e11b815260040160405180910390fd5b505b6001600160401b038416600090815260016020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b81600303612e065780806020019051810190612dec9190614a3a565b6001600160401b0384166000908152600260205260409020555b81600403612e3c5780806020019051810190612e229190614a3a565b6001600160401b0384166000908152600360205260409020555b81600503612e725780806020019051810190612e589190614a3a565b6001600160401b0384166000908152600560205260409020555b81600603612ea85780806020019051810190612e8e9190614a3a565b6001600160401b0384166000908152600660205260409020555b81600703612ede5780806020019051810190612ec49190614a3a565b6001600160401b0384166000908152600760205260409020555b81600803612f145780806020019051810190612efa9190614a3a565b6001600160401b0384166000908152600860205260409020555b81600903612f4a5780806020019051810190612f309190614a3a565b6001600160401b0384166000908152600960205260409020555b81600a03612f805780806020019051810190612f669190614a3a565b6001600160401b0384166000908152600a60205260409020555b81600b03612fb65780806020019051810190612f9c9190614a3a565b6001600160401b0384166000908152600b60205260409020555b81600c03612fec5780806020019051810190612fd29190614a3a565b6001600160401b0384166000908152600c60205260409020555b81600d0361302257808060200190518101906130089190614a3a565b6001600160401b0384166000908152600460205260409020555b81836001600160401b03167fae3dadf141b0383d3b4db666b2fc32179836af27e11a3e8f07c3ef8da82e59308360405161305c9190614649565b60405180910390a3505050565b60006130786020830183615938565b6001600160a01b03161461310c5760006130956020830183615938565b905060006130a282613d09565b60ff16905060088110806130b65750601281115b156130d4576040516333339aa360e11b815260040160405180910390fd5b506001600160401b038316600090815260208190526040902080546001600160a01b0319166001600160a01b03929092169190911790555b600061311e6040830160208401615938565b6001600160a01b0316146131b557600061313e6040830160208401615938565b9050600061314b82613d09565b60ff169050600881108061315f5750601281115b1561317d576040516333339aa360e11b815260040160405180910390fd5b506001600160401b038316600090815260016020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b6001600160401b0382166000908152600260209081526040808320818501359055600382528083206060850135905560058252808320608085013590556006825280832060a085013590556007825280832060c085013590556008825280832060e08501359055600982528083206101008501359055600a82528083206101208501359055600b82528083206101408501359055600c825280832061016085013590556004909152908190206101808301359055517fdee9f507a37f922d400f1af8b89ddcf4419171e4570e9bc6b83e49659d6a26eb906132999084908490615955565b60405180910390a15050565b6000816000036132b7575060006126d1565b60006132e27f0000000000000000000000000000000000000000000000000000000000000000613d6d565b6132ec9084615a21565b9050806000036133005760009150506126d1565b600061330b85613d6d565b90508060000361332e57604051634c8f99a760e11b815260040160405180910390fd5b6133388183615a38565b95945050505050565b8260008190036133645760405163021b4ea160e01b815260040160405180910390fd5b80821461338457604051634456f5e960e11b815260040160405180910390fd5b60005b818110156134125761340a878787848181106133a5576133a56149a9565b905060200201358686858181106133be576133be6149a9565b90506020028101906133d09190615a5a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c8692505050565b600101613387565b50505050505050565b606060008280602001905181019061343391906157d5565b905083816020015160405160200161344c9291906158ce565b60408051601f1981840301815291815260208381019290925285516001600160401b03881660009081526009845282812054925191939091839161349291879101614b7e565b604051602081830303815290604052516134ac9190615a21565b905060006134bb8360a0615a21565b9050836001600160401b038111156134d5576134d561416b565b60405190808252806020026020018201604052801561350857816020015b60608152602001906001900390816134f35790505b50955060005b84811015613671576000816000036135265783613528565b825b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630eff125d8b848151811061356b5761356b6149a9565b60200260200101516040518263ffffffff1660e01b8152600401613598919060ff91909116815260200190565b602060405180830381865afa1580156135b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135d991906149df565b6001600160a01b03166325fc6dd0826040518263ffffffff1660e01b815260040161360691815260200190565b600060405180830381865afa158015613623573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261364b9190810190614c1c565b88838151811061365d5761365d6149a9565b60209081029190910101525060010161350e565b5050505050509392505050565b60606000604051806101400160405280613696613ea6565b815260200184600001518152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460c00151151581526020018460e00151151581526020018461010001516001600160a01b031681526020018461014001518152506040516020016137129190615b0d565b60408051601f198184030181528282018252600019835260208381018290529151909350613741929101614b7e565b604051602081830303815290604052915050919050565b60606000604051806101400160405280613770613ea6565b815260200184600001518152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460c0015181526020018460e0015181526020018461010001516001600160a01b031681526020018461014001518152506040516020016137129190615c3f565b604080516001808252818301909252606091816020015b6040805160c0810182526060808252600060208084018290529383018190529082018190526080820181905260a082015282526000199092019101816137ff5790505090508181600081518110613858576138586149a9565b6020026020010181905250919050565b8051600090815b818110156138aa57838181518110613889576138896149a9565b602002602001015160a00151836138a09190614a69565b925060010161386f565b5050919050565b6001600160401b038216600090815260036020526040812054610a749083615a21565b6001600160401b037f0000000000000000000000000000000000000000000000000000000000000000166000908152600a602052604081205481906139199084615a21565b90506139447f0000000000000000000000000000000000000000000000000000000000000000613f42565b610a749082615a21565b604080516001808252818301909252606091602080830190803683370190505090508181600081518110613984576139846149a9565b91151560209283029190910190910152919050565b600080836001600160401b03167f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316036139df5760009150506126d1565b825160005b81811015613a1f578481815181106139fe576139fe6149a9565b602002602001015115613a1757613a148361591f565b92505b6001016139e4565b5081600003613a33576000925050506126d1565b6001600160401b0385166000908152600260205260409020546133389083615a21565b600080613a6285614007565b5060405163596db71760e01b815263ffffffff82166004820152909250600091506001600160a01b0385169063596db71790602401602060405180830381865afa158015613ab4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ad891906155d7565b905080158015613aee575063ffffffff82166002145b15613b1d576001600160401b0385166000908152600b6020526040902054613b169084614a69565b9250613b49565b8015613b49576001600160401b0385166000908152600c6020526040902054613b469084614a69565b92505b50509392505050565b8051600090815b81811015613bf257838181518110613b7357613b736149a9565b602002602001015160000151516000148015613bbf575060006001600160a01b0316848281518110613ba757613ba76149a9565b6020026020010151602001516001600160a01b031614155b15613bea576001600160401b038516600090815260046020526040902054613be79084614a69565b92505b600101613b59565b505092915050565b60008084613c20576001600160401b038416600090815260066020526040902054613c3a565b6001600160401b0384166000908152600560205260409020545b9050610a708382615a21565b600080613c5285613f42565b613c5c9085615a21565b905080600003613c70576000915050610a74565b82613c7c579050610a74565b6000613c8786613d6d565b613c919083615a21565b905080600003613ca657600092505050610a74565b6000613cd17f0000000000000000000000000000000000000000000000000000000000000000613d6d565b905080600003613cf457604051634c8f99a760e11b815260040160405180910390fd5b613cfe8183615a38565b979650505050505050565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d49573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d19190615d52565b6001600160401b0381166000908152602081905260408120546001600160a01b03168015613e8957806001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015613def575060408051601f3d908101601f19168201909252613dec91810190615d89565b60015b15613e895760008413613e155760405163119d4d6b60e11b815260040160405180910390fd5b81600003613e36576040516376685d7f60e11b815260040160405180910390fd5b6000613e4187613d09565b60ff1690506007198101613e5c575092979650505050505050565b613e67600882615dd9565b613e7290600a615ed0565b613e7c9086615a38565b9998505050505050505050565b50506001600160401b031660009081526007602052604090205490565b6000613ed17f55b101fc856aff484166c46ad33bc74831c135693c159b0092bb3b72254ffb6b612645565b6001600160a01b03166313c02a596040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f329190614a3a565b9050613f3d8161591f565b905090565b6001600160401b0381166000908152600160205260408120546001600160a01b03168015613fea57806001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015613fc4575060408051601f3d908101601f19168201909252613fc191810190615d89565b60015b15613fea5760008413613e155760405163119d4d6b60e11b815260040160405180910390fd5b50506001600160401b031660009081526008602052604090205490565b8060a081901c60c082901c60008190036140345760405163030042b760e01b815260040160405180910390fd5b9193909250565b6040518061016001604052806000815260200160008152602001600081526020016000815260200161409b6040805160c081018252606080825260006020830181905292820183905281018290526080810182905260a081019190915290565b81526060602082018190526000604083018190528183018190526080830181905260a083015260c09091015290565b604051806101600160405280606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016060815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081525090565b6001600160401b038116811461414b57600080fd5b50565b60006020828403121561416057600080fd5b8135610a7481614136565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156141a3576141a361416b565b60405290565b60405161014081016001600160401b03811182821017156141a3576141a361416b565b60405161016081016001600160401b03811182821017156141a3576141a361416b565b604051601f8201601f191681016001600160401b03811182821017156142175761421761416b565b604052919050565b60006001600160401b038211156142385761423861416b565b5060051b60200190565b60ff8116811461414b57600080fd5b600082601f83011261426257600080fd5b813560206142776142728361421f565b6141ef565b8083825260208201915060208460051b87010193508684111561429957600080fd5b602086015b848110156142be5780356142b181614242565b835291830191830161429e565b509695505050505050565b60006001600160401b038211156142e2576142e261416b565b50601f01601f191660200190565b600082601f83011261430157600080fd5b813561430f614272826142c9565b81815284602083860101111561432457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561435757600080fd5b84356001600160401b038082111561436e57600080fd5b61437a88838901614251565b9550602091508187013561438d81614136565b94506040870135818111156143a157600080fd5b6143ad89828a016142f0565b9450506060870135818111156143c257600080fd5b8701601f810189136143d357600080fd5b80356143e16142728261421f565b81815260059190911b8201840190848101908b83111561440057600080fd5b8584015b838110156144385780358681111561441c5760008081fd5b61442a8e89838901016142f0565b845250918601918601614404565b50989b979a50959850505050505050565b60006040820184835260206040602085015281855180845260608601915060208701935060005b8181101561448c57845183529383019391830191600101614470565b5090979650505050505050565b60008083601f8401126144ab57600080fd5b5081356001600160401b038111156144c257600080fd5b6020830191508360208260051b85010111156144dd57600080fd5b9250929050565b600080600080606085870312156144fa57600080fd5b843561450581614136565b935060208501356001600160401b038082111561452157600080fd5b61452d88838901614499565b9095509350604087013591508082111561454657600080fd5b50614553878288016142f0565b91505092959194509250565b60005b8381101561457a578181015183820152602001614562565b50506000910152565b6000815180845261459b81602086016020860161455f565b601f01601f19169290920160200192915050565b828152604060208201526000610f206040830184614583565b801515811461414b57600080fd5b80356145e1816145c8565b919050565b6000806000606084860312156145fb57600080fd5b8335614606816145c8565b925060208401356001600160401b0381111561462157600080fd5b61462d86828701614251565b925050604084013561463e81614136565b809150509250925092565b602081526000610a746020830184614583565b60006020828403121561466e57600080fd5b5035919050565b60006060828403121561468757600080fd5b50919050565b600080604083850312156146a057600080fd5b82356001600160401b038111156146b657600080fd5b6146c285828601614675565b92505060208301356146d3816145c8565b809150509250929050565b60006020828403121561468757600080fd5b6000806040838503121561470357600080fd5b82356001600160401b0381111561471957600080fd5b6146c2858286016146de565b60008060006060848603121561473a57600080fd5b833561474581614136565b92506020840135915060408401356001600160401b0381111561476757600080fd5b614773868287016142f0565b9150509250925092565b6000806000806040858703121561479357600080fd5b84356001600160401b03808211156147aa57600080fd5b6147b688838901614499565b909650945060208701359150808211156147cf57600080fd5b818701915087601f8301126147e357600080fd5b8135818111156147f257600080fd5b8860206101a08302850101111561480857600080fd5b95989497505060200194505050565b6000808284036101c081121561482c57600080fd5b833561483781614136565b92506101a0601f198201121561484c57600080fd5b506020830190509250929050565b60006020828403121561486c57600080fd5b81356001600160401b0381111561488257600080fd5b610f20848285016142f0565b6000806000806000606086880312156148a657600080fd5b85356148b181614136565b945060208601356001600160401b03808211156148cd57600080fd5b6148d989838a01614499565b909650945060408801359150808211156148f257600080fd5b506148ff88828901614499565b969995985093965092949392505050565b6000806000806000806060878903121561492957600080fd5b86356001600160401b038082111561494057600080fd5b61494c8a838b01614499565b9098509650602089013591508082111561496557600080fd5b6149718a838b01614499565b9096509450604089013591508082111561498a57600080fd5b5061499789828a01614499565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038116811461414b57600080fd5b80516145e1816149bf565b6000602082840312156149f157600080fd5b8151610a74816149bf565b6001600160401b0384168152606060208201526000614a1e6060830185614583565b8281036040840152614a308185614583565b9695505050505050565b600060208284031215614a4c57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156126d1576126d1614a53565b60008151808452602080850194506020840160005b83811015614aad57815187529582019590820190600101614a91565b509495945050505050565b600060208083528351604082850152614ad46060850182614a7c565b82860151601f198683038101604088015281518084529293509084019183850190600581901b8501860160005b82811015614b2d5784878303018452614b1b828751614583565b95880195938801939150600101614b01565b509998505050505050505050565b60208152815160208201526000602083015160606040840152614b616080840182614a7c565b90506040840151601f198483030160608501526133388282614a7c565b602081528151602082015260006020830151604080840152610f206060840182614583565b600181811c90821680614bb757607f821691505b60208210810361468757634e487b7160e01b600052602260045260246000fd5b600082601f830112614be857600080fd5b8151614bf6614272826142c9565b818152846020838601011115614c0b57600080fd5b610f2082602083016020870161455f565b600060208284031215614c2e57600080fd5b81516001600160401b03811115614c4457600080fd5b610f2084828501614bd7565b600082601f830112614c6157600080fd5b81516020614c716142728361421f565b8083825260208201915060208460051b870101935086841115614c9357600080fd5b602086015b848110156142be5780518352918301918301614c98565b600060c08284031215614cc157600080fd5b614cc9614181565b905081516001600160401b03811115614ce157600080fd5b614ced84828501614bd7565b8252506020820151614cfe816149bf565b60208201526040820151614d11816149bf565b60408201526060820151614d2481614242565b60608201526080820151614d3781614136565b8060808301525060a082015160a082015292915050565b600082601f830112614d5f57600080fd5b81516020614d6f6142728361421f565b82815260059290921b84018101918181019086841115614d8e57600080fd5b8286015b848110156142be5780516001600160401b03811115614db15760008081fd5b614dbf8986838b0101614caf565b845250918301918301614d92565b80516145e1816145c8565b600082601f830112614de957600080fd5b81516020614df96142728361421f565b8083825260208201915060208460051b870101935086841115614e1b57600080fd5b602086015b848110156142be578051614e33816145c8565b8352918301918301614e20565b600060208284031215614e5257600080fd5b81516001600160401b0380821115614e6957600080fd5b908301906101408286031215614e7e57600080fd5b614e866141a9565b82518152602083015182811115614e9c57600080fd5b614ea887828601614c50565b602083015250604083015182811115614ec057600080fd5b614ecc87828601614c50565b604083015250606083015182811115614ee457600080fd5b614ef087828601614c50565b606083015250608083015182811115614f0857600080fd5b614f1487828601614c50565b60808301525060a083015182811115614f2c57600080fd5b614f3887828601614d4e565b60a08301525060c083015182811115614f5057600080fd5b614f5c87828601614dd8565b60c08301525060e083015182811115614f7457600080fd5b614f8087828601614dd8565b60e083015250610100614f948185016149d4565b908201526101208381015183811115614fac57600080fd5b614fb888828701614bd7565b918301919091525095945050505050565b600060208284031215614fdb57600080fd5b81516001600160401b0380821115614ff257600080fd5b90830190610140828603121561500757600080fd5b61500f6141a9565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a08301518281111561504d57600080fd5b61505987828601614caf565b60a08301525061506b60c08401614dcd565b60c082015261507c60e08401614dcd565b60e0820152610100614f948185016149d4565b600060208083850312156150a257600080fd5b82516001600160401b038111156150b857600080fd5b8301601f810185136150c957600080fd5b80516150d76142728261421f565b81815260059190911b820183019083810190878311156150f657600080fd5b928401925b82841015613cfe57835161510e81614242565b825292840192908401906150fb565b6000823561015e1983360301811261513457600080fd5b9190910192915050565b80356145e1816149bf565b600060c0828403121561515b57600080fd5b615163614181565b905081356001600160401b0381111561517b57600080fd5b615187848285016142f0565b8252506020820135615198816149bf565b602082015260408201356151ab816149bf565b604082015260608201356151be81614242565b606082015260808201356151d181614136565b8060808301525060a082013560a082015292915050565b600061016082840312156151fb57600080fd5b6152036141cc565b90508135815260208201356020820152604082013560408201526060820135606082015260808201356001600160401b038082111561524157600080fd5b61524d85838601615149565b608084015260a084013591508082111561526657600080fd5b615272858386016142f0565b60a084015261528360c085016145d6565b60c084015261529460e085016145d6565b60e084015261010091506152a982850161513e565b8284015261012091506152bd82850161513e565b82840152610140915081840135818111156152d757600080fd5b6152e3868287016142f0565b8385015250505092915050565b60006126d136836151e8565b6000808335601e1984360301811261531357600080fd5b8301803591506001600160401b0382111561532d57600080fd5b6020019150600581901b36038213156144dd57600080fd5b600082601f83011261535657600080fd5b813560206153666142728361421f565b8083825260208201915060208460051b87010193508684111561538857600080fd5b602086015b848110156142be578035835291830191830161538d565b600082601f8301126153b557600080fd5b813560206153c56142728361421f565b82815260059290921b840181019181810190868411156153e457600080fd5b8286015b848110156142be5780356001600160401b038111156154075760008081fd5b6154158986838b0101615149565b8452509183019183016153e8565b600082601f83011261543457600080fd5b813560206154446142728361421f565b8083825260208201915060208460051b87010193508684111561546657600080fd5b602086015b848110156142be57803561547e816145c8565b835291830191830161546b565b6000610160828403121561549e57600080fd5b6154a66141cc565b905081356001600160401b03808211156154bf57600080fd5b6154cb85838601615345565b835260208401359150808211156154e157600080fd5b6154ed85838601615345565b6020840152604084013591508082111561550657600080fd5b61551285838601615345565b6040840152606084013591508082111561552b57600080fd5b61553785838601615345565b6060840152608084013591508082111561555057600080fd5b61555c858386016153a4565b608084015260a084013591508082111561557557600080fd5b615581858386016142f0565b60a084015260c084013591508082111561559a57600080fd5b6155a685838601615423565b60c084015260e08401359150808211156155bf57600080fd5b61529485838601615423565b60006126d1368361548b565b6000602082840312156155e957600080fd5b8151610a74816145c8565b601f821115611362576000816000526020600020601f850160051c8101602086101561561d5750805b601f850160051c820191505b818110156114a357828155600101615629565b81516001600160401b038111156156555761565561416b565b615669816156638454614ba3565b846155f4565b602080601f83116001811461569e57600084156156865750858301515b600019600386901b1c1916600185901b1785556114a3565b600085815260208120601f198616915b828110156156cd578886015182559484019460019091019084016156ae565b50858210156156eb5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006157096142728461421f565b80848252602080830192508560051b85013681111561572757600080fd5b855b818110156157625780356001600160401b038111156157485760008081fd5b61575436828a016151e8565b865250938201938201615729565b50919695505050505050565b600061577c6142728461421f565b80848252602080830192508560051b85013681111561579a57600080fd5b855b818110156157625780356001600160401b038111156157bb5760008081fd5b6157c736828a0161548b565b86525093820193820161579c565b6000602082840312156157e757600080fd5b81516001600160401b03808211156157fe57600080fd5b908301906040828603121561581257600080fd5b60405160408101818110838211171561582d5761582d61416b565b6040528251815260208301518281111561584657600080fd5b61585287828601614bd7565b60208301525095945050505050565b6040808252810183905260008460608301825b8681101561589e57823561588781614242565b60ff16825260209283019290910190600101615874565b508381036020850152613cfe8186614583565b6000602082840312156158c357600080fd5b8135610a7481614242565b604080825283519082018190526000906020906060840190828701845b8281101561590a57815160ff16845292840192908401906001016158eb565b5050508381036020850152613b468186614583565b60006001820161593157615931614a53565b5060010190565b60006020828403121561594a57600080fd5b8135610a74816149bf565b6001600160401b03831681526101c08101615983602083016159768561513e565b6001600160a01b03169052565b61598f6020840161513e565b6001600160a01b0381166040840152506040830135606083015260608301356080830152608083013560a083015260a083013560c083015260c083013560e083015261010060e0840135818401526101208185013581850152610140915080850135828501525061016081850135818501526101809150808501358285015250808401356101a0840152509392505050565b80820281158282048414176126d1576126d1614a53565b600082615a5557634e487b7160e01b600052601260045260246000fd5b500490565b6000808335601e19843603018112615a7157600080fd5b8301803591506001600160401b03821115615a8b57600080fd5b6020019150368190038213156144dd57600080fd5b6000815160c08452615ab560c0850182614583565b9050602083015160018060a01b038082166020870152806040860151166040870152505060ff60608401511660608501526001600160401b03608084015116608085015260a083015160a08501528091505092915050565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a08301516101408060c0850152615b5e610160850183615aa0565b915060c0850151615b7360e086018215159052565b5060e0850151610100615b898187018315159052565b8601519050610120615ba5868201836001600160a01b03169052565b860151858403601f1901838701529050614a308382614583565b60008282518085526020808601955060208260051b8401016020860160005b8481101561448c57601f19868403018952615bfa838351615aa0565b98840198925090830190600101615bde565b60008151808452602080850194506020840160005b83811015614aad578151151587529582019590820190600101615c21565b602081528151602082015260006020830151610140806040850152615c68610160850183614a7c565b91506040850151601f1980868503016060870152615c868483614a7c565b93506060870151915080868503016080870152615ca38483614a7c565b935060808701519150808685030160a0870152615cc08483614a7c565b935060a08701519150808685030160c0870152615cdd8483615bbf565b935060c08701519150808685030160e0870152615cfa8483615c0c565b935060e08701519150610100818786030181880152615d198584615c0c565b945080880151925050610120615d39818801846001600160a01b03169052565b870151868503909101838701529050614a308382614583565b600060208284031215615d6457600080fd5b8151610a7481614242565b805169ffffffffffffffffffff811681146145e157600080fd5b600080600080600060a08688031215615da157600080fd5b615daa86615d6f565b9450602086015193506040860151925060608601519150615dcd60808701615d6f565b90509295509295909350565b818103818111156126d1576126d1614a53565b600181815b80851115615e27578160001904821115615e0d57615e0d614a53565b80851615615e1a57918102915b93841c9390800290615df1565b509250929050565b600082615e3e575060016126d1565b81615e4b575060006126d1565b8160018114615e615760028114615e6b57615e87565b60019150506126d1565b60ff841115615e7c57615e7c614a53565b50506001821b6126d1565b5060208310610133831016604e8410600b8410161715615eaa575081810a6126d1565b615eb48383615dec565b8060001904821115615ec857615ec8614a53565b029392505050565b6000610a748383615e2f56fe6b50fa17b77d24e42e27a04b69fe50cd6967cfb767d18de0bd5fe7e1a32aa8684a76dea3a6231aa5446f85ecde36fb499385f0f3539e800a138fb9855200db67bcc180fb907e9ae431665de4bc74305c00b7b27442aadd477980ecc4bb14c011a2646970667358221220f67d823bcf530e1c227709dc49c852062b141a3625cca76dcb66a7506feb656864736f6c6343000817003300000000000000000000000017a332dc7b40ae701485023b219e9d6f493a2514
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102065760003560e01c80637abae2511161011a578063b9694b52116100ad578063d8bb4f4e1161007c578063d8bb4f4e146105a6578063da163637146105c6578063ea7a8392146105ce578063f3afdd88146105e1578063f3d80846146105f457600080fd5b8063b9694b521461055a578063c2085f461461056d578063c97c55b014610580578063d70139741461059357600080fd5b80639d57d64e116100e95780639d57d64e14610501578063a8a0838914610514578063a9ce464814610527578063b1752d591461054757600080fd5b80637abae2511461046d5780637f7aecb51461048257806385e1f4d0146104a2578063904b1a28146104e157600080fd5b80634545fc311161019d57806353d69edc1161016c57806353d69edc146103c4578063596703e7146103d957806361d26cae146103ec5780637504988b1461041f578063786c69f31461044d57600080fd5b80634545fc311461033b5780634786b4241461035b57806349c3af451461037b5780634c75c0d8146103a457600080fd5b80631f864be3116101d95780631f864be3146102bf57806324c73dda146102e05780633283166a1461030757806336c7fe1d1461032857600080fd5b80630292540b1461020b57806310c5fbe41461023e57806312c4da861461025e5780631f5ae58f1461029f575b600080fd5b61022b61021936600461414e565b600c6020526000908152604090205481565b6040519081526020015b60405180910390f35b61022b61024c36600461414e565b60046020526000908152604090205481565b61028761026c36600461414e565b6000602081905290815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610235565b61022b6102ad36600461414e565b600b6020526000908152604090205481565b6102d26102cd366004614341565b610607565b604051610235929190614449565b6102877f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a251481565b61031a6103153660046144e4565b61082b565b6040516102359291906145af565b61022b6103363660046145e6565b61088a565b61022b61034936600461414e565b60076020526000908152604090205481565b61022b61036936600461414e565b60086020526000908152604090205481565b61028761038936600461414e565b6001602052600090815260409020546001600160a01b031681565b61022b6103b236600461414e565b60056020526000908152604090205481565b6103cc610a7b565b6040516102359190614649565b61022b6103e736600461465c565b610b0d565b6103ff6103fa36600461468d565b610f28565b604080519485526020850193909352918301526060820152608001610235565b61043261042d3660046146f0565b6110c7565b60408051938452602084019290925290820152606001610235565b61022b61045b36600461414e565b60036020526000908152604090205481565b61048061047b366004614725565b611226565b005b61022b61049036600461414e565b60066020526000908152604090205481565b6104c97f0000000000000000000000000000000000000000000000000000000000013e3181565b6040516001600160401b039091168152602001610235565b61022b6104ef36600461414e565b60096020526000908152604090205481565b61048061050f36600461477d565b611367565b610480610522366004614817565b6114ab565b61022b61053536600461414e565b60026020526000908152604090205481565b61022b6105553660046145e6565b611557565b61048061056836600461485a565b61156d565b61048061057b36600461488e565b6116aa565b6103ff61058e36600461468d565b6117ef565b6103ff6105a136600461468d565b611963565b61022b6105b436600461414e565b600a6020526000908152604090205481565b6103cc611b1e565b6104806105dc366004614910565b611bac565b6103ff6105ef36600461468d565b611dbf565b6104326106023660046146f0565b611f53565b835160009060609082816001600160401b038111156106285761062861416b565b604051908082528060200260200182016040528015610651578160200160208202803683370190505b509050866001600160401b03167f0000000000000000000000000000000000000000000000000000000000013e316001600160401b03161461081f5760005b8281101561081d577f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316630eff125d8a83815181106106d9576106d96149a9565b60200260200101516040518263ffffffff1660e01b8152600401610706919060ff91909116815260200190565b602060405180830381865afa158015610723573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074791906149df565b6001600160a01b031663ea98b1478989898581518110610769576107696149a9565b60200260200101516040518463ffffffff1660e01b815260040161078f939291906149fc565b602060405180830381865afa1580156107ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d09190614a3a565b8282815181106107e2576107e26149a9565b602002602001018181525050818181518110610800576108006149a9565b6020026020010151856108139190614a69565b9450600101610690565b505b91505094509492505050565b60006060600080600061084089898989612092565b92509250925060405180604001604052808481526020018381525060405160200161086b9190614ab8565b60408051601f1981840301815291905290999098509650505050505050565b6000606084156109e95760405163bffc1e1360e01b81526001600160401b03841660048201526000907f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b03169063bffc1e1390602401602060405180830381865afa158015610904573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109289190614a3a565b90506000816001600160401b038111156109445761094461416b565b60405190808252806020026020018201604052801561096d578160200160208202803683370190505b50905060005b828110156109a357600019828281518110610990576109906149a9565b6020908102919091010152600101610973565b5060405180606001604052806000198152602001828152602001828152506040516020016109d19190614b3b565b60405160208183030381529060405292505050610a30565b506040805160608082018352600019808352602080840182815293850182815285519182019290925292518385015251828201528251808303909101815260809091019091525b610a7084846040518060400160405280600019815260200185815250604051602001610a5c9190614b7e565b6040516020818303038152906040526123bc565b9150505b9392505050565b6060600d8054610a8a90614ba3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab690614ba3565b8015610b035780601f10610ad857610100808354040283529160200191610b03565b820191906000526020600020905b815481529060010190602001808311610ae657829003601f168201915b5050505050905090565b604080516101008101825260008082526020820181905291810182905260608082018190526080820181905260a0820183905260c0820183905260e08201526000610b777f55b101fc856aff484166c46ad33bc74831c135693c159b0092bb3b72254ffb6b612645565b9050806001600160a01b03166313c02a596040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdb9190614a3a565b808352841115610bfe576040516355da2ca360e11b815260040160405180910390fd5b6040516336445ffd60e01b8152600481018590526001600160a01b038216906336445ffd90602401602060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c679190614a3a565b602083015260405163361ad42b60e01b8152600481018590526001600160a01b0382169063361ad42b90602401600060405180830381865afa158015610cb1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cd99190810190614c1c565b6060830152602082015160c081811c9084015260ff601082901c811660a085015260089190911c166040830181905215610d17575060009392505050565b8160a0015160ff16600103610d8c5760008260600151806020019051810190610d409190614e40565b60408051606081018252855181526020808401518183015282840151828401529151929350610d7192909101614b3b565b60408051601f19818403018152919052606084015250610df7565b60008260600151806020019051810190610da69190614fc9565b60408051606080820183528651808352602085810151818501908152958501519385019384528451908101919091529351848401529051838201528151808403820181526080909301909152840152505b604051636c181b2760e11b8152600481018590526001600160a01b0382169063d830364e90602401600060405180830381865afa158015610e3c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e64919081019061508f565b608083015260408051808201918290526336445ffd60e01b90915260448101859052806001600160a01b0383166336445ffd60648301602060405180830381865afa158015610eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610edb9190614a3a565b81526060840151602091820152604051610ef6929101614b7e565b60408051601f1981840301815291905260e08301819052608083015160c0840151610f20926123bc565b949350505050565b6000806000806000610f47600080516020615f1d833981519152612645565b6040805160018082528183019092529192506000919060208083019080368337019050509050610f7d6040890160208a0161414e565b81600081518110610f9057610f906149a9565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b610fc961403b565b815260200190600190039081610fc1579050509050610feb60408b018b61511d565b610ff4906152f0565b81600081518110611007576110076149a9565b602002602001018190525061109c6040518060e00160405280600081526020018581526020018c806000019061103d91906152fc565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060208101859052604081018490526001600160a01b03871660608201528b15156080909101526126d7565b91995097509550876110ae8789614a69565b6110b89190614a69565b94505050505092959194509250565b6000806000806110e4600080516020615f1d833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090507f0000000000000000000000000000000000000000000000000000000000013e318160008151811061113e5761113e6149a9565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b6111776140ca565b81526020019060019003908161116f579050509050611196898061511d565b61119f906155cb565b816000815181106111b2576111b26149a9565b602002602001018190525060606112066040518060e0016040528060008152602001868152602001838152602001848152602001858152602001876001600160a01b031681526020018b15158152506126d7565b91995090975061121890508789614a69565b955050505050509250925092565b6040516321f8a72160e01b8152600080516020615edd83398151915260048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa158015611298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bc91906149df565b604051632474521560e21b8152600080516020615efd83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133a91906155d7565b61135757604051633108430360e11b815260040160405180910390fd5b611362838383612c86565b505050565b61137e600080516020615edd833981519152612645565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa1580156113c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e891906155d7565b61140557604051633721555560e21b815260040160405180910390fd5b8260008190036114285760405163021b4ea160e01b815260040160405180910390fd5b80821461144857604051634456f5e960e11b815260040160405180910390fd5b60005b818110156114a35761149b868683818110611468576114686149a9565b905060200201602081019061147d919061414e565b85858481811061148f5761148f6149a9565b90506101a00201613069565b60010161144b565b505050505050565b6114c2600080516020615edd833981519152612645565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa158015611508573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152c91906155d7565b61154957604051633721555560e21b815260040160405180910390fd5b6115538282613069565b5050565b6000610f208261156886868661088a565b6132a5565b6040516321f8a72160e01b8152600080516020615edd83398151915260048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa1580156115df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160391906149df565b604051632474521560e21b8152600080516020615efd83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa15801561165d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168191906155d7565b61169e57604051633108430360e11b815260040160405180910390fd5b600d611553828261563c565b6040516321f8a72160e01b8152600080516020615edd83398151915260048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174091906149df565b604051632474521560e21b8152600080516020615efd83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa15801561179a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117be91906155d7565b6117db57604051633108430360e11b815260040160405180910390fd5b6117e88585858585613341565b5050505050565b600080600080600061180e600080516020615f1d833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090506118446040890160208a0161414e565b81600081518110611857576118576149a9565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b6118906140ca565b8152602001906001900390816118885790505090506118b260408b018b61511d565b6118bb906155cb565b816000815181106118ce576118ce6149a9565b602002602001018190525061109c6040518060e00160405280600081526020018581526020018c806000019061190491906152fc565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060208101849052604081018590526001600160a01b03871660608201528b15156080909101526126d7565b60008080808061197660208801886152fc565b90509050600080600080611997600080516020615f1d833981519152612645565b9050606060005b86811015611af757611ac46040518060e001604052808381526020018f80602001906119ca91906152fc565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060000190611a1f91906152fc565b85818110611a2f57611a2f6149a9565b9050602002810190611a4191906152fc565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018481526020018f8060400190611a9c91906152fc565b611aa5916156fb565b8152602001856001600160a01b031681526020018e15158152506126d7565b91975095509350611ad5868c614a69565b9a50611ae1858b614a69565b9950611aed848a614a69565b985060010161199e565b5089611b03898b614a69565b611b0d9190614a69565b965050505050505092959194509250565b600d8054611b2b90614ba3565b80601f0160208091040260200160405190810160405280929190818152602001828054611b5790614ba3565b8015611ba45780601f10611b7957610100808354040283529160200191611ba4565b820191906000526020600020905b815481529060010190602001808311611b8757829003601f168201915b505050505081565b6040516321f8a72160e01b8152600080516020615edd83398151915260048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa158015611c1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4291906149df565b604051632474521560e21b8152600080516020615efd83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc091906155d7565b611cdd57604051633108430360e11b815260040160405180910390fd5b846000819003611d005760405163021b4ea160e01b815260040160405180910390fd5b8084148015611d0e57508082145b611d2b57604051634456f5e960e11b815260040160405180910390fd5b60005b81811015611db557611dad888883818110611d4b57611d4b6149a9565b9050602002016020810190611d60919061414e565b878784818110611d7257611d726149a9565b9050602002810190611d8491906152fc565b878786818110611d9657611d966149a9565b9050602002810190611da891906152fc565b613341565b600101611d2e565b5050505050505050565b600080808080611dd260208801886152fc565b90509050600080600080611df3600080516020615f1d833981519152612645565b9050606060005b86811015611af757611f206040518060e001604052808381526020018f8060200190611e2691906152fc565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060000190611e7b91906152fc565b85818110611e8b57611e8b6149a9565b9050602002810190611e9d91906152fc565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060400190611ef291906152fc565b611efb9161576e565b8152602001848152602001856001600160a01b031681526020018e15158152506126d7565b91975095509350611f31868c614a69565b9a50611f3d858b614a69565b9950611f49848a614a69565b9850600101611dfa565b600080600080611f70600080516020615f1d833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090507f0000000000000000000000000000000000000000000000000000000000013e3181600081518110611fca57611fca6149a9565b6001600160401b039290921660209283029190910190910152604080516001808252818301909252600091816020015b61200261403b565b815260200190600190039081611ffa579050509050612021888061511d565b61202a906152f0565b8160008151811061203d5761203d6149a9565b60200260200101819052506060806112066040518060e0016040528060008152602001868152602001838152602001848152602001858152602001876001600160a01b031681526020018b15158152506126d7565b606080600080848060200190518101906120ac91906157d5565b9050868682602001516040516020016120c793929190615861565b60408051601f1981840301815291815260208381019290925280518883028181018401909252888152889261211d928c92918c9186918291908501908490808284376000920191909152508b925061341b915050565b9350806001600160401b038111156121375761213761416b565b604051908082528060200260200182016040528015612160578160200160208202803683370190505b509450600060405180604001604052806000198152602001888051906020012060405160200161219291815260200190565b60408051601f198184030181529181529152516121b29190602001614b7e565b6040516020818303038152906040529050896001600160401b03167f0000000000000000000000000000000000000000000000000000000000013e316001600160401b0316146123af5760005b828110156123ad5760007f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316630eff125d8c8c8581811061224a5761224a6149a9565b905060200201602081019061225f91906158b1565b6040516001600160e01b031960e084901b16815260ff9091166004820152602401602060405180830381865afa15801561229d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c191906149df565b6001600160a01b031663ea98b1478d846000036122fd57876040516020016122e99190614b7e565b6040516020818303038152906040526122ff565b855b8a8681518110612311576123116149a9565b60200260200101516040518463ffffffff1660e01b8152600401612337939291906149fc565b602060405180830381865afa158015612354573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123789190614a3a565b90506123848187614a69565b955080888381518110612399576123996149a9565b6020908102919091010152506001016121ff565b505b5050509450945094915050565b8251600090816123cd85878661341b565b90506000848060200190518101906123e591906157d5565b90508681602001516040516020016123fe9291906158ce565b6040516020818303038152906040528160200181905250600060405180604001604052806000198152602001878051906020012060405160200161244491815260200190565b60408051601f198184030181529181529152516124649190602001614b7e565b6040516020818303038152906040529050866001600160401b03167f0000000000000000000000000000000000000000000000000000000000013e316001600160401b03161461263a5760005b848110156126385760007f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316630eff125d8b84815181106124fc576124fc6149a9565b60200260200101516040518263ffffffff1660e01b8152600401612529919060ff91909116815260200190565b602060405180830381865afa158015612546573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256a91906149df565b6001600160a01b031663ea98b1478a846000036125a657866040516020016125929190614b7e565b6040516020818303038152906040526125a8565b855b8886815181106125ba576125ba6149a9565b60200260200101516040518463ffffffff1660e01b81526004016125e0939291906149fc565b602060405180830381865afa1580156125fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126219190614a3a565b905061262d8188614a69565b9650506001016124b1565b505b505050509392505050565b6040516321f8a72160e01b8152600481018290526000907f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa1580156126ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d191906149df565b92915050565b60008060006127106040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b60007f0000000000000000000000000000000000000000000000000000000000013e316001600160401b03168660200151876000015181518110612756576127566149a9565b60200260200101516001600160401b03161415905060008260400181815250506000808760600151511190506000816127b8576127b388608001518960000151815181106127a6576127a66149a9565b602002602001015161367e565b6127e2565b6127e288606001518960000151815181106127d5576127d56149a9565b6020026020010151613758565b9050826127f0576000612820565b612820886040015189602001518a6000015181518110612812576128126149a9565b6020026020010151836123bc565b606085015281612831576001612856565b6060880151885181518110612848576128486149a9565b602002602001015160000151515b6020850152606084015161286a9087614a69565b95506000826128a6576128a189608001518a6000015181518110612890576128906149a9565b6020026020010151608001516137e8565b6128ca565b60608901518951815181106128bd576128bd6149a9565b6020026020010151608001515b90508860c0015115612a96576128df81613868565b6128e99089614a69565b97508315612a915761292089602001518a600001518151811061290e5761290e6149a9565b602002602001015186602001516138b1565b856040018181516129319190614a69565b905250600083156129a55760005b866020015181101561299f5760608b01518b5181518110612962576129626149a9565b602002602001015160e00151818151811061297f5761297f6149a9565b6020026020010151612997576129948261591f565b91505b60010161293f565b506129d8565b60808a01518a51815181106129bc576129bc6149a9565b602002602001015160e001516129d8576129d58161591f565b90505b6129e1816138d4565b6129eb9089614a69565b9750600084612a2957612a248b608001518c6000015181518110612a1157612a116149a9565b602002602001015160c00151151561394e565b612a4d565b60608b01518b5181518110612a4057612a406149a9565b602002602001015160c001515b9050612a7a8b602001518c6000015181518110612a6c57612a6c6149a9565b602002602001015182613999565b87604001818151612a8b9190614a69565b90525050505b612beb565b8215612b3b5760005b8560200151811015612b3557612b198a606001518b6000015181518110612ac857612ac86149a9565b6020026020010151600001518281518110612ae557612ae56149a9565b60200260200101518b602001518c6000015181518110612b0757612b076149a9565b60200260200101518c60a00151613a56565b86604001818151612b2a9190614a69565b905250600101612a9f565b50612ba5565b612b9089608001518a6000015181518110612b5857612b586149a9565b6020026020010151600001518a602001518b6000015181518110612b7e57612b7e6149a9565b60200260200101518b60a00151613a56565b85604001818151612ba19190614a69565b9052505b8315612beb57612bd689602001518a6000015181518110612bc857612bc86149a9565b602002602001015182613b52565b85604001818151612be79190614a69565b9052505b83612bf7576000612c2b565b612c2b8960c001518a602001518b6000015181518110612c1957612c196149a9565b60200260200101518760200151613bfa565b85604001818151612c3c9190614a69565b905250602089015189518151612c6f9291908110612c5c57612c5c6149a9565b6020026020010151866040015186613c46565b612c799087614a69565b9799969850505050505050565b81600103612d2b57600081806020019051810190612ca491906149df565b90506001600160a01b03811615612cf4576000612cc082613d09565b60ff1690506008811080612cd45750601281115b15612cf2576040516333339aa360e11b815260040160405180910390fd5b505b6001600160401b038416600090815260208190526040902080546001600160a01b0319166001600160a01b03929092169190911790555b81600203612dd057600081806020019051810190612d4991906149df565b90506001600160a01b03811615612d99576000612d6582613d09565b60ff1690506008811080612d795750601281115b15612d97576040516333339aa360e11b815260040160405180910390fd5b505b6001600160401b038416600090815260016020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b81600303612e065780806020019051810190612dec9190614a3a565b6001600160401b0384166000908152600260205260409020555b81600403612e3c5780806020019051810190612e229190614a3a565b6001600160401b0384166000908152600360205260409020555b81600503612e725780806020019051810190612e589190614a3a565b6001600160401b0384166000908152600560205260409020555b81600603612ea85780806020019051810190612e8e9190614a3a565b6001600160401b0384166000908152600660205260409020555b81600703612ede5780806020019051810190612ec49190614a3a565b6001600160401b0384166000908152600760205260409020555b81600803612f145780806020019051810190612efa9190614a3a565b6001600160401b0384166000908152600860205260409020555b81600903612f4a5780806020019051810190612f309190614a3a565b6001600160401b0384166000908152600960205260409020555b81600a03612f805780806020019051810190612f669190614a3a565b6001600160401b0384166000908152600a60205260409020555b81600b03612fb65780806020019051810190612f9c9190614a3a565b6001600160401b0384166000908152600b60205260409020555b81600c03612fec5780806020019051810190612fd29190614a3a565b6001600160401b0384166000908152600c60205260409020555b81600d0361302257808060200190518101906130089190614a3a565b6001600160401b0384166000908152600460205260409020555b81836001600160401b03167fae3dadf141b0383d3b4db666b2fc32179836af27e11a3e8f07c3ef8da82e59308360405161305c9190614649565b60405180910390a3505050565b60006130786020830183615938565b6001600160a01b03161461310c5760006130956020830183615938565b905060006130a282613d09565b60ff16905060088110806130b65750601281115b156130d4576040516333339aa360e11b815260040160405180910390fd5b506001600160401b038316600090815260208190526040902080546001600160a01b0319166001600160a01b03929092169190911790555b600061311e6040830160208401615938565b6001600160a01b0316146131b557600061313e6040830160208401615938565b9050600061314b82613d09565b60ff169050600881108061315f5750601281115b1561317d576040516333339aa360e11b815260040160405180910390fd5b506001600160401b038316600090815260016020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b6001600160401b0382166000908152600260209081526040808320818501359055600382528083206060850135905560058252808320608085013590556006825280832060a085013590556007825280832060c085013590556008825280832060e08501359055600982528083206101008501359055600a82528083206101208501359055600b82528083206101408501359055600c825280832061016085013590556004909152908190206101808301359055517fdee9f507a37f922d400f1af8b89ddcf4419171e4570e9bc6b83e49659d6a26eb906132999084908490615955565b60405180910390a15050565b6000816000036132b7575060006126d1565b60006132e27f0000000000000000000000000000000000000000000000000000000000013e31613d6d565b6132ec9084615a21565b9050806000036133005760009150506126d1565b600061330b85613d6d565b90508060000361332e57604051634c8f99a760e11b815260040160405180910390fd5b6133388183615a38565b95945050505050565b8260008190036133645760405163021b4ea160e01b815260040160405180910390fd5b80821461338457604051634456f5e960e11b815260040160405180910390fd5b60005b818110156134125761340a878787848181106133a5576133a56149a9565b905060200201358686858181106133be576133be6149a9565b90506020028101906133d09190615a5a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c8692505050565b600101613387565b50505050505050565b606060008280602001905181019061343391906157d5565b905083816020015160405160200161344c9291906158ce565b60408051601f1981840301815291815260208381019290925285516001600160401b03881660009081526009845282812054925191939091839161349291879101614b7e565b604051602081830303815290604052516134ac9190615a21565b905060006134bb8360a0615a21565b9050836001600160401b038111156134d5576134d561416b565b60405190808252806020026020018201604052801561350857816020015b60608152602001906001900390816134f35790505b50955060005b84811015613671576000816000036135265783613528565b825b90507f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316630eff125d8b848151811061356b5761356b6149a9565b60200260200101516040518263ffffffff1660e01b8152600401613598919060ff91909116815260200190565b602060405180830381865afa1580156135b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135d991906149df565b6001600160a01b03166325fc6dd0826040518263ffffffff1660e01b815260040161360691815260200190565b600060405180830381865afa158015613623573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261364b9190810190614c1c565b88838151811061365d5761365d6149a9565b60209081029190910101525060010161350e565b5050505050509392505050565b60606000604051806101400160405280613696613ea6565b815260200184600001518152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460c00151151581526020018460e00151151581526020018461010001516001600160a01b031681526020018461014001518152506040516020016137129190615b0d565b60408051601f198184030181528282018252600019835260208381018290529151909350613741929101614b7e565b604051602081830303815290604052915050919050565b60606000604051806101400160405280613770613ea6565b815260200184600001518152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460c0015181526020018460e0015181526020018461010001516001600160a01b031681526020018461014001518152506040516020016137129190615c3f565b604080516001808252818301909252606091816020015b6040805160c0810182526060808252600060208084018290529383018190529082018190526080820181905260a082015282526000199092019101816137ff5790505090508181600081518110613858576138586149a9565b6020026020010181905250919050565b8051600090815b818110156138aa57838181518110613889576138896149a9565b602002602001015160a00151836138a09190614a69565b925060010161386f565b5050919050565b6001600160401b038216600090815260036020526040812054610a749083615a21565b6001600160401b037f0000000000000000000000000000000000000000000000000000000000013e31166000908152600a602052604081205481906139199084615a21565b90506139447f0000000000000000000000000000000000000000000000000000000000013e31613f42565b610a749082615a21565b604080516001808252818301909252606091602080830190803683370190505090508181600081518110613984576139846149a9565b91151560209283029190910190910152919050565b600080836001600160401b03167f0000000000000000000000000000000000000000000000000000000000013e316001600160401b0316036139df5760009150506126d1565b825160005b81811015613a1f578481815181106139fe576139fe6149a9565b602002602001015115613a1757613a148361591f565b92505b6001016139e4565b5081600003613a33576000925050506126d1565b6001600160401b0385166000908152600260205260409020546133389083615a21565b600080613a6285614007565b5060405163596db71760e01b815263ffffffff82166004820152909250600091506001600160a01b0385169063596db71790602401602060405180830381865afa158015613ab4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ad891906155d7565b905080158015613aee575063ffffffff82166002145b15613b1d576001600160401b0385166000908152600b6020526040902054613b169084614a69565b9250613b49565b8015613b49576001600160401b0385166000908152600c6020526040902054613b469084614a69565b92505b50509392505050565b8051600090815b81811015613bf257838181518110613b7357613b736149a9565b602002602001015160000151516000148015613bbf575060006001600160a01b0316848281518110613ba757613ba76149a9565b6020026020010151602001516001600160a01b031614155b15613bea576001600160401b038516600090815260046020526040902054613be79084614a69565b92505b600101613b59565b505092915050565b60008084613c20576001600160401b038416600090815260066020526040902054613c3a565b6001600160401b0384166000908152600560205260409020545b9050610a708382615a21565b600080613c5285613f42565b613c5c9085615a21565b905080600003613c70576000915050610a74565b82613c7c579050610a74565b6000613c8786613d6d565b613c919083615a21565b905080600003613ca657600092505050610a74565b6000613cd17f0000000000000000000000000000000000000000000000000000000000013e31613d6d565b905080600003613cf457604051634c8f99a760e11b815260040160405180910390fd5b613cfe8183615a38565b979650505050505050565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d49573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d19190615d52565b6001600160401b0381166000908152602081905260408120546001600160a01b03168015613e8957806001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015613def575060408051601f3d908101601f19168201909252613dec91810190615d89565b60015b15613e895760008413613e155760405163119d4d6b60e11b815260040160405180910390fd5b81600003613e36576040516376685d7f60e11b815260040160405180910390fd5b6000613e4187613d09565b60ff1690506007198101613e5c575092979650505050505050565b613e67600882615dd9565b613e7290600a615ed0565b613e7c9086615a38565b9998505050505050505050565b50506001600160401b031660009081526007602052604090205490565b6000613ed17f55b101fc856aff484166c46ad33bc74831c135693c159b0092bb3b72254ffb6b612645565b6001600160a01b03166313c02a596040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f329190614a3a565b9050613f3d8161591f565b905090565b6001600160401b0381166000908152600160205260408120546001600160a01b03168015613fea57806001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015613fc4575060408051601f3d908101601f19168201909252613fc191810190615d89565b60015b15613fea5760008413613e155760405163119d4d6b60e11b815260040160405180910390fd5b50506001600160401b031660009081526008602052604090205490565b8060a081901c60c082901c60008190036140345760405163030042b760e01b815260040160405180910390fd5b9193909250565b6040518061016001604052806000815260200160008152602001600081526020016000815260200161409b6040805160c081018252606080825260006020830181905292820183905281018290526080810182905260a081019190915290565b81526060602082018190526000604083018190528183018190526080830181905260a083015260c09091015290565b604051806101600160405280606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016060815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081525090565b6001600160401b038116811461414b57600080fd5b50565b60006020828403121561416057600080fd5b8135610a7481614136565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156141a3576141a361416b565b60405290565b60405161014081016001600160401b03811182821017156141a3576141a361416b565b60405161016081016001600160401b03811182821017156141a3576141a361416b565b604051601f8201601f191681016001600160401b03811182821017156142175761421761416b565b604052919050565b60006001600160401b038211156142385761423861416b565b5060051b60200190565b60ff8116811461414b57600080fd5b600082601f83011261426257600080fd5b813560206142776142728361421f565b6141ef565b8083825260208201915060208460051b87010193508684111561429957600080fd5b602086015b848110156142be5780356142b181614242565b835291830191830161429e565b509695505050505050565b60006001600160401b038211156142e2576142e261416b565b50601f01601f191660200190565b600082601f83011261430157600080fd5b813561430f614272826142c9565b81815284602083860101111561432457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561435757600080fd5b84356001600160401b038082111561436e57600080fd5b61437a88838901614251565b9550602091508187013561438d81614136565b94506040870135818111156143a157600080fd5b6143ad89828a016142f0565b9450506060870135818111156143c257600080fd5b8701601f810189136143d357600080fd5b80356143e16142728261421f565b81815260059190911b8201840190848101908b83111561440057600080fd5b8584015b838110156144385780358681111561441c5760008081fd5b61442a8e89838901016142f0565b845250918601918601614404565b50989b979a50959850505050505050565b60006040820184835260206040602085015281855180845260608601915060208701935060005b8181101561448c57845183529383019391830191600101614470565b5090979650505050505050565b60008083601f8401126144ab57600080fd5b5081356001600160401b038111156144c257600080fd5b6020830191508360208260051b85010111156144dd57600080fd5b9250929050565b600080600080606085870312156144fa57600080fd5b843561450581614136565b935060208501356001600160401b038082111561452157600080fd5b61452d88838901614499565b9095509350604087013591508082111561454657600080fd5b50614553878288016142f0565b91505092959194509250565b60005b8381101561457a578181015183820152602001614562565b50506000910152565b6000815180845261459b81602086016020860161455f565b601f01601f19169290920160200192915050565b828152604060208201526000610f206040830184614583565b801515811461414b57600080fd5b80356145e1816145c8565b919050565b6000806000606084860312156145fb57600080fd5b8335614606816145c8565b925060208401356001600160401b0381111561462157600080fd5b61462d86828701614251565b925050604084013561463e81614136565b809150509250925092565b602081526000610a746020830184614583565b60006020828403121561466e57600080fd5b5035919050565b60006060828403121561468757600080fd5b50919050565b600080604083850312156146a057600080fd5b82356001600160401b038111156146b657600080fd5b6146c285828601614675565b92505060208301356146d3816145c8565b809150509250929050565b60006020828403121561468757600080fd5b6000806040838503121561470357600080fd5b82356001600160401b0381111561471957600080fd5b6146c2858286016146de565b60008060006060848603121561473a57600080fd5b833561474581614136565b92506020840135915060408401356001600160401b0381111561476757600080fd5b614773868287016142f0565b9150509250925092565b6000806000806040858703121561479357600080fd5b84356001600160401b03808211156147aa57600080fd5b6147b688838901614499565b909650945060208701359150808211156147cf57600080fd5b818701915087601f8301126147e357600080fd5b8135818111156147f257600080fd5b8860206101a08302850101111561480857600080fd5b95989497505060200194505050565b6000808284036101c081121561482c57600080fd5b833561483781614136565b92506101a0601f198201121561484c57600080fd5b506020830190509250929050565b60006020828403121561486c57600080fd5b81356001600160401b0381111561488257600080fd5b610f20848285016142f0565b6000806000806000606086880312156148a657600080fd5b85356148b181614136565b945060208601356001600160401b03808211156148cd57600080fd5b6148d989838a01614499565b909650945060408801359150808211156148f257600080fd5b506148ff88828901614499565b969995985093965092949392505050565b6000806000806000806060878903121561492957600080fd5b86356001600160401b038082111561494057600080fd5b61494c8a838b01614499565b9098509650602089013591508082111561496557600080fd5b6149718a838b01614499565b9096509450604089013591508082111561498a57600080fd5b5061499789828a01614499565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038116811461414b57600080fd5b80516145e1816149bf565b6000602082840312156149f157600080fd5b8151610a74816149bf565b6001600160401b0384168152606060208201526000614a1e6060830185614583565b8281036040840152614a308185614583565b9695505050505050565b600060208284031215614a4c57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156126d1576126d1614a53565b60008151808452602080850194506020840160005b83811015614aad57815187529582019590820190600101614a91565b509495945050505050565b600060208083528351604082850152614ad46060850182614a7c565b82860151601f198683038101604088015281518084529293509084019183850190600581901b8501860160005b82811015614b2d5784878303018452614b1b828751614583565b95880195938801939150600101614b01565b509998505050505050505050565b60208152815160208201526000602083015160606040840152614b616080840182614a7c565b90506040840151601f198483030160608501526133388282614a7c565b602081528151602082015260006020830151604080840152610f206060840182614583565b600181811c90821680614bb757607f821691505b60208210810361468757634e487b7160e01b600052602260045260246000fd5b600082601f830112614be857600080fd5b8151614bf6614272826142c9565b818152846020838601011115614c0b57600080fd5b610f2082602083016020870161455f565b600060208284031215614c2e57600080fd5b81516001600160401b03811115614c4457600080fd5b610f2084828501614bd7565b600082601f830112614c6157600080fd5b81516020614c716142728361421f565b8083825260208201915060208460051b870101935086841115614c9357600080fd5b602086015b848110156142be5780518352918301918301614c98565b600060c08284031215614cc157600080fd5b614cc9614181565b905081516001600160401b03811115614ce157600080fd5b614ced84828501614bd7565b8252506020820151614cfe816149bf565b60208201526040820151614d11816149bf565b60408201526060820151614d2481614242565b60608201526080820151614d3781614136565b8060808301525060a082015160a082015292915050565b600082601f830112614d5f57600080fd5b81516020614d6f6142728361421f565b82815260059290921b84018101918181019086841115614d8e57600080fd5b8286015b848110156142be5780516001600160401b03811115614db15760008081fd5b614dbf8986838b0101614caf565b845250918301918301614d92565b80516145e1816145c8565b600082601f830112614de957600080fd5b81516020614df96142728361421f565b8083825260208201915060208460051b870101935086841115614e1b57600080fd5b602086015b848110156142be578051614e33816145c8565b8352918301918301614e20565b600060208284031215614e5257600080fd5b81516001600160401b0380821115614e6957600080fd5b908301906101408286031215614e7e57600080fd5b614e866141a9565b82518152602083015182811115614e9c57600080fd5b614ea887828601614c50565b602083015250604083015182811115614ec057600080fd5b614ecc87828601614c50565b604083015250606083015182811115614ee457600080fd5b614ef087828601614c50565b606083015250608083015182811115614f0857600080fd5b614f1487828601614c50565b60808301525060a083015182811115614f2c57600080fd5b614f3887828601614d4e565b60a08301525060c083015182811115614f5057600080fd5b614f5c87828601614dd8565b60c08301525060e083015182811115614f7457600080fd5b614f8087828601614dd8565b60e083015250610100614f948185016149d4565b908201526101208381015183811115614fac57600080fd5b614fb888828701614bd7565b918301919091525095945050505050565b600060208284031215614fdb57600080fd5b81516001600160401b0380821115614ff257600080fd5b90830190610140828603121561500757600080fd5b61500f6141a9565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a08301518281111561504d57600080fd5b61505987828601614caf565b60a08301525061506b60c08401614dcd565b60c082015261507c60e08401614dcd565b60e0820152610100614f948185016149d4565b600060208083850312156150a257600080fd5b82516001600160401b038111156150b857600080fd5b8301601f810185136150c957600080fd5b80516150d76142728261421f565b81815260059190911b820183019083810190878311156150f657600080fd5b928401925b82841015613cfe57835161510e81614242565b825292840192908401906150fb565b6000823561015e1983360301811261513457600080fd5b9190910192915050565b80356145e1816149bf565b600060c0828403121561515b57600080fd5b615163614181565b905081356001600160401b0381111561517b57600080fd5b615187848285016142f0565b8252506020820135615198816149bf565b602082015260408201356151ab816149bf565b604082015260608201356151be81614242565b606082015260808201356151d181614136565b8060808301525060a082013560a082015292915050565b600061016082840312156151fb57600080fd5b6152036141cc565b90508135815260208201356020820152604082013560408201526060820135606082015260808201356001600160401b038082111561524157600080fd5b61524d85838601615149565b608084015260a084013591508082111561526657600080fd5b615272858386016142f0565b60a084015261528360c085016145d6565b60c084015261529460e085016145d6565b60e084015261010091506152a982850161513e565b8284015261012091506152bd82850161513e565b82840152610140915081840135818111156152d757600080fd5b6152e3868287016142f0565b8385015250505092915050565b60006126d136836151e8565b6000808335601e1984360301811261531357600080fd5b8301803591506001600160401b0382111561532d57600080fd5b6020019150600581901b36038213156144dd57600080fd5b600082601f83011261535657600080fd5b813560206153666142728361421f565b8083825260208201915060208460051b87010193508684111561538857600080fd5b602086015b848110156142be578035835291830191830161538d565b600082601f8301126153b557600080fd5b813560206153c56142728361421f565b82815260059290921b840181019181810190868411156153e457600080fd5b8286015b848110156142be5780356001600160401b038111156154075760008081fd5b6154158986838b0101615149565b8452509183019183016153e8565b600082601f83011261543457600080fd5b813560206154446142728361421f565b8083825260208201915060208460051b87010193508684111561546657600080fd5b602086015b848110156142be57803561547e816145c8565b835291830191830161546b565b6000610160828403121561549e57600080fd5b6154a66141cc565b905081356001600160401b03808211156154bf57600080fd5b6154cb85838601615345565b835260208401359150808211156154e157600080fd5b6154ed85838601615345565b6020840152604084013591508082111561550657600080fd5b61551285838601615345565b6040840152606084013591508082111561552b57600080fd5b61553785838601615345565b6060840152608084013591508082111561555057600080fd5b61555c858386016153a4565b608084015260a084013591508082111561557557600080fd5b615581858386016142f0565b60a084015260c084013591508082111561559a57600080fd5b6155a685838601615423565b60c084015260e08401359150808211156155bf57600080fd5b61529485838601615423565b60006126d1368361548b565b6000602082840312156155e957600080fd5b8151610a74816145c8565b601f821115611362576000816000526020600020601f850160051c8101602086101561561d5750805b601f850160051c820191505b818110156114a357828155600101615629565b81516001600160401b038111156156555761565561416b565b615669816156638454614ba3565b846155f4565b602080601f83116001811461569e57600084156156865750858301515b600019600386901b1c1916600185901b1785556114a3565b600085815260208120601f198616915b828110156156cd578886015182559484019460019091019084016156ae565b50858210156156eb5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006157096142728461421f565b80848252602080830192508560051b85013681111561572757600080fd5b855b818110156157625780356001600160401b038111156157485760008081fd5b61575436828a016151e8565b865250938201938201615729565b50919695505050505050565b600061577c6142728461421f565b80848252602080830192508560051b85013681111561579a57600080fd5b855b818110156157625780356001600160401b038111156157bb5760008081fd5b6157c736828a0161548b565b86525093820193820161579c565b6000602082840312156157e757600080fd5b81516001600160401b03808211156157fe57600080fd5b908301906040828603121561581257600080fd5b60405160408101818110838211171561582d5761582d61416b565b6040528251815260208301518281111561584657600080fd5b61585287828601614bd7565b60208301525095945050505050565b6040808252810183905260008460608301825b8681101561589e57823561588781614242565b60ff16825260209283019290910190600101615874565b508381036020850152613cfe8186614583565b6000602082840312156158c357600080fd5b8135610a7481614242565b604080825283519082018190526000906020906060840190828701845b8281101561590a57815160ff16845292840192908401906001016158eb565b5050508381036020850152613b468186614583565b60006001820161593157615931614a53565b5060010190565b60006020828403121561594a57600080fd5b8135610a74816149bf565b6001600160401b03831681526101c08101615983602083016159768561513e565b6001600160a01b03169052565b61598f6020840161513e565b6001600160a01b0381166040840152506040830135606083015260608301356080830152608083013560a083015260a083013560c083015260c083013560e083015261010060e0840135818401526101208185013581850152610140915080850135828501525061016081850135818501526101809150808501358285015250808401356101a0840152509392505050565b80820281158282048414176126d1576126d1614a53565b600082615a5557634e487b7160e01b600052601260045260246000fd5b500490565b6000808335601e19843603018112615a7157600080fd5b8301803591506001600160401b03821115615a8b57600080fd5b6020019150368190038213156144dd57600080fd5b6000815160c08452615ab560c0850182614583565b9050602083015160018060a01b038082166020870152806040860151166040870152505060ff60608401511660608501526001600160401b03608084015116608085015260a083015160a08501528091505092915050565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a08301516101408060c0850152615b5e610160850183615aa0565b915060c0850151615b7360e086018215159052565b5060e0850151610100615b898187018315159052565b8601519050610120615ba5868201836001600160a01b03169052565b860151858403601f1901838701529050614a308382614583565b60008282518085526020808601955060208260051b8401016020860160005b8481101561448c57601f19868403018952615bfa838351615aa0565b98840198925090830190600101615bde565b60008151808452602080850194506020840160005b83811015614aad578151151587529582019590820190600101615c21565b602081528151602082015260006020830151610140806040850152615c68610160850183614a7c565b91506040850151601f1980868503016060870152615c868483614a7c565b93506060870151915080868503016080870152615ca38483614a7c565b935060808701519150808685030160a0870152615cc08483614a7c565b935060a08701519150808685030160c0870152615cdd8483615bbf565b935060c08701519150808685030160e0870152615cfa8483615c0c565b935060e08701519150610100818786030181880152615d198584615c0c565b945080880151925050610120615d39818801846001600160a01b03169052565b870151868503909101838701529050614a308382614583565b600060208284031215615d6457600080fd5b8151610a7481614242565b805169ffffffffffffffffffff811681146145e157600080fd5b600080600080600060a08688031215615da157600080fd5b615daa86615d6f565b9450602086015193506040860151925060608601519150615dcd60808701615d6f565b90509295509295909350565b818103818111156126d1576126d1614a53565b600181815b80851115615e27578160001904821115615e0d57615e0d614a53565b80851615615e1a57918102915b93841c9390800290615df1565b509250929050565b600082615e3e575060016126d1565b81615e4b575060006126d1565b8160018114615e615760028114615e6b57615e87565b60019150506126d1565b60ff841115615e7c57615e7c614a53565b50506001821b6126d1565b5060208310610133831016604e8410600b8410161715615eaa575081810a6126d1565b615eb48383615dec565b8060001904821115615ec857615ec8614a53565b029392505050565b6000610a748383615e2f56fe6b50fa17b77d24e42e27a04b69fe50cd6967cfb767d18de0bd5fe7e1a32aa8684a76dea3a6231aa5446f85ecde36fb499385f0f3539e800a138fb9855200db67bcc180fb907e9ae431665de4bc74305c00b7b27442aadd477980ecc4bb14c011a2646970667358221220f67d823bcf530e1c227709dc49c852062b141a3625cca76dcb66a7506feb656864736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a2514
-----Decoded View---------------
Arg [0] : superRegistry_ (address): 0x17A332dC7B40aE701485023b219E9D6f493a2514
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a2514
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 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.