Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
Latest 25 from a total of 953 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer Native | 22117386 | 24 hrs ago | IN | 0.01 ETH | 0.00034355 | ||||
Transfer Native | 22117285 | 24 hrs ago | IN | 0.006 ETH | 0.00023316 | ||||
Transfer Native | 21979144 | 20 days ago | IN | 0.006 ETH | 0.00014002 | ||||
Transfer Native | 21880072 | 34 days ago | IN | 0.5 ETH | 0.0000877 | ||||
Transfer | 21872952 | 35 days ago | IN | 0 ETH | 0.00018555 | ||||
Transfer | 21835795 | 40 days ago | IN | 0 ETH | 0.00020333 | ||||
Transfer Native | 21814671 | 43 days ago | IN | 0.01 ETH | 0.00009414 | ||||
Transfer | 21761588 | 50 days ago | IN | 0 ETH | 0.00117944 | ||||
Transfer | 21761492 | 50 days ago | IN | 0 ETH | 0.00095745 | ||||
Transfer | 21681508 | 61 days ago | IN | 0 ETH | 0.00182078 | ||||
Transfer | 21580100 | 76 days ago | IN | 0 ETH | 0.00133669 | ||||
Transfer | 21502498 | 86 days ago | IN | 0 ETH | 0.00111322 | ||||
Transfer | 21432547 | 96 days ago | IN | 0 ETH | 0.00165875 | ||||
Transfer | 21432049 | 96 days ago | IN | 0 ETH | 0.00478253 | ||||
Transfer | 21429384 | 97 days ago | IN | 0 ETH | 0.00224345 | ||||
Transfer | 21414937 | 99 days ago | IN | 0 ETH | 0.00214224 | ||||
Transfer | 21399687 | 101 days ago | IN | 0 ETH | 0.00120185 | ||||
Transfer Native | 21398700 | 101 days ago | IN | 0.02995816 ETH | 0.00080919 | ||||
Transfer | 21397026 | 101 days ago | IN | 0 ETH | 0.00153219 | ||||
Transfer Native | 21381335 | 103 days ago | IN | 5.92929692 ETH | 0.00337335 | ||||
Transfer | 21368032 | 105 days ago | IN | 0 ETH | 0.00618823 | ||||
Transfer | 21348947 | 108 days ago | IN | 0 ETH | 0.00140308 | ||||
Transfer | 21338533 | 109 days ago | IN | 0 ETH | 0.00400194 | ||||
Transfer | 21302611 | 114 days ago | IN | 0 ETH | 0.00193114 | ||||
Transfer | 21292574 | 116 days ago | IN | 0 ETH | 0.00118979 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
Deposit Native | 22117386 | 24 hrs ago | 0.01 ETH | ||||
Deposit Native | 22117285 | 24 hrs ago | 0.006 ETH | ||||
Deposit Native | 21979144 | 20 days ago | 0.006 ETH | ||||
Deposit Native | 21880072 | 34 days ago | 0.5 ETH | ||||
Deposit Native | 21814671 | 43 days ago | 0.01 ETH | ||||
Deposit Native | 21398700 | 101 days ago | 0.02995816 ETH | ||||
Deposit Native | 21381335 | 103 days ago | 5.92929692 ETH | ||||
Deposit Native | 21228702 | 125 days ago | 0.1 ETH | ||||
Deposit Native | 21194869 | 129 days ago | 0.03780401 ETH | ||||
Deposit Native | 21194393 | 129 days ago | 0.006249 ETH | ||||
Deposit Native | 21194124 | 129 days ago | 0.018733 ETH | ||||
Deposit Native | 21145359 | 136 days ago | 0.03 ETH | ||||
Deposit Native | 21008716 | 155 days ago | 0.015 ETH | ||||
Deposit Native | 21006723 | 156 days ago | 0.33 ETH | ||||
Deposit Native | 20995261 | 157 days ago | 0.0051 ETH | ||||
Deposit Native | 20967717 | 161 days ago | 0.11901265 ETH | ||||
Deposit Native | 20948982 | 164 days ago | 0.81 ETH | ||||
Deposit Native | 20915147 | 168 days ago | 0.1 ETH | ||||
Deposit Native | 20871883 | 174 days ago | 0.04 ETH | ||||
Deposit Native | 20790581 | 186 days ago | 0.58 ETH | ||||
Deposit Native | 20679027 | 201 days ago | 0.368 ETH | ||||
Deposit Native | 20530378 | 222 days ago | 0.35 ETH | ||||
Deposit Native | 20310727 | 253 days ago | 0.0051 ETH | ||||
Deposit Native | 20174230 | 272 days ago | 0.04501591 ETH | ||||
Deposit Native | 20085461 | 284 days ago | 0.02 ETH |
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
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.