Latest 25 from a total of 1,097 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer Native | 24279246 | 35 mins ago | IN | 0.7 ETH | 0.00005427 | ||||
| Transfer Native | 24276795 | 8 hrs ago | IN | 0.7 ETH | 0.00016402 | ||||
| Transfer Native | 24274233 | 17 hrs ago | IN | 0.7 ETH | 0.00005554 | ||||
| Transfer Native | 24267198 | 40 hrs ago | IN | 0.7 ETH | 0.00005209 | ||||
| Transfer | 24234249 | 6 days ago | IN | 0 ETH | 0.00008805 | ||||
| Transfer | 24175749 | 14 days ago | IN | 0 ETH | 0.00002201 | ||||
| Transfer | 24119329 | 22 days ago | IN | 0 ETH | 0.00000567 | ||||
| Transfer | 24047883 | 32 days ago | IN | 0 ETH | 0.00005422 | ||||
| Transfer Native | 24041656 | 33 days ago | IN | 0.8 ETH | 0.00005687 | ||||
| Transfer Native | 24034299 | 34 days ago | IN | 0.7 ETH | 0.0000665 | ||||
| Transfer Native | 24022903 | 35 days ago | IN | 0.7 ETH | 0.00005329 | ||||
| Transfer | 24020717 | 36 days ago | IN | 0 ETH | 0.00013886 | ||||
| Transfer | 24019841 | 36 days ago | IN | 0 ETH | 0.00025365 | ||||
| Transfer | 24019721 | 36 days ago | IN | 0 ETH | 0.00001663 | ||||
| Transfer | 24019696 | 36 days ago | IN | 0 ETH | 0.00001893 | ||||
| Transfer Native | 23998247 | 39 days ago | IN | 0.974 ETH | 0.00019722 | ||||
| Transfer | 23984195 | 41 days ago | IN | 0 ETH | 0.00001977 | ||||
| Transfer | 23976457 | 42 days ago | IN | 0 ETH | 0.0000923 | ||||
| Transfer Native | 23961569 | 44 days ago | IN | 0.7 ETH | 0.00011894 | ||||
| Transfer | 23926733 | 49 days ago | IN | 0 ETH | 0.00031923 | ||||
| Transfer Native | 23915229 | 50 days ago | IN | 1.04 ETH | 0.00023214 | ||||
| Transfer Native | 23914989 | 50 days ago | IN | 0.7 ETH | 0.00010924 | ||||
| Transfer | 23913487 | 51 days ago | IN | 0 ETH | 0.00001934 | ||||
| Transfer | 23913413 | 51 days ago | IN | 0 ETH | 0.00002003 | ||||
| Transfer | 23870419 | 57 days ago | IN | 0 ETH | 0.00035661 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Deposit Native | 24279246 | 35 mins ago | 0.7 ETH | ||||
| Deposit Native | 24276795 | 8 hrs ago | 0.7 ETH | ||||
| Deposit Native | 24274233 | 17 hrs ago | 0.7 ETH | ||||
| Deposit Native | 24267198 | 40 hrs ago | 0.7 ETH | ||||
| Deposit Native | 24041656 | 33 days ago | 0.8 ETH | ||||
| Deposit Native | 24034299 | 34 days ago | 0.7 ETH | ||||
| Deposit Native | 24022903 | 35 days ago | 0.7 ETH | ||||
| Deposit Native | 23998247 | 39 days ago | 0.974 ETH | ||||
| Deposit Native | 23961569 | 44 days ago | 0.7 ETH | ||||
| Deposit Native | 23915229 | 50 days ago | 1.04 ETH | ||||
| Deposit Native | 23914989 | 50 days ago | 0.7 ETH | ||||
| Deposit Native | 23846551 | 60 days ago | 0.7 ETH | ||||
| Deposit Native | 23846240 | 60 days ago | 0.7 ETH | ||||
| Deposit Native | 23842435 | 61 days ago | 0.0051 ETH | ||||
| Deposit Native | 23821053 | 64 days ago | 0.7 ETH | ||||
| Deposit Native | 23820533 | 64 days ago | 0.7 ETH | ||||
| Deposit Native | 23819996 | 64 days ago | 0.6 ETH | ||||
| Deposit Native | 23812929 | 65 days ago | 0.7 ETH | ||||
| Deposit Native | 23797454 | 67 days ago | 0.6 ETH | ||||
| Deposit Native | 23797287 | 67 days ago | 0.6 ETH | ||||
| Deposit Native | 23792444 | 68 days ago | 0.6 ETH | ||||
| Deposit Native | 23791851 | 68 days ago | 0.5 ETH | ||||
| Deposit Native | 23791610 | 68 days ago | 0.6 ETH | ||||
| Deposit Native | 23791580 | 68 days ago | 0.5 ETH | ||||
| Deposit Native | 23778531 | 70 days ago | 0.45 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TransferAgent
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.9;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "../libraries/BridgeTransferLib.sol";
import "../safeguard/Ownable.sol";
/**
* @title Transfer agent. Designed to support arbitrary length receiver address for transfer. Supports the liquidity pool-based {Bridge}, the {OriginalTokenVault} for pegged
* deposit and the {PeggedTokenBridge} for pegged burn.
*/
contract TransferAgent is ReentrancyGuard, Ownable {
using SafeERC20 for IERC20;
struct Extension {
uint8 Type;
bytes Value;
}
mapping(BridgeTransferLib.BridgeSendType => address) public bridges;
event Supplement(
BridgeTransferLib.BridgeSendType bridgeSendType,
bytes32 transferId,
address sender,
bytes receiver,
Extension[] extensions
);
event BridgeUpdated(BridgeTransferLib.BridgeSendType bridgeSendType, address bridgeAddr);
/**
* @notice Send a cross-chain transfer of ERC20 token either via liquidity pool-based bridge or in form of mint/burn.
* @param _receiver The address of the receiver.
* @param _token The address of the token.
* @param _amount The amount of the transfer.
* @param _dstChainId The destination chain ID.
* @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.
* @param _maxSlippage The max slippage accepted, given as percentage in point (pip). Eg. 5000 means 0.5%.
* Must be greater than minimalMaxSlippage. Receiver is guaranteed to receive at least
* (100% - max slippage percentage) * amount or the transfer can be refunded.
* Only applicable to the {BridgeSendType.Liquidity}.
* @param _bridgeSendType The type of bridge used by this transfer. One of the {BridgeSendType} enum.
* @param _extensions A list of extension to be processed by agent, is designed to be used for extending
* present transfer. Contact Celer team to learn about already supported type of extension.
*/
function transfer(
bytes calldata _receiver,
address _token,
uint256 _amount,
uint64 _dstChainId,
uint64 _nonce,
uint32 _maxSlippage, // slippage * 1M, eg. 0.5% -> 5000
BridgeTransferLib.BridgeSendType _bridgeSendType,
Extension[] calldata _extensions
) external nonReentrant returns (bytes32) {
bytes32 transferId;
{
address _bridgeAddr = bridges[_bridgeSendType];
require(_bridgeAddr != address(0), "unknown bridge type");
IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);
transferId = BridgeTransferLib.sendTransfer(
address(0),
_token,
_amount,
_dstChainId,
_nonce,
_maxSlippage,
_bridgeSendType,
_bridgeAddr
);
}
emit Supplement(_bridgeSendType, transferId, msg.sender, _receiver, _extensions);
return transferId;
}
/**
* @notice Send a cross-chain transfer of native token either via liquidity pool-based bridge or in form of mint/burn.
* @param _receiver The address of the receiver.
* @param _amount The amount of the transfer.
* @param _dstChainId The destination chain ID.
* @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.
* @param _maxSlippage The max slippage accepted, given as percentage in point (pip). Eg. 5000 means 0.5%.
* Must be greater than minimalMaxSlippage. Receiver is guaranteed to receive at least
* (100% - max slippage percentage) * amount or the transfer can be refunded.
* Only applicable to the {BridgeSendType.Liquidity}.
* @param _bridgeSendType The type of bridge used by this transfer. One of the {BridgeSendType} enum.
* @param _extensions A list of extension to be processed by agent, is designed to be used for extending
* present transfer. Contact Celer team to learn about already supported type of extension.
*/
function transferNative(
bytes calldata _receiver,
uint256 _amount,
uint64 _dstChainId,
uint64 _nonce,
uint32 _maxSlippage, // slippage * 1M, eg. 0.5% -> 5000
BridgeTransferLib.BridgeSendType _bridgeSendType,
Extension[] calldata _extensions
) external payable nonReentrant returns (bytes32) {
bytes32 transferId;
{
address _bridgeAddr = bridges[_bridgeSendType];
require(_bridgeAddr != address(0), "unknown bridge type");
require(msg.value == _amount, "amount mismatch");
transferId = BridgeTransferLib.sendNativeTransfer(
address(0),
_amount,
_dstChainId,
_nonce,
_maxSlippage,
_bridgeSendType,
_bridgeAddr
);
}
emit Supplement(_bridgeSendType, transferId, msg.sender, _receiver, _extensions);
return transferId;
}
// ----------------------Admin operation-----------------------
function setBridgeAddress(BridgeTransferLib.BridgeSendType _bridgeSendType, address _addr) public onlyOwner {
require(_addr != address(0), "invalid address");
bridges[_bridgeSendType] = _addr;
emit BridgeUpdated(_bridgeSendType, _addr);
}
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./PbBridge.sol";
import "./PbPegged.sol";
import "./PbPool.sol";
import "../interfaces/IBridge.sol";
import "../interfaces/IOriginalTokenVault.sol";
import "../interfaces/IOriginalTokenVaultV2.sol";
import "../interfaces/IPeggedTokenBridge.sol";
import "../interfaces/IPeggedTokenBridgeV2.sol";
interface INativeWrap {
function nativeWrap() external view returns (address);
}
library BridgeTransferLib {
using SafeERC20 for IERC20;
enum BridgeSendType {
Null,
Liquidity,
PegDeposit,
PegBurn,
PegV2Deposit,
PegV2Burn,
PegV2BurnFrom
}
enum BridgeReceiveType {
Null,
LqRelay,
LqWithdraw,
PegMint,
PegWithdraw,
PegV2Mint,
PegV2Withdraw
}
struct ReceiveInfo {
bytes32 transferId;
address receiver;
address token; // 0 address for native token
uint256 amount;
bytes32 refid; // reference id, e.g., srcTransferId for refund
}
// ============== Internal library functions called by apps ==============
/**
* @notice Send a cross-chain transfer of ERC20 token either via liquidity pool-based bridge or in the form of pegged mint / burn.
* @param _receiver The address of the receiver.
* @param _token The address of the token.
* @param _amount The amount of the transfer.
* @param _dstChainId The destination chain ID.
* @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.
* @param _maxSlippage The max slippage accepted, given as percentage in point (pip). Eg. 5000 means 0.5%.
* Must be greater than minimalMaxSlippage. Receiver is guaranteed to receive at least
* (100% - max slippage percentage) * amount or the transfer can be refunded.
* Only applicable to the {BridgeSendType.Liquidity}.
* @param _bridgeSendType The type of the bridge used by this transfer. One of the {BridgeSendType} enum.
* @param _bridgeAddr The address of the bridge used.
*/
function sendTransfer(
address _receiver,
address _token,
uint256 _amount,
uint64 _dstChainId,
uint64 _nonce,
uint32 _maxSlippage, // slippage * 1M, eg. 0.5% -> 5000
BridgeSendType _bridgeSendType,
address _bridgeAddr
) internal returns (bytes32) {
bytes32 transferId;
IERC20(_token).safeIncreaseAllowance(_bridgeAddr, _amount);
if (_bridgeSendType == BridgeSendType.Liquidity) {
IBridge(_bridgeAddr).send(_receiver, _token, _amount, _dstChainId, _nonce, _maxSlippage);
transferId = keccak256(
abi.encodePacked(address(this), _receiver, _token, _amount, _dstChainId, _nonce, uint64(block.chainid))
);
} else if (_bridgeSendType == BridgeSendType.PegDeposit) {
IOriginalTokenVault(_bridgeAddr).deposit(_token, _amount, _dstChainId, _receiver, _nonce);
transferId = keccak256(
abi.encodePacked(address(this), _token, _amount, _dstChainId, _receiver, _nonce, uint64(block.chainid))
);
} else if (_bridgeSendType == BridgeSendType.PegBurn) {
IPeggedTokenBridge(_bridgeAddr).burn(_token, _amount, _receiver, _nonce);
transferId = keccak256(
abi.encodePacked(address(this), _token, _amount, _receiver, _nonce, uint64(block.chainid))
);
// handle cases where certain tokens do not spend allowance for role-based burn
IERC20(_token).safeApprove(_bridgeAddr, 0);
} else if (_bridgeSendType == BridgeSendType.PegV2Deposit) {
transferId = IOriginalTokenVaultV2(_bridgeAddr).deposit(_token, _amount, _dstChainId, _receiver, _nonce);
} else if (_bridgeSendType == BridgeSendType.PegV2Burn) {
transferId = IPeggedTokenBridgeV2(_bridgeAddr).burn(_token, _amount, _dstChainId, _receiver, _nonce);
// handle cases where certain tokens do not spend allowance for role-based burn
IERC20(_token).safeApprove(_bridgeAddr, 0);
} else if (_bridgeSendType == BridgeSendType.PegV2BurnFrom) {
transferId = IPeggedTokenBridgeV2(_bridgeAddr).burnFrom(_token, _amount, _dstChainId, _receiver, _nonce);
// handle cases where certain tokens do not spend allowance for role-based burn
IERC20(_token).safeApprove(_bridgeAddr, 0);
} else {
revert("bridge send type not supported");
}
return transferId;
}
/**
* @notice Send a cross-chain transfer of native token either via liquidity pool-based bridge or in the form of pegged mint / burn.
* @param _receiver The address of the receiver.
* @param _amount The amount of the transfer.
* @param _dstChainId The destination chain ID.
* @param _nonce A number input to guarantee uniqueness of transferId. Can be timestamp in practice.
* @param _maxSlippage The max slippage accepted, given as percentage in point (pip). Eg. 5000 means 0.5%.
* Must be greater than minimalMaxSlippage. Receiver is guaranteed to receive at least
* (100% - max slippage percentage) * amount or the transfer can be refunded.
* Only applicable to the {BridgeSendType.Liquidity}.
* @param _bridgeSendType The type of the bridge used by this transfer. One of the {BridgeSendType} enum.
* @param _bridgeAddr The address of the bridge used.
*/
function sendNativeTransfer(
address _receiver,
uint256 _amount,
uint64 _dstChainId,
uint64 _nonce,
uint32 _maxSlippage, // slippage * 1M, eg. 0.5% -> 5000
BridgeSendType _bridgeSendType,
address _bridgeAddr
) internal returns (bytes32) {
require(_bridgeSendType == BridgeSendType.Liquidity || _bridgeSendType == BridgeSendType.PegDeposit || _bridgeSendType == BridgeSendType.PegV2Deposit, "Lib: invalid bridge send type");
address _token = INativeWrap(_bridgeAddr).nativeWrap();
bytes32 transferId;
if (_bridgeSendType == BridgeSendType.Liquidity) {
IBridge(_bridgeAddr).sendNative{value: msg.value}(_receiver, _amount, _dstChainId, _nonce, _maxSlippage);
transferId = keccak256(
abi.encodePacked(address(this), _receiver, _token, _amount, _dstChainId, _nonce, uint64(block.chainid))
);
} else if (_bridgeSendType == BridgeSendType.PegDeposit) {
IOriginalTokenVault(_bridgeAddr).depositNative{value: msg.value}(_amount, _dstChainId, _receiver, _nonce);
transferId = keccak256(
abi.encodePacked(address(this), _token, _amount, _dstChainId, _receiver, _nonce, uint64(block.chainid))
);
} else {
// _bridgeSendType == BridgeSendType.PegV2Deposit
transferId = IOriginalTokenVaultV2(_bridgeAddr).depositNative{value: msg.value}(_amount, _dstChainId, _receiver, _nonce);
}
return transferId;
}
/**
* @notice Receive a cross-chain transfer.
* @param _request The serialized request protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
* @param _bridgeReceiveType The type of the received transfer. One of the {BridgeReceiveType} enum.
* @param _bridgeAddr The address of the bridge used.
*/
function receiveTransfer(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers,
BridgeReceiveType _bridgeReceiveType,
address _bridgeAddr
) internal returns (ReceiveInfo memory) {
if (_bridgeReceiveType == BridgeReceiveType.LqRelay) {
return receiveLiquidityRelay(_request, _sigs, _signers, _powers, _bridgeAddr);
} else if (_bridgeReceiveType == BridgeReceiveType.LqWithdraw) {
return receiveLiquidityWithdraw(_request, _sigs, _signers, _powers, _bridgeAddr);
} else if (_bridgeReceiveType == BridgeReceiveType.PegWithdraw) {
return receivePegWithdraw(_request, _sigs, _signers, _powers, _bridgeAddr);
} else if (_bridgeReceiveType == BridgeReceiveType.PegMint) {
return receivePegMint(_request, _sigs, _signers, _powers, _bridgeAddr);
} else if (_bridgeReceiveType == BridgeReceiveType.PegV2Withdraw) {
return receivePegV2Withdraw(_request, _sigs, _signers, _powers, _bridgeAddr);
} else if (_bridgeReceiveType == BridgeReceiveType.PegV2Mint) {
return receivePegV2Mint(_request, _sigs, _signers, _powers, _bridgeAddr);
} else {
revert("bridge receive type not supported");
}
}
/**
* @notice Receive a liquidity bridge relay.
* @param _request The serialized request protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
* @param _bridgeAddr The address of liquidity bridge.
*/
function receiveLiquidityRelay(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers,
address _bridgeAddr
) internal returns (ReceiveInfo memory) {
ReceiveInfo memory recv;
PbBridge.Relay memory request = PbBridge.decRelay(_request);
recv.transferId = keccak256(
abi.encodePacked(
request.sender,
request.receiver,
request.token,
request.amount,
request.srcChainId,
uint64(block.chainid),
request.srcTransferId
)
);
recv.refid = request.srcTransferId;
recv.receiver = request.receiver;
recv.token = request.token;
recv.amount = request.amount;
if (!IBridge(_bridgeAddr).transfers(recv.transferId)) {
IBridge(_bridgeAddr).relay(_request, _sigs, _signers, _powers);
}
return recv;
}
/**
* @notice Receive a liquidity bridge withdrawal.
* @param _request The serialized request protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
* @param _bridgeAddr The address of liquidity bridge.
*/
function receiveLiquidityWithdraw(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers,
address _bridgeAddr
) internal returns (ReceiveInfo memory) {
ReceiveInfo memory recv;
PbPool.WithdrawMsg memory request = PbPool.decWithdrawMsg(_request);
recv.transferId = keccak256(
abi.encodePacked(request.chainid, request.seqnum, request.receiver, request.token, request.amount)
);
recv.refid = request.refid;
recv.receiver = request.receiver;
if (INativeWrap(_bridgeAddr).nativeWrap() == request.token) {
recv.token = address(0);
} else {
recv.token = request.token;
}
recv.amount = request.amount;
if (!IBridge(_bridgeAddr).withdraws(recv.transferId)) {
IBridge(_bridgeAddr).withdraw(_request, _sigs, _signers, _powers);
}
return recv;
}
/**
* @notice Receive an OriginalTokenVault withdrawal.
* @param _request The serialized request protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
* @param _bridgeAddr The address of OriginalTokenVault.
*/
function receivePegWithdraw(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers,
address _bridgeAddr
) internal returns (ReceiveInfo memory) {
ReceiveInfo memory recv;
PbPegged.Withdraw memory request = PbPegged.decWithdraw(_request);
recv.transferId = keccak256(
abi.encodePacked(
request.receiver,
request.token,
request.amount,
request.burnAccount,
request.refChainId,
request.refId
)
);
recv.refid = request.refId;
recv.receiver = request.receiver;
if (INativeWrap(_bridgeAddr).nativeWrap() == request.token) {
recv.token = address(0);
} else {
recv.token = request.token;
}
recv.amount = request.amount;
if (!IOriginalTokenVault(_bridgeAddr).records(recv.transferId)) {
IOriginalTokenVault(_bridgeAddr).withdraw(_request, _sigs, _signers, _powers);
}
return recv;
}
/**
* @notice Receive a PeggedTokenBridge mint.
* @param _request The serialized request protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
* @param _bridgeAddr The address of PeggedTokenBridge.
*/
function receivePegMint(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers,
address _bridgeAddr
) internal returns (ReceiveInfo memory) {
ReceiveInfo memory recv;
PbPegged.Mint memory request = PbPegged.decMint(_request);
recv.transferId = keccak256(
abi.encodePacked(
request.account,
request.token,
request.amount,
request.depositor,
request.refChainId,
request.refId
)
);
recv.refid = request.refId;
recv.receiver = request.account;
recv.token = request.token;
recv.amount = request.amount;
if (!IPeggedTokenBridge(_bridgeAddr).records(recv.transferId)) {
IPeggedTokenBridge(_bridgeAddr).mint(_request, _sigs, _signers, _powers);
}
return recv;
}
/**
* @notice Receive an OriginalTokenVaultV2 withdrawal.
* @param _request The serialized request protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order. A request must be signed-off by
* +2/3 of the bridge's current signing power to be delivered.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
* @param _bridgeAddr The address of OriginalTokenVaultV2.
*/
function receivePegV2Withdraw(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers,
address _bridgeAddr
) internal returns (ReceiveInfo memory) {
ReceiveInfo memory recv;
PbPegged.Withdraw memory request = PbPegged.decWithdraw(_request);
if (IOriginalTokenVaultV2(_bridgeAddr).records(request.refId)) {
recv.transferId = keccak256(
abi.encodePacked(
request.receiver,
request.token,
request.amount,
request.burnAccount,
request.refChainId,
request.refId,
_bridgeAddr
)
);
} else {
recv.transferId = IOriginalTokenVaultV2(_bridgeAddr).withdraw(_request, _sigs, _signers, _powers);
}
recv.refid = request.refId;
recv.receiver = request.receiver;
if (INativeWrap(_bridgeAddr).nativeWrap() == request.token) {
recv.token = address(0);
} else {
recv.token = request.token;
}
recv.amount = request.amount;
return recv;
}
/**
* @notice Receive a PeggedTokenBridgeV2 mint.
* @param _request The serialized request protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order. A request must be signed-off by
* +2/3 of the bridge's current signing power to be delivered.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
* @param _bridgeAddr The address of PeggedTokenBridgeV2.
*/
function receivePegV2Mint(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers,
address _bridgeAddr
) internal returns (ReceiveInfo memory) {
ReceiveInfo memory recv;
PbPegged.Mint memory request = PbPegged.decMint(_request);
if (IPeggedTokenBridgeV2(_bridgeAddr).records(request.refId)) {
recv.transferId = keccak256(
abi.encodePacked(
request.account,
request.token,
request.amount,
request.depositor,
request.refChainId,
request.refId,
_bridgeAddr
)
);
} else {
recv.transferId = IPeggedTokenBridgeV2(_bridgeAddr).mint(_request, _sigs, _signers, _powers);
}
recv.refid = request.refId;
recv.receiver = request.account;
recv.token = request.token;
recv.amount = request.amount;
return recv;
}
function bridgeRefundType(BridgeSendType _bridgeSendType) internal pure returns (BridgeReceiveType) {
if (_bridgeSendType == BridgeSendType.Liquidity) {
return BridgeReceiveType.LqWithdraw;
}
if (_bridgeSendType == BridgeSendType.PegDeposit) {
return BridgeReceiveType.PegWithdraw;
}
if (_bridgeSendType == BridgeSendType.PegBurn) {
return BridgeReceiveType.PegMint;
}
if (_bridgeSendType == BridgeSendType.PegV2Deposit) {
return BridgeReceiveType.PegV2Withdraw;
}
if (_bridgeSendType == BridgeSendType.PegV2Burn || _bridgeSendType == BridgeSendType.PegV2BurnFrom) {
return BridgeReceiveType.PegV2Mint;
}
return BridgeReceiveType.Null;
}
}// SPDX-License-Identifier: GPL-3.0-only
// Code generated by protoc-gen-sol. DO NOT EDIT.
// source: bridge.proto
pragma solidity 0.8.9;
import "./Pb.sol";
library PbBridge {
using Pb for Pb.Buffer; // so we can call Pb funcs on Buffer obj
struct Relay {
address sender; // tag: 1
address receiver; // tag: 2
address token; // tag: 3
uint256 amount; // tag: 4
uint64 srcChainId; // tag: 5
uint64 dstChainId; // tag: 6
bytes32 srcTransferId; // tag: 7
} // end struct Relay
function decRelay(bytes memory raw) internal pure returns (Relay memory m) {
Pb.Buffer memory buf = Pb.fromBytes(raw);
uint256 tag;
Pb.WireType wire;
while (buf.hasMore()) {
(tag, wire) = buf.decKey();
if (false) {}
// solidity has no switch/case
else if (tag == 1) {
m.sender = Pb._address(buf.decBytes());
} else if (tag == 2) {
m.receiver = Pb._address(buf.decBytes());
} else if (tag == 3) {
m.token = Pb._address(buf.decBytes());
} else if (tag == 4) {
m.amount = Pb._uint256(buf.decBytes());
} else if (tag == 5) {
m.srcChainId = uint64(buf.decVarint());
} else if (tag == 6) {
m.dstChainId = uint64(buf.decVarint());
} else if (tag == 7) {
m.srcTransferId = Pb._bytes32(buf.decBytes());
} else {
buf.skipValue(wire);
} // skip value of unknown tag
}
} // end decoder Relay
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.9;
// runtime proto sol library
library Pb {
enum WireType {
Varint,
Fixed64,
LengthDelim,
StartGroup,
EndGroup,
Fixed32
}
struct Buffer {
uint256 idx; // the start index of next read. when idx=b.length, we're done
bytes b; // hold serialized proto msg, readonly
}
// create a new in-memory Buffer object from raw msg bytes
function fromBytes(bytes memory raw) internal pure returns (Buffer memory buf) {
buf.b = raw;
buf.idx = 0;
}
// whether there are unread bytes
function hasMore(Buffer memory buf) internal pure returns (bool) {
return buf.idx < buf.b.length;
}
// decode current field number and wiretype
function decKey(Buffer memory buf) internal pure returns (uint256 tag, WireType wiretype) {
uint256 v = decVarint(buf);
tag = v / 8;
wiretype = WireType(v & 7);
}
// count tag occurrences, return an array due to no memory map support
// have to create array for (maxtag+1) size. cnts[tag] = occurrences
// should keep buf.idx unchanged because this is only a count function
function cntTags(Buffer memory buf, uint256 maxtag) internal pure returns (uint256[] memory cnts) {
uint256 originalIdx = buf.idx;
cnts = new uint256[](maxtag + 1); // protobuf's tags are from 1 rather than 0
uint256 tag;
WireType wire;
while (hasMore(buf)) {
(tag, wire) = decKey(buf);
cnts[tag] += 1;
skipValue(buf, wire);
}
buf.idx = originalIdx;
}
// read varint from current buf idx, move buf.idx to next read, return the int value
function decVarint(Buffer memory buf) internal pure returns (uint256 v) {
bytes10 tmp; // proto int is at most 10 bytes (7 bits can be used per byte)
bytes memory bb = buf.b; // get buf.b mem addr to use in assembly
v = buf.idx; // use v to save one additional uint variable
assembly {
tmp := mload(add(add(bb, 32), v)) // load 10 bytes from buf.b[buf.idx] to tmp
}
uint256 b; // store current byte content
v = 0; // reset to 0 for return value
for (uint256 i = 0; i < 10; i++) {
assembly {
b := byte(i, tmp) // don't use tmp[i] because it does bound check and costs extra
}
v |= (b & 0x7F) << (i * 7);
if (b & 0x80 == 0) {
buf.idx += i + 1;
return v;
}
}
revert(); // i=10, invalid varint stream
}
// read length delimited field and return bytes
function decBytes(Buffer memory buf) internal pure returns (bytes memory b) {
uint256 len = decVarint(buf);
uint256 end = buf.idx + len;
require(end <= buf.b.length); // avoid overflow
b = new bytes(len);
bytes memory bufB = buf.b; // get buf.b mem addr to use in assembly
uint256 bStart;
uint256 bufBStart = buf.idx;
assembly {
bStart := add(b, 32)
bufBStart := add(add(bufB, 32), bufBStart)
}
for (uint256 i = 0; i < len; i += 32) {
assembly {
mstore(add(bStart, i), mload(add(bufBStart, i)))
}
}
buf.idx = end;
}
// return packed ints
function decPacked(Buffer memory buf) internal pure returns (uint256[] memory t) {
uint256 len = decVarint(buf);
uint256 end = buf.idx + len;
require(end <= buf.b.length); // avoid overflow
// array in memory must be init w/ known length
// so we have to create a tmp array w/ max possible len first
uint256[] memory tmp = new uint256[](len);
uint256 i = 0; // count how many ints are there
while (buf.idx < end) {
tmp[i] = decVarint(buf);
i++;
}
t = new uint256[](i); // init t with correct length
for (uint256 j = 0; j < i; j++) {
t[j] = tmp[j];
}
return t;
}
// move idx pass current value field, to beginning of next tag or msg end
function skipValue(Buffer memory buf, WireType wire) internal pure {
if (wire == WireType.Varint) {
decVarint(buf);
} else if (wire == WireType.LengthDelim) {
uint256 len = decVarint(buf);
buf.idx += len; // skip len bytes value data
require(buf.idx <= buf.b.length); // avoid overflow
} else {
revert();
} // unsupported wiretype
}
// type conversion help utils
function _bool(uint256 x) internal pure returns (bool v) {
return x != 0;
}
function _uint256(bytes memory b) internal pure returns (uint256 v) {
require(b.length <= 32); // b's length must be smaller than or equal to 32
assembly {
v := mload(add(b, 32))
} // load all 32bytes to v
v = v >> (8 * (32 - b.length)); // only first b.length is valid
}
function _address(bytes memory b) internal pure returns (address v) {
v = _addressPayable(b);
}
function _addressPayable(bytes memory b) internal pure returns (address payable v) {
require(b.length == 20);
//load 32bytes then shift right 12 bytes
assembly {
v := div(mload(add(b, 32)), 0x1000000000000000000000000)
}
}
function _bytes32(bytes memory b) internal pure returns (bytes32 v) {
require(b.length == 32);
assembly {
v := mload(add(b, 32))
}
}
// uint[] to uint8[]
function uint8s(uint256[] memory arr) internal pure returns (uint8[] memory t) {
t = new uint8[](arr.length);
for (uint256 i = 0; i < t.length; i++) {
t[i] = uint8(arr[i]);
}
}
function uint32s(uint256[] memory arr) internal pure returns (uint32[] memory t) {
t = new uint32[](arr.length);
for (uint256 i = 0; i < t.length; i++) {
t[i] = uint32(arr[i]);
}
}
function uint64s(uint256[] memory arr) internal pure returns (uint64[] memory t) {
t = new uint64[](arr.length);
for (uint256 i = 0; i < t.length; i++) {
t[i] = uint64(arr[i]);
}
}
function bools(uint256[] memory arr) internal pure returns (bool[] memory t) {
t = new bool[](arr.length);
for (uint256 i = 0; i < t.length; i++) {
t[i] = arr[i] != 0;
}
}
}// SPDX-License-Identifier: GPL-3.0-only
// Code generated by protoc-gen-sol. DO NOT EDIT.
// source: contracts/libraries/proto/pegged.proto
pragma solidity 0.8.9;
import "./Pb.sol";
library PbPegged {
using Pb for Pb.Buffer; // so we can call Pb funcs on Buffer obj
struct Mint {
address token; // tag: 1
address account; // tag: 2
uint256 amount; // tag: 3
address depositor; // tag: 4
uint64 refChainId; // tag: 5
bytes32 refId; // tag: 6
} // end struct Mint
function decMint(bytes memory raw) internal pure returns (Mint memory m) {
Pb.Buffer memory buf = Pb.fromBytes(raw);
uint256 tag;
Pb.WireType wire;
while (buf.hasMore()) {
(tag, wire) = buf.decKey();
if (false) {}
// solidity has no switch/case
else if (tag == 1) {
m.token = Pb._address(buf.decBytes());
} else if (tag == 2) {
m.account = Pb._address(buf.decBytes());
} else if (tag == 3) {
m.amount = Pb._uint256(buf.decBytes());
} else if (tag == 4) {
m.depositor = Pb._address(buf.decBytes());
} else if (tag == 5) {
m.refChainId = uint64(buf.decVarint());
} else if (tag == 6) {
m.refId = Pb._bytes32(buf.decBytes());
} else {
buf.skipValue(wire);
} // skip value of unknown tag
}
} // end decoder Mint
struct Withdraw {
address token; // tag: 1
address receiver; // tag: 2
uint256 amount; // tag: 3
address burnAccount; // tag: 4
uint64 refChainId; // tag: 5
bytes32 refId; // tag: 6
} // end struct Withdraw
function decWithdraw(bytes memory raw) internal pure returns (Withdraw memory m) {
Pb.Buffer memory buf = Pb.fromBytes(raw);
uint256 tag;
Pb.WireType wire;
while (buf.hasMore()) {
(tag, wire) = buf.decKey();
if (false) {}
// solidity has no switch/case
else if (tag == 1) {
m.token = Pb._address(buf.decBytes());
} else if (tag == 2) {
m.receiver = Pb._address(buf.decBytes());
} else if (tag == 3) {
m.amount = Pb._uint256(buf.decBytes());
} else if (tag == 4) {
m.burnAccount = Pb._address(buf.decBytes());
} else if (tag == 5) {
m.refChainId = uint64(buf.decVarint());
} else if (tag == 6) {
m.refId = Pb._bytes32(buf.decBytes());
} else {
buf.skipValue(wire);
} // skip value of unknown tag
}
} // end decoder Withdraw
}// SPDX-License-Identifier: GPL-3.0-only
// Code generated by protoc-gen-sol. DO NOT EDIT.
// source: contracts/libraries/proto/pool.proto
pragma solidity 0.8.9;
import "./Pb.sol";
library PbPool {
using Pb for Pb.Buffer; // so we can call Pb funcs on Buffer obj
struct WithdrawMsg {
uint64 chainid; // tag: 1
uint64 seqnum; // tag: 2
address receiver; // tag: 3
address token; // tag: 4
uint256 amount; // tag: 5
bytes32 refid; // tag: 6
} // end struct WithdrawMsg
function decWithdrawMsg(bytes memory raw) internal pure returns (WithdrawMsg memory m) {
Pb.Buffer memory buf = Pb.fromBytes(raw);
uint256 tag;
Pb.WireType wire;
while (buf.hasMore()) {
(tag, wire) = buf.decKey();
if (false) {}
// solidity has no switch/case
else if (tag == 1) {
m.chainid = uint64(buf.decVarint());
} else if (tag == 2) {
m.seqnum = uint64(buf.decVarint());
} else if (tag == 3) {
m.receiver = Pb._address(buf.decBytes());
} else if (tag == 4) {
m.token = Pb._address(buf.decBytes());
} else if (tag == 5) {
m.amount = Pb._uint256(buf.decBytes());
} else if (tag == 6) {
m.refid = Pb._bytes32(buf.decBytes());
} else {
buf.skipValue(wire);
} // skip value of unknown tag
}
} // end decoder WithdrawMsg
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;
interface IBridge {
function send(
address _receiver,
address _token,
uint256 _amount,
uint64 _dstChainId,
uint64 _nonce,
uint32 _maxSlippage
) external;
function sendNative(
address _receiver,
uint256 _amount,
uint64 _dstChainId,
uint64 _nonce,
uint32 _maxSlippage
) external payable;
function relay(
bytes calldata _relayRequest,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external;
function transfers(bytes32 transferId) external view returns (bool);
function withdraws(bytes32 withdrawId) external view returns (bool);
function withdraw(
bytes calldata _wdmsg,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external;
/**
* @notice Verifies that a message is signed by a quorum among the signers.
* @param _msg signed message
* @param _sigs list of signatures sorted by signer addresses in ascending order
* @param _signers sorted list of current signers
* @param _powers powers of current signers
*/
function verifySigs(
bytes memory _msg,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external view;
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;
interface IOriginalTokenVault {
/**
* @notice Lock original tokens to trigger mint at a remote chain's PeggedTokenBridge
* @param _token local token address
* @param _amount locked token amount
* @param _mintChainId destination chainId to mint tokens
* @param _mintAccount destination account to receive minted tokens
* @param _nonce user input to guarantee unique depositId
*/
function deposit(
address _token,
uint256 _amount,
uint64 _mintChainId,
address _mintAccount,
uint64 _nonce
) external;
/**
* @notice Lock native token as original token to trigger mint at a remote chain's PeggedTokenBridge
* @param _amount locked token amount
* @param _mintChainId destination chainId to mint tokens
* @param _mintAccount destination account to receive minted tokens
* @param _nonce user input to guarantee unique depositId
*/
function depositNative(
uint256 _amount,
uint64 _mintChainId,
address _mintAccount,
uint64 _nonce
) external payable;
/**
* @notice Withdraw locked original tokens triggered by a burn at a remote chain's PeggedTokenBridge.
* @param _request The serialized Withdraw protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by
* +2/3 of the bridge's current signing power to be delivered.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
*/
function withdraw(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external;
function records(bytes32 recordId) external view returns (bool);
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;
interface IOriginalTokenVaultV2 {
/**
* @notice Lock original tokens to trigger mint at a remote chain's PeggedTokenBridge
* @param _token local token address
* @param _amount locked token amount
* @param _mintChainId destination chainId to mint tokens
* @param _mintAccount destination account to receive minted tokens
* @param _nonce user input to guarantee unique depositId
*/
function deposit(
address _token,
uint256 _amount,
uint64 _mintChainId,
address _mintAccount,
uint64 _nonce
) external returns (bytes32);
/**
* @notice Lock native token as original token to trigger mint at a remote chain's PeggedTokenBridge
* @param _amount locked token amount
* @param _mintChainId destination chainId to mint tokens
* @param _mintAccount destination account to receive minted tokens
* @param _nonce user input to guarantee unique depositId
*/
function depositNative(
uint256 _amount,
uint64 _mintChainId,
address _mintAccount,
uint64 _nonce
) external payable returns (bytes32);
/**
* @notice Withdraw locked original tokens triggered by a burn at a remote chain's PeggedTokenBridge.
* @param _request The serialized Withdraw protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by
* +2/3 of the bridge's current signing power to be delivered.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
*/
function withdraw(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external returns (bytes32);
function records(bytes32 recordId) external view returns (bool);
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;
interface IPeggedTokenBridge {
/**
* @notice Burn tokens to trigger withdrawal at a remote chain's OriginalTokenVault
* @param _token local token address
* @param _amount locked token amount
* @param _withdrawAccount account who withdraw original tokens on the remote chain
* @param _nonce user input to guarantee unique depositId
*/
function burn(
address _token,
uint256 _amount,
address _withdrawAccount,
uint64 _nonce
) external;
/**
* @notice Mint tokens triggered by deposit at a remote chain's OriginalTokenVault.
* @param _request The serialized Mint protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by
* +2/3 of the sigsVerifier's current signing power to be delivered.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
*/
function mint(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external;
function records(bytes32 recordId) external view returns (bool);
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;
interface IPeggedTokenBridgeV2 {
/**
* @notice Burn pegged tokens to trigger a cross-chain withdrawal of the original tokens at a remote chain's
* OriginalTokenVault, or mint at another remote chain
* @param _token The pegged token address.
* @param _amount The amount to burn.
* @param _toChainId If zero, withdraw from original vault; otherwise, the remote chain to mint tokens.
* @param _toAccount The account to receive tokens on the remote chain
* @param _nonce A number to guarantee unique depositId. Can be timestamp in practice.
*/
function burn(
address _token,
uint256 _amount,
uint64 _toChainId,
address _toAccount,
uint64 _nonce
) external returns (bytes32);
// same with `burn` above, use openzeppelin ERC20Burnable interface
function burnFrom(
address _token,
uint256 _amount,
uint64 _toChainId,
address _toAccount,
uint64 _nonce
) external returns (bytes32);
/**
* @notice Mint tokens triggered by deposit at a remote chain's OriginalTokenVault.
* @param _request The serialized Mint protobuf.
* @param _sigs The list of signatures sorted by signing addresses in ascending order. A relay must be signed-off by
* +2/3 of the sigsVerifier's current signing power to be delivered.
* @param _signers The sorted list of signers.
* @param _powers The signing powers of the signers.
*/
function mint(
bytes calldata _request,
bytes[] calldata _sigs,
address[] calldata _signers,
uint256[] calldata _powers
) external returns (bytes32);
function records(bytes32 recordId) external view returns (bool);
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*
* This adds a normal func that setOwner if _owner is address(0). So we can't allow
* renounceOwnership. So we can support Proxy based upgradable contract
*/
abstract contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_setOwner(msg.sender);
}
/**
* @dev Only to be called by inherit contracts, in their init func called by Proxy
* we require _owner == address(0), which is only possible when it's a delegateCall
* because constructor sets _owner in contract state.
*/
function initOwner() internal {
require(_owner == address(0), "owner already set");
_setOwner(msg.sender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == msg.sender, "Ownable: caller is not the owner");
_;
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}{
"metadata": {
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 800
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum BridgeTransferLib.BridgeSendType","name":"bridgeSendType","type":"uint8"},{"indexed":false,"internalType":"address","name":"bridgeAddr","type":"address"}],"name":"BridgeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum BridgeTransferLib.BridgeSendType","name":"bridgeSendType","type":"uint8"},{"indexed":false,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes","name":"receiver","type":"bytes"},{"components":[{"internalType":"uint8","name":"Type","type":"uint8"},{"internalType":"bytes","name":"Value","type":"bytes"}],"indexed":false,"internalType":"struct TransferAgent.Extension[]","name":"extensions","type":"tuple[]"}],"name":"Supplement","type":"event"},{"inputs":[{"internalType":"enum BridgeTransferLib.BridgeSendType","name":"","type":"uint8"}],"name":"bridges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum BridgeTransferLib.BridgeSendType","name":"_bridgeSendType","type":"uint8"},{"internalType":"address","name":"_addr","type":"address"}],"name":"setBridgeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_receiver","type":"bytes"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint64","name":"_dstChainId","type":"uint64"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"uint32","name":"_maxSlippage","type":"uint32"},{"internalType":"enum BridgeTransferLib.BridgeSendType","name":"_bridgeSendType","type":"uint8"},{"components":[{"internalType":"uint8","name":"Type","type":"uint8"},{"internalType":"bytes","name":"Value","type":"bytes"}],"internalType":"struct TransferAgent.Extension[]","name":"_extensions","type":"tuple[]"}],"name":"transfer","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_receiver","type":"bytes"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint64","name":"_dstChainId","type":"uint64"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"uint32","name":"_maxSlippage","type":"uint32"},{"internalType":"enum BridgeTransferLib.BridgeSendType","name":"_bridgeSendType","type":"uint8"},{"components":[{"internalType":"uint8","name":"Type","type":"uint8"},{"internalType":"bytes","name":"Value","type":"bytes"}],"internalType":"struct TransferAgent.Extension[]","name":"_extensions","type":"tuple[]"}],"name":"transferNative","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50600160005561001f33610024565b610076565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611b97806100856000396000f3fe6080604052600436106100655760003560e01c80638da5cb5b116100435780638da5cb5b1461010d578063c5d8ac7e1461012b578063f2fde38b1461013e57600080fd5b806339b0070c1461006a57806365d67c331461009d5780636701d514146100eb575b600080fd5b34801561007657600080fd5b5061008a6100853660046116d2565b61015e565b6040519081526020015b60405180910390f35b3480156100a957600080fd5b506100d36100b83660046117a7565b6002602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610094565b3480156100f757600080fd5b5061010b6101063660046117c2565b6102cf565b005b34801561011957600080fd5b506001546001600160a01b03166100d3565b61008a6101393660046117f9565b610425565b34801561014a57600080fd5b5061010b6101593660046118ba565b6105c9565b6000600260005414156101b85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000818155908190818760068111156101d5576101d56118d7565b60068111156101e6576101e66118d7565b81526020810191909152604001600020546001600160a01b031690508061024f5760405162461bcd60e51b815260206004820152601360248201527f756e6b6e6f776e2062726964676520747970650000000000000000000000000060448201526064016101af565b6102646001600160a01b038c1633308d6106ba565b61027560008c8c8c8c8c8c88610758565b9150507f3f2b4c063a18045940932b9fba423a72e3b8d36e63ca462720d880f7b64504ca8582338f8f89896040516102b39796959493929190611938565b60405180910390a160016000559b9a5050505050505050505050565b336102e26001546001600160a01b031690565b6001600160a01b0316146103385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101af565b6001600160a01b03811661038e5760405162461bcd60e51b815260206004820152600f60248201527f696e76616c69642061646472657373000000000000000000000000000000000060448201526064016101af565b80600260008460068111156103a5576103a56118d7565b60068111156103b6576103b66118d7565b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055507fe85507dd8a6159a69bf9f4aa5ae1283824ec9948b7d4a03d5cb457070f312dfc8282604051610419929190611a44565b60405180910390a15050565b60006002600054141561047a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016101af565b6002600081815590819081876006811115610497576104976118d7565b60068111156104a8576104a86118d7565b81526020810191909152604001600020546001600160a01b03169050806105115760405162461bcd60e51b815260206004820152601360248201527f756e6b6e6f776e2062726964676520747970650000000000000000000000000060448201526064016101af565b8934146105605760405162461bcd60e51b815260206004820152600f60248201527f616d6f756e74206d69736d61746368000000000000000000000000000000000060448201526064016101af565b61057060008b8b8b8b8b87610d3b565b9150507f3f2b4c063a18045940932b9fba423a72e3b8d36e63ca462720d880f7b64504ca8582338e8e89896040516105ae9796959493929190611938565b60405180910390a160016000559a9950505050505050505050565b336105dc6001546001600160a01b031690565b6001600160a01b0316146106325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101af565b6001600160a01b0381166106ae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101af565b6106b781611115565b50565b6040516001600160a01b03808516602483015283166044820152606481018290526107529085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261117f565b50505050565b60008061076f6001600160a01b038a16848a611269565b6001846006811115610783576107836118d7565b141561089e5760405163a5977fbb60e01b81526001600160a01b038b811660048301528a81166024830152604482018a905267ffffffffffffffff808a1660648401528816608483015263ffffffff871660a483015284169063a5977fbb9060c401600060405180830381600087803b1580156107ff57600080fd5b505af1158015610813573d6000803e3d6000fd5b50506040516bffffffffffffffffffffffff1930606090811b821660208401528e811b821660348401528d901b166048820152605c81018b90526001600160c01b031960c08b811b8216607c8401528a811b8216608484015246901b16608c82015260940191506108819050565b604051602081830303815290604052805190602001209050610d2e565b60028460068111156108b2576108b26118d7565b14156109b8576040516308d18d8960e21b81526001600160a01b038a81166004830152602482018a905267ffffffffffffffff808a1660448401528c821660648401528816608483015284169063234636249060a401600060405180830381600087803b15801561092257600080fd5b505af1158015610936573d6000803e3d6000fd5b50505050308989898d8a466040516020016108819796959493929190606097881b6bffffffffffffffffffffffff19908116825296881b87166014820152602881019590955260c093841b6001600160c01b031990811660488701529290961b909416605084015292811b831660648301529290921b16606c82015260740190565b60038460068111156109cc576109cc6118d7565b1415610ae057604051636f3c863f60e11b81526001600160a01b038a81166004830152602482018a90528b8116604483015267ffffffffffffffff8816606483015284169063de790c7e90608401600060405180830381600087803b158015610a3457600080fd5b505af1158015610a48573d6000803e3d6000fd5b50506040516bffffffffffffffffffffffff1930606090811b821660208401528d811b82166034840152604883018d90528e901b1660688201526001600160c01b031960c08a811b8216607c84015246901b166084820152608c019150610aac9050565b60408051601f1981840301815291905280516020909101209050610adb6001600160a01b038a1684600061132a565b610d2e565b6004846006811115610af457610af46118d7565b1415610ba3576040516308d18d8960e21b81526001600160a01b038a81166004830152602482018a905267ffffffffffffffff808a1660448401528c821660648401528816608483015284169063234636249060a401602060405180830381600087803b158015610b6457600080fd5b505af1158015610b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9c9190611a68565b9050610d2e565b6005846006811115610bb757610bb76118d7565b1415610c775760405163a002930160e01b81526001600160a01b038a81166004830152602482018a905267ffffffffffffffff808a1660448401528c821660648401528816608483015284169063a00293019060a4015b602060405180830381600087803b158015610c2857600080fd5b505af1158015610c3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c609190611a68565b9050610adb6001600160a01b038a1684600061132a565b6006846006811115610c8b57610c8b6118d7565b1415610ce657604051639e422c3360e01b81526001600160a01b038a81166004830152602482018a905267ffffffffffffffff808a1660448401528c8216606484015288166084830152841690639e422c339060a401610c0e565b60405162461bcd60e51b815260206004820152601e60248201527f6272696467652073656e642074797065206e6f7420737570706f72746564000060448201526064016101af565b9998505050505050505050565b60006001836006811115610d5157610d516118d7565b1480610d6e57506002836006811115610d6c57610d6c6118d7565b145b80610d8a57506004836006811115610d8857610d886118d7565b145b610dd65760405162461bcd60e51b815260206004820152601d60248201527f4c69623a20696e76616c6964206272696467652073656e64207479706500000060448201526064016101af565b6000826001600160a01b031663457bfa2f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e1157600080fd5b505afa158015610e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e499190611a81565b905060006001856006811115610e6157610e616118d7565b1415610f5957604051633f2e5fc360e01b81526001600160a01b038b81166004830152602482018b905267ffffffffffffffff808b1660448401528916606483015263ffffffff88166084830152851690633f2e5fc390349060a4016000604051808303818588803b158015610ed657600080fd5b505af1158015610eea573d6000803e3d6000fd5b50506040516bffffffffffffffffffffffff1930606090811b821660208401528f811b8216603484015287901b166048820152605c81018d90526001600160c01b031960c08d811b8216607c8401528c811b8216608484015246901b16608c8201526094019250610881915050565b6002856006811115610f6d57610f6d6118d7565b141561106c5760405162a95fd760e01b8152600481018a905267ffffffffffffffff808a1660248301526001600160a01b038c81166044840152908916606483015285169062a95fd79034906084016000604051808303818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b505050505030828a8a8d8b466040516020016108819796959493929190606097881b6bffffffffffffffffffffffff19908116825296881b87166014820152602881019590955260c093841b6001600160c01b031990811660488701529290961b909416605084015292811b831660648301529290921b16606c82015260740190565b60405162a95fd760e01b8152600481018a905267ffffffffffffffff808a1660248301526001600160a01b038c81166044840152908916606483015285169062a95fd79034906084016020604051808303818588803b1580156110ce57600080fd5b505af11580156110e2573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906111079190611a68565b9a9950505050505050505050565b600180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006111d4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166114559092919063ffffffff16565b80519091501561126457808060200190518101906111f29190611a9e565b6112645760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101af565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e9060440160206040518083038186803b1580156112b557600080fd5b505afa1580156112c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ed9190611a68565b6112f79190611ac0565b6040516001600160a01b03851660248201526044810182905290915061075290859063095ea7b360e01b906064016106ee565b8015806113b35750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561137957600080fd5b505afa15801561138d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b19190611a68565b155b6114255760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016101af565b6040516001600160a01b03831660248201526044810182905261126490849063095ea7b360e01b906064016106ee565b6060611464848460008561146e565b90505b9392505050565b6060824710156114e65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101af565b6001600160a01b0385163b61153d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101af565b600080866001600160a01b031685876040516115599190611b12565b60006040518083038185875af1925050503d8060008114611596576040519150601f19603f3d011682016040523d82523d6000602084013e61159b565b606091505b50915091506115ab8282866115b6565b979650505050505050565b606083156115c5575081611467565b8251156115d55782518084602001fd5b8160405162461bcd60e51b81526004016101af9190611b2e565b60008083601f84011261160157600080fd5b50813567ffffffffffffffff81111561161957600080fd5b60208301915083602082850101111561163157600080fd5b9250929050565b6001600160a01b03811681146106b757600080fd5b803567ffffffffffffffff8116811461166557600080fd5b919050565b803563ffffffff8116811461166557600080fd5b80356007811061166557600080fd5b60008083601f84011261169f57600080fd5b50813567ffffffffffffffff8111156116b757600080fd5b6020830191508360208260051b850101111561163157600080fd5b6000806000806000806000806000806101008b8d0312156116f257600080fd5b8a3567ffffffffffffffff8082111561170a57600080fd5b6117168e838f016115ef565b909c509a5060208d0135915061172b82611638565b81995060408d0135985061174160608e0161164d565b975061174f60808e0161164d565b965061175d60a08e0161166a565b955061176b60c08e0161167e565b945060e08d013591508082111561178157600080fd5b5061178e8d828e0161168d565b915080935050809150509295989b9194979a5092959850565b6000602082840312156117b957600080fd5b6114678261167e565b600080604083850312156117d557600080fd5b6117de8361167e565b915060208301356117ee81611638565b809150509250929050565b600080600080600080600080600060e08a8c03121561181757600080fd5b893567ffffffffffffffff8082111561182f57600080fd5b61183b8d838e016115ef565b909b50995060208c0135985089915061185660408d0161164d565b975061186460608d0161164d565b965061187260808d0161166a565b955061188060a08d0161167e565b945060c08c013591508082111561189657600080fd5b506118a38c828d0161168d565b915080935050809150509295985092959850929598565b6000602082840312156118cc57600080fd5b813561146781611638565b634e487b7160e01b600052602160045260246000fd5b6007811061190b57634e487b7160e01b600052602160045260246000fd5b9052565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61194281896118ed565b60006020888184015260406001600160a01b0389168185015260a0606085015261197060a08501888a61190f565b8481036080860152858152828101600587901b820184018860005b89811015611a3057848303601f190184528135368c9003603e190181126119b157600080fd5b8b01803560ff81168082146119c557600080fd5b8552508088013536829003601e190181126119df57600080fd5b8101803567ffffffffffffffff8111156119f857600080fd5b803603831315611a0757600080fd5b888a870152611a1b898701828c850161190f565b968a019695505050918701915060010161198b565b50909e9d5050505050505050505050505050565b60408101611a5282856118ed565b6001600160a01b03831660208301529392505050565b600060208284031215611a7a57600080fd5b5051919050565b600060208284031215611a9357600080fd5b815161146781611638565b600060208284031215611ab057600080fd5b8151801515811461146757600080fd5b60008219821115611ae157634e487b7160e01b600052601160045260246000fd5b500190565b60005b83811015611b01578181015183820152602001611ae9565b838111156107525750506000910152565b60008251611b24818460208701611ae6565b9190910192915050565b6020815260008251806020840152611b4d816040850160208701611ae6565b601f01601f1916919091016040019291505056fea2646970667358221220561fe3475257c3c94d9125e0e6e7679cfe936272130de55c816a352cb0f7609264736f6c63430008090033
Deployed Bytecode
0x6080604052600436106100655760003560e01c80638da5cb5b116100435780638da5cb5b1461010d578063c5d8ac7e1461012b578063f2fde38b1461013e57600080fd5b806339b0070c1461006a57806365d67c331461009d5780636701d514146100eb575b600080fd5b34801561007657600080fd5b5061008a6100853660046116d2565b61015e565b6040519081526020015b60405180910390f35b3480156100a957600080fd5b506100d36100b83660046117a7565b6002602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610094565b3480156100f757600080fd5b5061010b6101063660046117c2565b6102cf565b005b34801561011957600080fd5b506001546001600160a01b03166100d3565b61008a6101393660046117f9565b610425565b34801561014a57600080fd5b5061010b6101593660046118ba565b6105c9565b6000600260005414156101b85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000818155908190818760068111156101d5576101d56118d7565b60068111156101e6576101e66118d7565b81526020810191909152604001600020546001600160a01b031690508061024f5760405162461bcd60e51b815260206004820152601360248201527f756e6b6e6f776e2062726964676520747970650000000000000000000000000060448201526064016101af565b6102646001600160a01b038c1633308d6106ba565b61027560008c8c8c8c8c8c88610758565b9150507f3f2b4c063a18045940932b9fba423a72e3b8d36e63ca462720d880f7b64504ca8582338f8f89896040516102b39796959493929190611938565b60405180910390a160016000559b9a5050505050505050505050565b336102e26001546001600160a01b031690565b6001600160a01b0316146103385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101af565b6001600160a01b03811661038e5760405162461bcd60e51b815260206004820152600f60248201527f696e76616c69642061646472657373000000000000000000000000000000000060448201526064016101af565b80600260008460068111156103a5576103a56118d7565b60068111156103b6576103b66118d7565b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055507fe85507dd8a6159a69bf9f4aa5ae1283824ec9948b7d4a03d5cb457070f312dfc8282604051610419929190611a44565b60405180910390a15050565b60006002600054141561047a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016101af565b6002600081815590819081876006811115610497576104976118d7565b60068111156104a8576104a86118d7565b81526020810191909152604001600020546001600160a01b03169050806105115760405162461bcd60e51b815260206004820152601360248201527f756e6b6e6f776e2062726964676520747970650000000000000000000000000060448201526064016101af565b8934146105605760405162461bcd60e51b815260206004820152600f60248201527f616d6f756e74206d69736d61746368000000000000000000000000000000000060448201526064016101af565b61057060008b8b8b8b8b87610d3b565b9150507f3f2b4c063a18045940932b9fba423a72e3b8d36e63ca462720d880f7b64504ca8582338e8e89896040516105ae9796959493929190611938565b60405180910390a160016000559a9950505050505050505050565b336105dc6001546001600160a01b031690565b6001600160a01b0316146106325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101af565b6001600160a01b0381166106ae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101af565b6106b781611115565b50565b6040516001600160a01b03808516602483015283166044820152606481018290526107529085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261117f565b50505050565b60008061076f6001600160a01b038a16848a611269565b6001846006811115610783576107836118d7565b141561089e5760405163a5977fbb60e01b81526001600160a01b038b811660048301528a81166024830152604482018a905267ffffffffffffffff808a1660648401528816608483015263ffffffff871660a483015284169063a5977fbb9060c401600060405180830381600087803b1580156107ff57600080fd5b505af1158015610813573d6000803e3d6000fd5b50506040516bffffffffffffffffffffffff1930606090811b821660208401528e811b821660348401528d901b166048820152605c81018b90526001600160c01b031960c08b811b8216607c8401528a811b8216608484015246901b16608c82015260940191506108819050565b604051602081830303815290604052805190602001209050610d2e565b60028460068111156108b2576108b26118d7565b14156109b8576040516308d18d8960e21b81526001600160a01b038a81166004830152602482018a905267ffffffffffffffff808a1660448401528c821660648401528816608483015284169063234636249060a401600060405180830381600087803b15801561092257600080fd5b505af1158015610936573d6000803e3d6000fd5b50505050308989898d8a466040516020016108819796959493929190606097881b6bffffffffffffffffffffffff19908116825296881b87166014820152602881019590955260c093841b6001600160c01b031990811660488701529290961b909416605084015292811b831660648301529290921b16606c82015260740190565b60038460068111156109cc576109cc6118d7565b1415610ae057604051636f3c863f60e11b81526001600160a01b038a81166004830152602482018a90528b8116604483015267ffffffffffffffff8816606483015284169063de790c7e90608401600060405180830381600087803b158015610a3457600080fd5b505af1158015610a48573d6000803e3d6000fd5b50506040516bffffffffffffffffffffffff1930606090811b821660208401528d811b82166034840152604883018d90528e901b1660688201526001600160c01b031960c08a811b8216607c84015246901b166084820152608c019150610aac9050565b60408051601f1981840301815291905280516020909101209050610adb6001600160a01b038a1684600061132a565b610d2e565b6004846006811115610af457610af46118d7565b1415610ba3576040516308d18d8960e21b81526001600160a01b038a81166004830152602482018a905267ffffffffffffffff808a1660448401528c821660648401528816608483015284169063234636249060a401602060405180830381600087803b158015610b6457600080fd5b505af1158015610b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9c9190611a68565b9050610d2e565b6005846006811115610bb757610bb76118d7565b1415610c775760405163a002930160e01b81526001600160a01b038a81166004830152602482018a905267ffffffffffffffff808a1660448401528c821660648401528816608483015284169063a00293019060a4015b602060405180830381600087803b158015610c2857600080fd5b505af1158015610c3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c609190611a68565b9050610adb6001600160a01b038a1684600061132a565b6006846006811115610c8b57610c8b6118d7565b1415610ce657604051639e422c3360e01b81526001600160a01b038a81166004830152602482018a905267ffffffffffffffff808a1660448401528c8216606484015288166084830152841690639e422c339060a401610c0e565b60405162461bcd60e51b815260206004820152601e60248201527f6272696467652073656e642074797065206e6f7420737570706f72746564000060448201526064016101af565b9998505050505050505050565b60006001836006811115610d5157610d516118d7565b1480610d6e57506002836006811115610d6c57610d6c6118d7565b145b80610d8a57506004836006811115610d8857610d886118d7565b145b610dd65760405162461bcd60e51b815260206004820152601d60248201527f4c69623a20696e76616c6964206272696467652073656e64207479706500000060448201526064016101af565b6000826001600160a01b031663457bfa2f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e1157600080fd5b505afa158015610e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e499190611a81565b905060006001856006811115610e6157610e616118d7565b1415610f5957604051633f2e5fc360e01b81526001600160a01b038b81166004830152602482018b905267ffffffffffffffff808b1660448401528916606483015263ffffffff88166084830152851690633f2e5fc390349060a4016000604051808303818588803b158015610ed657600080fd5b505af1158015610eea573d6000803e3d6000fd5b50506040516bffffffffffffffffffffffff1930606090811b821660208401528f811b8216603484015287901b166048820152605c81018d90526001600160c01b031960c08d811b8216607c8401528c811b8216608484015246901b16608c8201526094019250610881915050565b6002856006811115610f6d57610f6d6118d7565b141561106c5760405162a95fd760e01b8152600481018a905267ffffffffffffffff808a1660248301526001600160a01b038c81166044840152908916606483015285169062a95fd79034906084016000604051808303818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b505050505030828a8a8d8b466040516020016108819796959493929190606097881b6bffffffffffffffffffffffff19908116825296881b87166014820152602881019590955260c093841b6001600160c01b031990811660488701529290961b909416605084015292811b831660648301529290921b16606c82015260740190565b60405162a95fd760e01b8152600481018a905267ffffffffffffffff808a1660248301526001600160a01b038c81166044840152908916606483015285169062a95fd79034906084016020604051808303818588803b1580156110ce57600080fd5b505af11580156110e2573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906111079190611a68565b9a9950505050505050505050565b600180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006111d4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166114559092919063ffffffff16565b80519091501561126457808060200190518101906111f29190611a9e565b6112645760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016101af565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e9060440160206040518083038186803b1580156112b557600080fd5b505afa1580156112c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ed9190611a68565b6112f79190611ac0565b6040516001600160a01b03851660248201526044810182905290915061075290859063095ea7b360e01b906064016106ee565b8015806113b35750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561137957600080fd5b505afa15801561138d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b19190611a68565b155b6114255760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016101af565b6040516001600160a01b03831660248201526044810182905261126490849063095ea7b360e01b906064016106ee565b6060611464848460008561146e565b90505b9392505050565b6060824710156114e65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016101af565b6001600160a01b0385163b61153d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101af565b600080866001600160a01b031685876040516115599190611b12565b60006040518083038185875af1925050503d8060008114611596576040519150601f19603f3d011682016040523d82523d6000602084013e61159b565b606091505b50915091506115ab8282866115b6565b979650505050505050565b606083156115c5575081611467565b8251156115d55782518084602001fd5b8160405162461bcd60e51b81526004016101af9190611b2e565b60008083601f84011261160157600080fd5b50813567ffffffffffffffff81111561161957600080fd5b60208301915083602082850101111561163157600080fd5b9250929050565b6001600160a01b03811681146106b757600080fd5b803567ffffffffffffffff8116811461166557600080fd5b919050565b803563ffffffff8116811461166557600080fd5b80356007811061166557600080fd5b60008083601f84011261169f57600080fd5b50813567ffffffffffffffff8111156116b757600080fd5b6020830191508360208260051b850101111561163157600080fd5b6000806000806000806000806000806101008b8d0312156116f257600080fd5b8a3567ffffffffffffffff8082111561170a57600080fd5b6117168e838f016115ef565b909c509a5060208d0135915061172b82611638565b81995060408d0135985061174160608e0161164d565b975061174f60808e0161164d565b965061175d60a08e0161166a565b955061176b60c08e0161167e565b945060e08d013591508082111561178157600080fd5b5061178e8d828e0161168d565b915080935050809150509295989b9194979a5092959850565b6000602082840312156117b957600080fd5b6114678261167e565b600080604083850312156117d557600080fd5b6117de8361167e565b915060208301356117ee81611638565b809150509250929050565b600080600080600080600080600060e08a8c03121561181757600080fd5b893567ffffffffffffffff8082111561182f57600080fd5b61183b8d838e016115ef565b909b50995060208c0135985089915061185660408d0161164d565b975061186460608d0161164d565b965061187260808d0161166a565b955061188060a08d0161167e565b945060c08c013591508082111561189657600080fd5b506118a38c828d0161168d565b915080935050809150509295985092959850929598565b6000602082840312156118cc57600080fd5b813561146781611638565b634e487b7160e01b600052602160045260246000fd5b6007811061190b57634e487b7160e01b600052602160045260246000fd5b9052565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61194281896118ed565b60006020888184015260406001600160a01b0389168185015260a0606085015261197060a08501888a61190f565b8481036080860152858152828101600587901b820184018860005b89811015611a3057848303601f190184528135368c9003603e190181126119b157600080fd5b8b01803560ff81168082146119c557600080fd5b8552508088013536829003601e190181126119df57600080fd5b8101803567ffffffffffffffff8111156119f857600080fd5b803603831315611a0757600080fd5b888a870152611a1b898701828c850161190f565b968a019695505050918701915060010161198b565b50909e9d5050505050505050505050505050565b60408101611a5282856118ed565b6001600160a01b03831660208301529392505050565b600060208284031215611a7a57600080fd5b5051919050565b600060208284031215611a9357600080fd5b815161146781611638565b600060208284031215611ab057600080fd5b8151801515811461146757600080fd5b60008219821115611ae157634e487b7160e01b600052601160045260246000fd5b500190565b60005b83811015611b01578181015183820152602001611ae9565b838111156107525750506000910152565b60008251611b24818460208701611ae6565b9190910192915050565b6020815260008251806020840152611b4d816040850160208701611ae6565b601f01601f1916919091016040019291505056fea2646970667358221220561fe3475257c3c94d9125e0e6e7679cfe936272130de55c816a352cb0f7609264736f6c63430008090033
Deployed Bytecode Sourcemap
572:5109:10:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2221:1039;;;;;;;;;;-1:-1:-1;2221:1039:10;;;;;:::i;:::-;;:::i;:::-;;;2890:25:16;;;2878:2;2863:18;2221:1039:10;;;;;;;;733:67;;;;;;;;;;-1:-1:-1;733:67:10;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;733:67:10;;;;;;-1:-1:-1;;;;;3311:55:16;;;3293:74;;3281:2;3266:18;733:67:10;3147:226:16;5413:266:10;;;;;;;;;;-1:-1:-1;5413:266:10;;;;;:::i;:::-;;:::i;:::-;;1479:85:11;;;;;;;;;;-1:-1:-1;1551:6:11;;-1:-1:-1;;;;;1551:6:11;1479:85;;4346:992:10;;;;;;:::i;:::-;;:::i;1916:189:11:-;;;;;;;;;;-1:-1:-1;1916:189:11;;;;;:::i;:::-;;:::i;2221:1039:10:-;2574:7;1744:1:12;2325:7;;:19;;2317:63;;;;-1:-1:-1;;;2317:63:12;;5377:2:16;2317:63:12;;;5359:21:16;5416:2;5396:18;;;5389:30;5455:33;5435:18;;;5428:61;5506:18;;2317:63:12;;;;;;;;;1744:1;2455:7;:18;;;:7;;;;2665:15:10;2657:24:::1;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;2657:24:10;;-1:-1:-1;;;;;2657:24:10::1;::::0;-1:-1:-1;2703:25:10;2695:57:::1;;;::::0;-1:-1:-1;;;2695:57:10;;5869:2:16;2695:57:10::1;::::0;::::1;5851:21:16::0;5908:2;5888:18;;;5881:30;5947:21;5927:18;;;5920:49;5986:18;;2695:57:10::1;5667:343:16::0;2695:57:10::1;2766:67;-1:-1:-1::0;;;;;2766:31:10;::::1;2798:10;2818:4;2825:7:::0;2766:31:::1;:67::i;:::-;2860:266;2916:1;2936:6;2960:7;2985:11;3014:6;3038:12;3068:15;3101:11;2860:30;:266::i;:::-;2847:279;;2621:516;3151:75;3162:15;3179:10;3191;3203:9;;3214:11;;3151:75;;;;;;;;;;;;:::i;:::-;;;;;;;;1701:1:12::0;2628:7;:22;3243:10:10;2221:1039;-1:-1:-1;;;;;;;;;;;2221:1039:10:o;5413:266::-;1702:10:11;1691:7;1551:6;;-1:-1:-1;;;;;1551:6:11;;1479:85;1691:7;-1:-1:-1;;;;;1691:21:11;;1683:66;;;;-1:-1:-1;;;1683:66:11;;8905:2:16;1683:66:11;;;8887:21:16;;;8924:18;;;8917:30;8983:34;8963:18;;;8956:62;9035:18;;1683:66:11;8703:356:16;1683:66:11;-1:-1:-1;;;;;5539:19:10;::::1;5531:47;;;::::0;-1:-1:-1;;;5531:47:10;;9266:2:16;5531:47:10::1;::::0;::::1;9248:21:16::0;9305:2;9285:18;;;9278:30;9344:17;9324:18;;;9317:45;9379:18;;5531:47:10::1;9064:339:16::0;5531:47:10::1;5615:5;5588:7;:24;5596:15;5588:24;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:32;;;;;-1:-1:-1::0;;;;;5588:32:10::1;;;;;-1:-1:-1::0;;;;;5588:32:10::1;;;;;;5635:37;5649:15;5666:5;5635:37;;;;;;;:::i;:::-;;;;;;;;5413:266:::0;;:::o;4346:992::-;4689:7;1744:1:12;2325:7;;:19;;2317:63;;;;-1:-1:-1;;;2317:63:12;;5377:2:16;2317:63:12;;;5359:21:16;5416:2;5396:18;;;5389:30;5455:33;5435:18;;;5428:61;5506:18;;2317:63:12;5175:355:16;2317:63:12;1744:1;2455:7;:18;;;:7;;;;4780:15:10;4772:24:::1;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;4772:24:10;;-1:-1:-1;;;;;4772:24:10::1;::::0;-1:-1:-1;4818:25:10;4810:57:::1;;;::::0;-1:-1:-1;;;4810:57:10;;5869:2:16;4810:57:10::1;::::0;::::1;5851:21:16::0;5908:2;5888:18;;;5881:30;5947:21;5927:18;;;5920:49;5986:18;;4810:57:10::1;5667:343:16::0;4810:57:10::1;4902:7;4889:9;:20;4881:48;;;::::0;-1:-1:-1;;;4881:48:10;;9952:2:16;4881:48:10::1;::::0;::::1;9934:21:16::0;9991:2;9971:18;;;9964:30;10030:17;10010:18;;;10003:45;10065:18;;4881:48:10::1;9750:339:16::0;4881:48:10::1;4956:248;5018:1;5038:7;5063:11;5092:6;5116:12;5146:15;5179:11;4956:36;:248::i;:::-;4943:261;;4736:479;5229:75;5240:15;5257:10;5269;5281:9;;5292:11;;5229:75;;;;;;;;;;;;:::i;:::-;;;;;;;;1701:1:12::0;2628:7;:22;5321:10:10;4346:992;-1:-1:-1;;;;;;;;;;4346:992:10:o;1916:189:11:-;1702:10;1691:7;1551:6;;-1:-1:-1;;;;;1551:6:11;;1479:85;1691:7;-1:-1:-1;;;;;1691:21:11;;1683:66;;;;-1:-1:-1;;;1683:66:11;;8905:2:16;1683:66:11;;;8887:21:16;;;8924:18;;;8917:30;8983:34;8963:18;;;8956:62;9035:18;;1683:66:11;8703:356:16;1683:66:11;-1:-1:-1;;;;;2004:22:11;::::1;1996:73;;;::::0;-1:-1:-1;;;1996:73:11;;10296:2:16;1996:73:11::1;::::0;::::1;10278:21:16::0;10335:2;10315:18;;;10308:30;10374:34;10354:18;;;10347:62;10445:8;10425:18;;;10418:36;10471:19;;1996:73:11::1;10094:402:16::0;1996:73:11::1;2079:19;2089:8;2079:9;:19::i;:::-;1916:189:::0;:::o;912:241:14:-;1077:68;;-1:-1:-1;;;;;10782:15:16;;;1077:68:14;;;10764:34:16;10834:15;;10814:18;;;10807:43;10866:18;;;10859:34;;;1050:96:14;;1070:5;;-1:-1:-1;;;1100:27:14;10676:18:16;;1077:68:14;;;;-1:-1:-1;;1077:68:14;;;;;;;;;;;;;;;;;;;;;;;;;;;1050:19;:96::i;:::-;912:241;;;;:::o;2282:2506:5:-;2588:7;;2635:58;-1:-1:-1;;;;;2635:36:5;;2672:11;2685:7;2635:36;:58::i;:::-;2726:24;2707:15;:43;;;;;;;;:::i;:::-;;2703:2052;;;2766:88;;-1:-1:-1;;;2766:88:5;;-1:-1:-1;;;;;11264:15:16;;;2766:88:5;;;11246:34:16;11316:15;;;11296:18;;;11289:43;11348:18;;;11341:34;;;11394:18;11448:15;;;11428:18;;;11421:43;11501:15;;11480:19;;;11473:44;11566:10;11554:23;;11533:19;;;11526:52;2766:25:5;;;;;11157:19:16;;2766:88:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2908:103:5;;-1:-1:-1;;2933:4:5;11950:2:16;11946:15;;;11942:24;;2908:103:5;;;11930:37:16;12001:15;;;11997:24;;11983:12;;;11976:46;12056:15;;;12052:24;12038:12;;;12031:46;12093:12;;;12086:28;;;-1:-1:-1;;;;;;12237:3:16;12233:16;;;12229:25;;12215:12;;;12208:47;12290:16;;;12286:25;;12271:13;;;12264:48;2996:13:5;12347:16:16;;12343:25;12328:13;;;12321:48;12385:13;;;-1:-1:-1;2908:103:5;;-1:-1:-1;11589:815:16;2908:103:5;;;;;;;;;;;;;2881:144;;;;;;2868:157;;2703:2052;;;3065:25;3046:15;:44;;;;;;;;:::i;:::-;;3042:1713;;;3106:89;;-1:-1:-1;;;3106:89:5;;-1:-1:-1;;;;;12743:15:16;;;3106:89:5;;;12725:34:16;12775:18;;;12768:34;;;12821:18;12875:15;;;12855:18;;;12848:43;12927:15;;;12907:18;;;12900:43;12980:15;;12959:19;;;12952:44;3106:40:5;;;;;12636:19:16;;3106:89:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3274:4;3281:6;3289:7;3298:11;3311:9;3322:6;3337:13;3249:103;;;;;;;;;;;;;13368:2:16;13364:15;;;-1:-1:-1;;13360:24:16;;;13348:37;;13419:15;;;13415:24;;13410:2;13401:12;;13394:46;13465:2;13456:12;;13449:28;;;;13600:3;13596:16;;;-1:-1:-1;;;;;;13592:25:16;;;13587:2;13578:12;;13571:47;13652:15;;;;13648:24;;;13643:2;13634:12;;13627:46;13708:16;;;13704:25;;13698:3;13689:13;;13682:48;13765:16;;;;13761:25;13755:3;13746:13;;13739:48;13812:3;13803:13;;13007:815;3042:1713:5;3406:22;3387:15;:41;;;;;;;;:::i;:::-;;3383:1372;;;3444:72;;-1:-1:-1;;;3444:72:5;;-1:-1:-1;;;;;14135:15:16;;;3444:72:5;;;14117:34:16;14167:18;;;14160:34;;;14230:15;;;14210:18;;;14203:43;14294:18;14282:31;;14262:18;;;14255:59;3444:36:5;;;;;14028:19:16;;3444:72:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3570:90:5;;-1:-1:-1;;3595:4:5;14660:2:16;14656:15;;;14652:24;;3570:90:5;;;14640:37:16;14711:15;;;14707:24;;14693:12;;;14686:46;14748:12;;;14741:28;;;14803:15;;;14799:24;14785:12;;;14778:46;-1:-1:-1;;;;;;14947:3:16;14943:16;;;14939:25;;14925:12;;;14918:47;3645:13:5;15000:16:16;;14996:25;14981:13;;;14974:48;15038:13;;;-1:-1:-1;3570:90:5;;-1:-1:-1;14325:732:16;3570:90:5;;;;-1:-1:-1;;3570:90:5;;;;;;;;;3543:131;;3570:90;3543:131;;;;;-1:-1:-1;3780:42:5;-1:-1:-1;;;;;3780:26:5;;3807:11;3820:1;3780:26;:42::i;:::-;3383:1372;;;3862:27;3843:15;:46;;;;;;;;:::i;:::-;;3839:916;;;3918:91;;-1:-1:-1;;;3918:91:5;;-1:-1:-1;;;;;12743:15:16;;;3918:91:5;;;12725:34:16;12775:18;;;12768:34;;;12821:18;12875:15;;;12855:18;;;12848:43;12927:15;;;12907:18;;;12900:43;12980:15;;12959:19;;;12952:44;3918:42:5;;;;;12636:19:16;;3918:91:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3905:104;;3839:916;;;4049:24;4030:15;:43;;;;;;;;:::i;:::-;;4026:729;;;4102:87;;-1:-1:-1;;;4102:87:5;;-1:-1:-1;;;;;12743:15:16;;;4102:87:5;;;12725:34:16;12775:18;;;12768:34;;;12821:18;12875:15;;;12855:18;;;12848:43;12927:15;;;12907:18;;;12900:43;12980:15;;12959:19;;;12952:44;4102:38:5;;;;;12636:19:16;;4102:87:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4089:100;-1:-1:-1;4295:42:5;-1:-1:-1;;;;;4295:26:5;;4322:11;4335:1;4295:26;:42::i;4026:729::-;4377:28;4358:15;:47;;;;;;;;:::i;:::-;;4354:401;;;4434:91;;-1:-1:-1;;;4434:91:5;;-1:-1:-1;;;;;12743:15:16;;;4434:91:5;;;12725:34:16;12775:18;;;12768:34;;;12821:18;12875:15;;;12855:18;;;12848:43;12927:15;;;12907:18;;;12900:43;12980:15;;12959:19;;;12952:44;4434:42:5;;;;;12636:19:16;;4434:91:5;12409:593:16;4354:401:5;4704:40;;-1:-1:-1;;;4704:40:5;;15453:2:16;4704:40:5;;;15435:21:16;15492:2;15472:18;;;15465:30;15531:32;15511:18;;;15504:60;15581:18;;4704:40:5;15251:354:16;4354:401:5;4771:10;2282:2506;-1:-1:-1;;;;;;;;;2282:2506:5:o;5737:1544::-;6025:7;6071:24;6052:15;:43;;;;;;;;:::i;:::-;;:91;;;-1:-1:-1;6118:25:5;6099:15;:44;;;;;;;;:::i;:::-;;6052:91;:141;;;-1:-1:-1;6166:27:5;6147:15;:46;;;;;;;;:::i;:::-;;6052:141;6044:183;;;;-1:-1:-1;;;6044:183:5;;15812:2:16;6044:183:5;;;15794:21:16;15851:2;15831:18;;;15824:30;15890:31;15870:18;;;15863:59;15939:18;;6044:183:5;15610:353:16;6044:183:5;6237:14;6266:11;-1:-1:-1;;;;;6254:35:5;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6237:54;-1:-1:-1;6301:18:5;6352:24;6333:15;:43;;;;;;;;:::i;:::-;;6329:919;;;6392:104;;-1:-1:-1;;;6392:104:5;;-1:-1:-1;;;;;16495:55:16;;;6392:104:5;;;16477:74:16;16567:18;;;16560:34;;;16613:18;16667:15;;;16647:18;;;16640:43;16719:15;;16699:18;;;16692:43;16784:10;16772:23;;16751:19;;;16744:52;6392:31:5;;;;;6431:9;;16449:19:16;;6392:104:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6550:103:5;;-1:-1:-1;;6575:4:5;11950:2:16;11946:15;;;11942:24;;6550:103:5;;;11930:37:16;12001:15;;;11997:24;;11983:12;;;11976:46;12056:15;;;12052:24;12038:12;;;12031:46;12093:12;;;12086:28;;;-1:-1:-1;;;;;;12237:3:16;12233:16;;;12229:25;;12215:12;;;12208:47;12290:16;;;12286:25;;12271:13;;;12264:48;6638:13:5;12347:16:16;;12343:25;12328:13;;;12321:48;12385:13;;;-1:-1:-1;6550:103:5;;-1:-1:-1;;11589:815:16;6329:919:5;6707:25;6688:15;:44;;;;;;;;:::i;:::-;;6684:564;;;6748:105;;-1:-1:-1;;;6748:105:5;;;;;17034:25:16;;;17078:18;17132:15;;;17112:18;;;17105:43;-1:-1:-1;;;;;17184:55:16;;;17164:18;;;17157:83;17276:15;;;17256:18;;;17249:43;6748:46:5;;;;;6802:9;;17006:19:16;;6748:105:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6932:4;6939:6;6947:7;6956:11;6969:9;6980:6;6995:13;6907:103;;;;;;;;;;;;;13368:2:16;13364:15;;;-1:-1:-1;;13360:24:16;;;13348:37;;13419:15;;;13415:24;;13410:2;13401:12;;13394:46;13465:2;13456:12;;13449:28;;;;13600:3;13596:16;;;-1:-1:-1;;;;;;13592:25:16;;;13587:2;13578:12;;13571:47;13652:15;;;;13648:24;;;13643:2;13634:12;;13627:46;13708:16;;;13704:25;;13698:3;13689:13;;13682:48;13765:16;;;;13761:25;13755:3;13746:13;;13739:48;13812:3;13803:13;;13007:815;6684:564:5;7130:107;;-1:-1:-1;;;7130:107:5;;;;;17034:25:16;;;17078:18;17132:15;;;17112:18;;;17105:43;-1:-1:-1;;;;;17184:55:16;;;17164:18;;;17157:83;17276:15;;;17256:18;;;17249:43;7130:48:5;;;;;7186:9;;17006:19:16;;7130:107:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7117:120;7264:10;-1:-1:-1;;;;;;;;;;5737:1544:5:o;2111:169:11:-;2185:6;;;-1:-1:-1;;;;;2201:17:11;;;;;;;;;;;2233:40;;2185:6;;;2201:17;2185:6;;2233:40;;2166:16;;2233:40;2156:124;2111:169;:::o;3207:706:14:-;3626:23;3652:69;3680:4;3652:69;;;;;;;;;;;;;;;;;3660:5;-1:-1:-1;;;;;3652:27:14;;;:69;;;;;:::i;:::-;3735:17;;3626:95;;-1:-1:-1;3735:21:14;3731:176;;3830:10;3819:30;;;;;;;;;;;;:::i;:::-;3811:85;;;;-1:-1:-1;;;3811:85:14;;17787:2:16;3811:85:14;;;17769:21:16;17826:2;17806:18;;;17799:30;17865:34;17845:18;;;17838:62;17936:12;17916:18;;;17909:40;17966:19;;3811:85:14;17585:406:16;3811:85:14;3277:636;3207:706;;:::o;2022:310::-;2171:39;;-1:-1:-1;;;2171:39:14;;2195:4;2171:39;;;18231:34:16;-1:-1:-1;;;;;18301:15:16;;;18281:18;;;18274:43;2148:20:14;;2213:5;;2171:15;;;;;18143:18:16;;2171:39:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;;;:::i;:::-;2255:69;;-1:-1:-1;;;;;18939:55:16;;2255:69:14;;;18921:74:16;19011:18;;;19004:34;;;2148:70:14;;-1:-1:-1;2228:97:14;;2248:5;;-1:-1:-1;;;2278:22:14;18894:18:16;;2255:69:14;18747:297:16;1413:603:14;1768:10;;;1767:62;;-1:-1:-1;1784:39:14;;-1:-1:-1;;;1784:39:14;;1808:4;1784:39;;;18231:34:16;-1:-1:-1;;;;;18301:15:16;;;18281:18;;;18274:43;1784:15:14;;;;;18143:18:16;;1784:39:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;1767:62;1746:163;;;;-1:-1:-1;;;1746:163:14;;19251:2:16;1746:163:14;;;19233:21:16;19290:2;19270:18;;;19263:30;19329:34;19309:18;;;19302:62;19400:24;19380:18;;;19373:52;19442:19;;1746:163:14;19049:418:16;1746:163:14;1946:62;;-1:-1:-1;;;;;18939:55:16;;1946:62:14;;;18921:74:16;19011:18;;;19004:34;;;1919:90:14;;1939:5;;-1:-1:-1;;;1969:22:14;18894:18:16;;1946:62:14;18747:297:16;3861:223:15;3994:12;4025:52;4047:6;4055:4;4061:1;4064:12;4025:21;:52::i;:::-;4018:59;;3861:223;;;;;;:::o;4948:499::-;5113:12;5170:5;5145:21;:30;;5137:81;;;;-1:-1:-1;;;5137:81:15;;19674:2:16;5137:81:15;;;19656:21:16;19713:2;19693:18;;;19686:30;19752:34;19732:18;;;19725:62;19823:8;19803:18;;;19796:36;19849:19;;5137:81:15;19472:402:16;5137:81:15;-1:-1:-1;;;;;1465:19:15;;;5228:60;;;;-1:-1:-1;;;5228:60:15;;20081:2:16;5228:60:15;;;20063:21:16;20120:2;20100:18;;;20093:30;20159:31;20139:18;;;20132:59;20208:18;;5228:60:15;19879:353:16;5228:60:15;5300:12;5314:23;5341:6;-1:-1:-1;;;;;5341:11:15;5360:5;5367:4;5341:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5299:73;;;;5389:51;5406:7;5415:10;5427:12;5389:16;:51::i;:::-;5382:58;4948:499;-1:-1:-1;;;;;;;4948:499:15:o;7561:692::-;7707:12;7735:7;7731:516;;;-1:-1:-1;7765:10:15;7758:17;;7731:516;7876:17;;:21;7872:365;;8070:10;8064:17;8130:15;8117:10;8113:2;8109:19;8102:44;7872:365;8209:12;8202:20;;-1:-1:-1;;;8202:20:15;;;;;;;;:::i;14:347:16:-;65:8;75:6;129:3;122:4;114:6;110:17;106:27;96:55;;147:1;144;137:12;96:55;-1:-1:-1;170:20:16;;213:18;202:30;;199:50;;;245:1;242;235:12;199:50;282:4;274:6;270:17;258:29;;334:3;327:4;318:6;310;306:19;302:30;299:39;296:59;;;351:1;348;341:12;296:59;14:347;;;;;:::o;366:154::-;-1:-1:-1;;;;;445:5:16;441:54;434:5;431:65;421:93;;510:1;507;500:12;525:171;592:20;;652:18;641:30;;631:41;;621:69;;686:1;683;676:12;621:69;525:171;;;:::o;701:163::-;768:20;;828:10;817:22;;807:33;;797:61;;854:1;851;844:12;869:155;949:20;;998:1;988:12;;978:40;;1014:1;1011;1004:12;1029:385;1110:8;1120:6;1174:3;1167:4;1159:6;1155:17;1151:27;1141:55;;1192:1;1189;1182:12;1141:55;-1:-1:-1;1215:20:16;;1258:18;1247:30;;1244:50;;;1290:1;1287;1280:12;1244:50;1327:4;1319:6;1315:17;1303:29;;1387:3;1380:4;1370:6;1367:1;1363:14;1355:6;1351:27;1347:38;1344:47;1341:67;;;1404:1;1401;1394:12;1419:1320;1623:6;1631;1639;1647;1655;1663;1671;1679;1687;1695;1748:3;1736:9;1727:7;1723:23;1719:33;1716:53;;;1765:1;1762;1755:12;1716:53;1805:9;1792:23;1834:18;1875:2;1867:6;1864:14;1861:34;;;1891:1;1888;1881:12;1861:34;1930:58;1980:7;1971:6;1960:9;1956:22;1930:58;:::i;:::-;2007:8;;-1:-1:-1;1904:84:16;-1:-1:-1;2092:2:16;2077:18;;2064:32;;-1:-1:-1;2105:31:16;2064:32;2105:31;:::i;:::-;2155:5;2145:15;;2207:2;2196:9;2192:18;2179:32;2169:42;;2230:37;2263:2;2252:9;2248:18;2230:37;:::i;:::-;2220:47;;2286:38;2319:3;2308:9;2304:19;2286:38;:::i;:::-;2276:48;;2343:38;2376:3;2365:9;2361:19;2343:38;:::i;:::-;2333:48;;2400:51;2446:3;2435:9;2431:19;2400:51;:::i;:::-;2390:61;;2504:3;2493:9;2489:19;2476:33;2460:49;;2534:2;2524:8;2521:16;2518:36;;;2550:1;2547;2540:12;2518:36;;2589:90;2671:7;2660:8;2649:9;2645:24;2589:90;:::i;:::-;2563:116;;2698:8;2688:18;;;2725:8;2715:18;;;1419:1320;;;;;;;;;;;;;:::o;2926:216::-;3003:6;3056:2;3044:9;3035:7;3031:23;3027:32;3024:52;;;3072:1;3069;3062:12;3024:52;3095:41;3126:9;3095:41;:::i;3378:351::-;3464:6;3472;3525:2;3513:9;3504:7;3500:23;3496:32;3493:52;;;3541:1;3538;3531:12;3493:52;3564:41;3595:9;3564:41;:::i;:::-;3554:51;;3655:2;3644:9;3640:18;3627:32;3668:31;3693:5;3668:31;:::i;:::-;3718:5;3708:15;;;3378:351;;;;;:::o;3734:1184::-;3929:6;3937;3945;3953;3961;3969;3977;3985;3993;4046:3;4034:9;4025:7;4021:23;4017:33;4014:53;;;4063:1;4060;4053:12;4014:53;4103:9;4090:23;4132:18;4173:2;4165:6;4162:14;4159:34;;;4189:1;4186;4179:12;4159:34;4228:58;4278:7;4269:6;4258:9;4254:22;4228:58;:::i;:::-;4305:8;;-1:-1:-1;4202:84:16;-1:-1:-1;4387:2:16;4372:18;;4359:32;;-1:-1:-1;4202:84:16;;-1:-1:-1;4410:37:16;4443:2;4428:18;;4410:37;:::i;:::-;4400:47;;4466:37;4499:2;4488:9;4484:18;4466:37;:::i;:::-;4456:47;;4522:38;4555:3;4544:9;4540:19;4522:38;:::i;:::-;4512:48;;4579:51;4625:3;4614:9;4610:19;4579:51;:::i;:::-;4569:61;;4683:3;4672:9;4668:19;4655:33;4639:49;;4713:2;4703:8;4700:16;4697:36;;;4729:1;4726;4719:12;4697:36;;4768:90;4850:7;4839:8;4828:9;4824:24;4768:90;:::i;:::-;4742:116;;4877:8;4867:18;;;4904:8;4894:18;;;3734:1184;;;;;;;;;;;:::o;4923:247::-;4982:6;5035:2;5023:9;5014:7;5010:23;5006:32;5003:52;;;5051:1;5048;5041:12;5003:52;5090:9;5077:23;5109:31;5134:5;5109:31;:::i;5535:127::-;5596:10;5591:3;5587:20;5584:1;5577:31;5627:4;5624:1;5617:15;5651:4;5648:1;5641:15;6015:242;6101:1;6094:5;6091:12;6081:143;;6146:10;6141:3;6137:20;6134:1;6127:31;6181:4;6178:1;6171:15;6209:4;6206:1;6199:15;6081:143;6233:18;;6015:242::o;6262:266::-;6350:6;6345:3;6338:19;6402:6;6395:5;6388:4;6383:3;6379:14;6366:43;-1:-1:-1;6454:1:16;6429:16;;;6447:4;6425:27;;;6418:38;;;;6510:2;6489:15;;;-1:-1:-1;;6485:29:16;6476:39;;;6472:50;;6262:266::o;6533:2165::-;6916:49;6955:9;6947:6;6916:49;:::i;:::-;6897:4;6984:2;7022:6;7017:2;7006:9;7002:18;6995:34;7048:2;-1:-1:-1;;;;;7090:6:16;7086:55;7081:2;7070:9;7066:18;7059:83;7178:3;7173:2;7162:9;7158:18;7151:31;7205:62;7262:3;7251:9;7247:19;7239:6;7231;7205:62;:::i;:::-;7304:22;;;7298:3;7283:19;;7276:51;7362:22;;;7400:15;;;7458:1;7454:14;;;7442:27;;7438:36;;7497:6;7521:1;7531:1138;7545:6;7542:1;7539:13;7531:1138;;;7610:19;;;-1:-1:-1;;7606:33:16;7594:46;;7679:20;;7754:14;7750:27;;;-1:-1:-1;;7746:41:16;7722:66;;7712:94;;7802:1;7799;7792:12;7712:94;7832:31;;7891:19;;7946:4;7933:18;;7974:15;;;7964:43;;8003:1;8000;7993:12;7964:43;8020:18;;-1:-1:-1;8092:14:16;;;8079:28;8164:14;8160:26;;;-1:-1:-1;;8156:40:16;8130:67;;8120:95;;8211:1;8208;8201:12;8120:95;8243:32;;8302:21;;8350:18;8339:30;;8336:50;;;8382:1;8379;8372:12;8336:50;8433:6;8417:14;8413:27;8406:5;8402:39;8399:59;;;8454:1;8451;8444:12;8399:59;8495:2;8490;8482:6;8478:15;8471:27;8521:68;8585:2;8577:6;8573:15;8565:6;8560:2;8551:7;8547:16;8521:68;:::i;:::-;8647:12;;;;8511:78;-1:-1:-1;;;8612:15:16;;;;-1:-1:-1;7567:1:16;7560:9;7531:1138;;;-1:-1:-1;8686:6:16;;6533:2165;-1:-1:-1;;;;;;;;;;;;;;6533:2165:16:o;9408:337::-;9586:2;9571:18;;9598:49;9575:9;9629:6;9598:49;:::i;:::-;-1:-1:-1;;;;;9687:6:16;9683:55;9678:2;9667:9;9663:18;9656:83;9408:337;;;;;:::o;15062:184::-;15132:6;15185:2;15173:9;15164:7;15160:23;15156:32;15153:52;;;15201:1;15198;15191:12;15153:52;-1:-1:-1;15224:16:16;;15062:184;-1:-1:-1;15062:184:16:o;15968:251::-;16038:6;16091:2;16079:9;16070:7;16066:23;16062:32;16059:52;;;16107:1;16104;16097:12;16059:52;16139:9;16133:16;16158:31;16183:5;16158:31;:::i;17303:277::-;17370:6;17423:2;17411:9;17402:7;17398:23;17394:32;17391:52;;;17439:1;17436;17429:12;17391:52;17471:9;17465:16;17524:5;17517:13;17510:21;17503:5;17500:32;17490:60;;17546:1;17543;17536:12;18517:225;18557:3;18588:1;18584:6;18581:1;18578:13;18575:136;;;18633:10;18628:3;18624:20;18621:1;18614:31;18668:4;18665:1;18658:15;18696:4;18693:1;18686:15;18575:136;-1:-1:-1;18727:9:16;;18517:225::o;20237:258::-;20309:1;20319:113;20333:6;20330:1;20327:13;20319:113;;;20409:11;;;20403:18;20390:11;;;20383:39;20355:2;20348:10;20319:113;;;20450:6;20447:1;20444:13;20441:48;;;-1:-1:-1;;20485:1:16;20467:16;;20460:27;20237:258::o;20500:274::-;20629:3;20667:6;20661:13;20683:53;20729:6;20724:3;20717:4;20709:6;20705:17;20683:53;:::i;:::-;20752:16;;;;;20500:274;-1:-1:-1;;20500:274:16:o;20779:383::-;20928:2;20917:9;20910:21;20891:4;20960:6;20954:13;21003:6;20998:2;20987:9;20983:18;20976:34;21019:66;21078:6;21073:2;21062:9;21058:18;21053:2;21045:6;21041:15;21019:66;:::i;:::-;21146:2;21125:15;-1:-1:-1;;21121:29:16;21106:45;;;;21153:2;21102:54;;20779:383;-1:-1:-1;;20779:383:16:o
Swarm Source
ipfs://561fe3475257c3c94d9125e0e6e7679cfe936272130de55c816a352cb0f76092
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.