Spend less on fees, more on crypto. Buy crypto easily with MoonPay Balance. 20M+ users trust MoonPay worldwide.
Don’t invest unless you’re prepared to lose all the money you invest.
3000+ Slots, 20+ Cryptos, 75K Raffle, Sports Promos - World's largest Crypto Casino & Sportsbook - Provably Fair!
Play in crypto to make deposits and withdrawals easy! Register and get a free daily shot at a 100 000 $ jackpot.
Monthly Wagering Contest - $500,000+ rewards. Provably Fair, Low House Edge and best VIP Program!
Daily free Spin 50000 Matic ,760% Deposit Bonus, 20%Rakeback, And Get 1000000 Matic free bonus on BC.Game
Deposit BONUS 300% and Cashbacks. without verification!
Holidays are coming soon! Start betting on 1xBit and get a secret gift from Santa!
Overview
POL Balance
POL Value
$0.08 (@ $0.58/POL)Token Holdings
Could not find any matches!
- ERC-20 Tokens (25)0.028109 USDT(PoS) Tether... (USDT)$0.03@1.001161.05000054 IMXImpermax (IMX)$0.11@0.00070.002549 USDC.eUSD Coin (Po... (USDC.e)$0.00@1.003.05105923 WOOWOO (WOO)$0.86@0.28310.14 POLPolygon Toke... (POL)$0.08@0.57650.00002076 WETHWrapped Ethe... (WETH)$0.08@3,699.756215,000 WPOL [ POL-MAT.COM ] Visit to claim rewardERC-20: ! (WPOL [...)62.83 pAAVEERC-20: AAVEPool.... (pAAVE)10,000 BOSQUEERC-20: BOSQUE (BOSQUE)0.0172234 ECKNEcoban0.25 MDUSMedieus Token$0.00@0.0002300,000 MNEPMinereum Polygon50,000 TBBT.orgERC-20: TBBT.org (TBBT.o...)1 Use just official link: TRUSTBOX.SITEERC-20: TRUST WAL... (Use ju...)1 Use just official link: Trust-earn.xyzERC-20: TRUST WAL... (Use ju...)200 WGCWild Goat Coin$0.07@0.000360,000 TokenERC-20 TOKEN*[Suspicious]6,568 TokenERC-20 TOKEN*[Unsafe]15,000 TokenERC-20 TOKEN*[Spam]10,000 TokenERC-20 TOKEN*[Spam]4,894 TokenERC-20 TOKEN*[Spam]500 TokenERC-20 TOKEN*[Spam]3,000,000 TokenERC-20 TOKEN*[Spam]2,999.9 TokenERC-20 TOKEN*[Spam]52 TokenERC-20 TOKEN*[Spam]NFT Tokens (14)NFT Airdrop Round0.05 WBTCERC-1155NFT Airdrop Round15,000 ADAERC-1155Base Chain Raffle5.00 ETH by BaseERC-1155NFT Airdrop6000 WOOERC-1155ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]
More Info
Private Name Tags
ContractCreator
Multichain Info
4 addresses found via- Transactions
- Internal Transactions
- Token Transfers (ERC-20)
- NFT Transfers
- Contract
- Events
- Multichain Portfolio
Advanced Filter- Filter by Tx Type:
- Tx
- Internal Tx
- ERC-20
- NFTs
Latest 25 from a total of 30,220 transactions
Transaction Hash MethodBlockFromToStart Bridge Tok... 28989158 2022-05-31 10:42:50 923 days ago 1653993770 IN 0 POL$0.00 0.01148202 39.8 Start Bridge Tok... 28988825 2022-05-31 10:31:19 923 days ago 1653993079 IN 0 POL$0.00 0.00802713 30.00000001 Swap And Start B... 28988793 2022-05-31 10:30:07 923 days ago 1653993007 IN 119 POL$68.89 0.01739916 40 Swap And Start B... 28988675 2022-05-31 10:26:07 923 days ago 1653992767 IN 40 POL$23.16 0.03684915 50 Swap And Start B... 28988604 2022-05-31 10:23:32 923 days ago 1653992612 IN 10 POL$5.79 0.03076292 40 Start Bridge Tok... 28988517 2022-05-31 10:20:34 923 days ago 1653992434 IN 0 POL$0.00 0.0154254 50 Swap And Start B... 28988300 2022-05-31 10:13:08 923 days ago 1653991988 IN 25 POL$14.47 0.0314935 50 Swap And Start B... 28988286 2022-05-31 10:12:32 923 days ago 1653991952 IN 0 POL$0.00 0.0171094 40 Start Bridge Tok... 28988262 2022-05-31 10:11:44 923 days ago 1653991904 IN 0 POL$0.00 0.01518865 50 Swap And Start B... 28988248 2022-05-31 10:11:16 923 days ago 1653991876 IN 100 POL$57.89 0.01933764 40 Swap And Start B... 28988188 2022-05-31 10:09:12 923 days ago 1653991752 IN 0 POL$0.00 0.018917 50 Start Bridge Tok... 28988146 2022-05-31 10:07:44 923 days ago 1653991664 IN 0 POL$0.00 0.01418465 50 Start Bridge Tok... 28988114 2022-05-31 10:06:40 923 days ago 1653991600 IN 0 POL$0.00 0.0134056 50 Start Bridge Tok... 28987926 2022-05-31 10:00:12 923 days ago 1653991212 IN 0 POL$0.00 0.00600265 50 Start Bridge Tok... 28987904 2022-05-31 9:59:28 923 days ago 1653991168 IN 0 POL$0.00 0.01418465 50 Start Bridge Tok... 28987869 2022-05-31 9:57:06 923 days ago 1653991026 IN 0 POL$0.00 0.0066105 50 Swap And Start B... 28987824 2022-05-31 9:54:32 923 days ago 1653990872 IN 0 POL$0.00 0.03186875 50 Swap And Start B... 28987771 2022-05-31 9:52:42 923 days ago 1653990762 IN 0 POL$0.00 0.02404695 50 Start Bridge Tok... 28987769 2022-05-31 9:52:38 923 days ago 1653990758 IN 0 POL$0.00 0.01035892 40 Start Bridge Tok... 28987752 2022-05-31 9:52:04 923 days ago 1653990724 IN 0 POL$0.00 0.0066105 50 Start Bridge Tok... 28987681 2022-05-31 9:49:38 923 days ago 1653990578 IN 0 POL$0.00 0.00430832 34.3257644 Start Bridge Tok... 28987674 2022-05-31 9:49:24 923 days ago 1653990564 IN 0 POL$0.00 0.02536212 140 Start Bridge Tok... 28987610 2022-05-31 9:47:12 923 days ago 1653990432 IN 0 POL$0.00 0.0055169 50 Start Bridge Tok... 28987592 2022-05-31 9:46:36 923 days ago 1653990396 IN 0 POL$0.00 0.01182821 41 Start Bridge Tok... 28987540 2022-05-31 9:44:48 923 days ago 1653990288 IN 0 POL$0.00 0.01000868 35.27999999 Latest 25 internal transactions (View All)
Parent Transaction Hash Block From To 28988793 2022-05-31 10:30:07 923 days ago 1653993007 119 POL$68.89 28988675 2022-05-31 10:26:07 923 days ago 1653992767 40 POL$23.16 28988604 2022-05-31 10:23:32 923 days ago 1653992612 10 POL$5.79 28988453 2022-05-31 10:18:22 923 days ago 1653992302 119.27275213 POL$69.05 28988453 2022-05-31 10:18:22 923 days ago 1653992302 119.27275213 POL$69.05 28988357 2022-05-31 10:15:06 923 days ago 1653992106 119.66784217 POL$69.27 28988357 2022-05-31 10:15:06 923 days ago 1653992106 119.66784217 POL$69.27 28988300 2022-05-31 10:13:08 923 days ago 1653991988 25 POL$14.47 28988248 2022-05-31 10:11:16 923 days ago 1653991876 100 POL$57.89 28987389 2022-05-31 9:39:34 923 days ago 1653989974 64 POL$37.05 28987008 2022-05-31 9:26:32 923 days ago 1653989192 2 wei$0.00 28987008 2022-05-31 9:26:32 923 days ago 1653989192 0.069 POL$0.04 28986740 2022-05-31 9:17:16 923 days ago 1653988636 0.066 POL$0.04 28986683 2022-05-31 9:15:18 923 days ago 1653988518 137.7211151 POL$79.73 28986683 2022-05-31 9:15:18 923 days ago 1653988518 137.7211151 POL$79.73 28986656 2022-05-31 9:14:24 923 days ago 1653988464 3.01448149 POL$1.75 28986656 2022-05-31 9:14:24 923 days ago 1653988464 3.01448149 POL$1.75 28986529 2022-05-31 9:10:02 923 days ago 1653988202 20 POL$11.58 28986497 2022-05-31 9:08:58 923 days ago 1653988138 0.052 POL$0.03 28985683 2022-05-31 8:40:50 923 days ago 1653986450 15 POL$8.68 28985538 2022-05-31 8:35:52 923 days ago 1653986152 0.08 POL$0.05 28985536 2022-05-31 8:35:48 923 days ago 1653986148 4 POL$2.32 28985315 2022-05-31 8:26:02 923 days ago 1653985562 2 wei$0.00 28985315 2022-05-31 8:26:02 923 days ago 1653985562 0.07 POL$0.04 28984378 2022-05-31 7:53:48 923 days ago 1653983628 0.043 POL$0.02 Loading...LoadingThis contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.Contract Name:LiFiDiamond
Compiler Versionv0.8.7+commit.e28d00a7
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import { LibDiamond } from "./Libraries/LibDiamond.sol"; import { IDiamondCut } from "./Interfaces/IDiamondCut.sol"; contract LiFiDiamond { constructor(address _contractOwner, address _diamondCutFacet) payable { LibDiamond.setContractOwner(_contractOwner); // Add the diamondCut external function from the diamondCutFacet IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); bytes4[] memory functionSelectors = new bytes4[](1); functionSelectors[0] = IDiamondCut.diamondCut.selector; cut[0] = IDiamondCut.FacetCut({ facetAddress: _diamondCutFacet, action: IDiamondCut.FacetCutAction.Add, functionSelectors: functionSelectors }); LibDiamond.diamondCut(cut, address(0), ""); } // Find facet for function that is called and execute the // function if a facet is found and return any value. // solhint-disable-next-line no-complex-fallback fallback() external payable { LibDiamond.DiamondStorage storage ds; bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; // get diamond storage // solhint-disable-next-line no-inline-assembly assembly { ds.slot := position } // get facet from function selector address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress; require(facet != address(0), "Diamond: Function does not exist"); // Execute external function from facet using delegatecall and return any value. // solhint-disable-next-line no-inline-assembly assembly { // copy function selector and any arguments calldatacopy(0, 0, calldatasize()) // execute function call using the facet let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) // get any return value returndatacopy(0, 0, returndatasize()) // return any return value or error back to the caller switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } // Able to receive ether // solhint-disable-next-line no-empty-blocks receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ILiFi } from "../Interfaces/ILiFi.sol"; import { IAnyswapRouter } from "../Interfaces/IAnyswapRouter.sol"; import { LibDiamond } from "../Libraries/LibDiamond.sol"; import { LibAsset } from "../Libraries/LibAsset.sol"; import { LibSwap } from "../Libraries/LibSwap.sol"; import { IAnyswapToken } from "../Interfaces/IAnyswapToken.sol"; import { LibDiamond } from "../Libraries/LibDiamond.sol"; contract AnyswapFacet is ILiFi { /* ========== Storage ========== */ bytes32 internal constant NAMESPACE = keccak256("com.lifi.facets.anyswap"); struct Storage { address anyswapRouter; } /* ========== Types ========== */ struct AnyswapData { address token; uint256 amount; address recipient; uint256 toChainId; } /* ========== Init ========== */ function initAnyswap(address _anyswapRouter) external { Storage storage s = getStorage(); LibDiamond.enforceIsContractOwner(); s.anyswapRouter = _anyswapRouter; } /* ========== Public Bridge Functions ========== */ /** * @notice Bridges tokens via Anyswap * @param _lifiData data used purely for tracking and analytics * @param _anyswapData data specific to Anyswap */ function startBridgeTokensViaAnyswap(LiFiData memory _lifiData, AnyswapData calldata _anyswapData) public payable { if (_anyswapData.token != address(0)) { uint256 _fromTokenBalance = LibAsset.getOwnBalance(_anyswapData.token); address underlyingToken = IAnyswapToken(_anyswapData.token).underlying(); LibAsset.transferFromERC20(underlyingToken, msg.sender, address(this), _anyswapData.amount); require( LibAsset.getOwnBalance(underlyingToken) - _fromTokenBalance == _anyswapData.amount, "ERR_INVALID_AMOUNT" ); } else { require(msg.value == _anyswapData.amount, "ERR_INVALID_AMOUNT"); } _startBridge(_anyswapData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } /** * @notice Performs a swap before bridging via Anyswap * @param _lifiData data used purely for tracking and analytics * @param _swapData an array of swap related data for performing swaps before bridging * @param _anyswapData data specific to Anyswap */ function swapAndStartBridgeTokensViaAnyswap( LiFiData memory _lifiData, LibSwap.SwapData[] calldata _swapData, AnyswapData calldata _anyswapData ) public payable { if (_anyswapData.token != address(0)) { address underlyingToken = IAnyswapToken(_anyswapData.token).underlying(); uint256 _fromTokenBalance = LibAsset.getOwnBalance(underlyingToken); // Swap for (uint8 i; i < _swapData.length; i++) { LibSwap.swap(_lifiData.transactionId, _swapData[i]); } require( LibAsset.getOwnBalance(underlyingToken) - _fromTokenBalance >= _anyswapData.amount, "ERR_INVALID_AMOUNT" ); } else { uint256 _fromBalance = address(this).balance; // Swap for (uint8 i; i < _swapData.length; i++) { LibSwap.swap(_lifiData.transactionId, _swapData[i]); } require(address(this).balance - _fromBalance >= _anyswapData.amount, "ERR_INVALID_AMOUNT"); } _startBridge(_anyswapData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } /* ========== External Config Functions ========== */ /** * @dev Changes address of Anyswap router * @param _newRouter address of the new router */ function changeAnyswapRouter(address _newRouter) external { Storage storage s = getStorage(); LibDiamond.enforceIsContractOwner(); s.anyswapRouter = _newRouter; } /* ========== Internal Functions ========== */ /** * @dev Conatains the business logic for the bridge via Anyswap * @param _anyswapData data specific to Anyswap */ function _startBridge(AnyswapData calldata _anyswapData) internal { Storage storage s = getStorage(); // Check chain id require(block.chainid != _anyswapData.toChainId, "Cannot bridge to the same network."); if (_anyswapData.token != address(0)) { // Give Anyswap approval to bridge tokens LibAsset.approveERC20( IERC20(IAnyswapToken(_anyswapData.token).underlying()), s.anyswapRouter, _anyswapData.amount ); IAnyswapRouter(s.anyswapRouter).anySwapOutUnderlying( _anyswapData.token, _anyswapData.recipient, _anyswapData.amount, _anyswapData.toChainId ); } else { IAnyswapRouter(s.anyswapRouter).anySwapOutNative{ value: _anyswapData.amount }( _anyswapData.token, _anyswapData.recipient, _anyswapData.toChainId ); } } function getStorage() internal pure returns (Storage storage s) { bytes32 namespace = NAMESPACE; // solhint-disable-next-line no-inline-assembly assembly { s.slot := namespace } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; interface ILiFi { /* ========== Structs ========== */ struct LiFiData { bytes32 transactionId; string integrator; address referrer; address sendingAssetId; address receivingAssetId; address receiver; uint256 destinationChainId; uint256 amount; } /* ========== Events ========== */ event LiFiTransferStarted( bytes32 indexed transactionId, string integrator, address referrer, address sendingAssetId, address receivingAssetId, address receiver, uint256 amount, uint256 destinationChainId, uint256 timestamp ); event LiFiTransferCompleted( bytes32 indexed transactionId, address receivingAssetId, address receiver, uint256 amount, uint256 timestamp ); event LiFiTransferConfirmed( bytes32 indexed transactionId, string integrator, address referrer, address sendingAssetId, address receivingAssetId, address receiver, uint256 amount, uint256 destinationChainId, uint256 timestamp ); event LiFiTransferRefunded( bytes32 indexed transactionId, string integrator, address referrer, address sendingAssetId, address receivingAssetId, address receiver, uint256 amount, uint256 destinationChainId, uint256 timestamp ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; interface IAnyswapRouter { function anySwapOutUnderlying( address token, address to, uint256 amount, uint256 toChainID ) external; function anySwapOutNative( address token, address to, uint256 toChainID ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import { IDiamondCut } from "../Interfaces/IDiamondCut.sol"; library LibDiamond { bytes32 internal constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage"); struct FacetAddressAndPosition { address facetAddress; uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array } struct FacetFunctionSelectors { bytes4[] functionSelectors; uint256 facetAddressPosition; // position of facetAddress in facetAddresses array } struct DiamondStorage { // maps function selector to the facet address and // the position of the selector in the facetFunctionSelectors.selectors array mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition; // maps facet addresses to function selectors mapping(address => FacetFunctionSelectors) facetFunctionSelectors; // facet addresses address[] facetAddresses; // Used to query if a contract implements an interface. // Used to implement ERC-165. mapping(bytes4 => bool) supportedInterfaces; // owner of the contract address contractOwner; } function diamondStorage() internal pure returns (DiamondStorage storage ds) { bytes32 position = DIAMOND_STORAGE_POSITION; // solhint-disable-next-line no-inline-assembly assembly { ds.slot := position } } event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function setContractOwner(address _newOwner) internal { DiamondStorage storage ds = diamondStorage(); address previousOwner = ds.contractOwner; ds.contractOwner = _newOwner; emit OwnershipTransferred(previousOwner, _newOwner); } function contractOwner() internal view returns (address contractOwner_) { contractOwner_ = diamondStorage().contractOwner; } function enforceIsContractOwner() internal view { require(msg.sender == diamondStorage().contractOwner, "LibDiamond: Must be contract owner"); } event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata); // Internal function version of diamondCut function diamondCut( IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata ) internal { for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) { IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action; if (action == IDiamondCut.FacetCutAction.Add) { addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else if (action == IDiamondCut.FacetCutAction.Replace) { replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else if (action == IDiamondCut.FacetCutAction.Remove) { removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else { revert("LibDiamondCut: Incorrect FacetCutAction"); } } emit DiamondCut(_diamondCut, _init, _calldata); initializeDiamondCut(_init, _calldata); } function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); DiamondStorage storage ds = diamondStorage(); require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)"); uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length); // add new facet address if it does not exist if (selectorPosition == 0) { addFacet(ds, _facetAddress); } for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists"); addFunction(ds, selector, selectorPosition, _facetAddress); selectorPosition++; } } function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); DiamondStorage storage ds = diamondStorage(); require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)"); uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length); // add new facet address if it does not exist if (selectorPosition == 0) { addFacet(ds, _facetAddress); } for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function"); removeFunction(ds, oldFacetAddress, selector); addFunction(ds, selector, selectorPosition, _facetAddress); selectorPosition++; } } function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); DiamondStorage storage ds = diamondStorage(); // if function does not exist then do nothing and return require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)"); for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; removeFunction(ds, oldFacetAddress, selector); } } function addFacet(DiamondStorage storage ds, address _facetAddress) internal { enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code"); ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length; ds.facetAddresses.push(_facetAddress); } function addFunction( DiamondStorage storage ds, bytes4 _selector, uint96 _selectorPosition, address _facetAddress ) internal { ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition; ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector); ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress; } function removeFunction( DiamondStorage storage ds, address _facetAddress, bytes4 _selector ) internal { require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist"); // an immutable function is a function defined directly in a diamond require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function"); // replace selector with last selector, then delete last selector uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition; uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1; // if not the same then replace _selector with lastSelector if (selectorPosition != lastSelectorPosition) { bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition]; ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector; ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition); } // delete the last selector ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop(); delete ds.selectorToFacetAndPosition[_selector]; // if no more selectors for facet address then delete the facet address if (lastSelectorPosition == 0) { // replace facet address with last facet address and delete last facet address uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1; uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition; if (facetAddressPosition != lastFacetAddressPosition) { address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition]; ds.facetAddresses[facetAddressPosition] = lastFacetAddress; ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition; } ds.facetAddresses.pop(); delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition; } } function initializeDiamondCut(address _init, bytes memory _calldata) internal { if (_init == address(0)) { require(_calldata.length == 0, "LibDiamondCut: _init is address(0) but_calldata is not empty"); } else { require(_calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)"); if (_init != address(this)) { enforceHasContractCode(_init, "LibDiamondCut: _init address has no code"); } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory error) = _init.delegatecall(_calldata); if (!success) { if (error.length > 0) { // bubble up the error revert(string(error)); } else { revert("LibDiamondCut: _init function reverted"); } } } } function enforceHasContractCode(address _contract, string memory _errorMessage) internal view { uint256 contractSize; // solhint-disable-next-line no-inline-assembly assembly { contractSize := extcodesize(_contract) } require(contractSize > 0, _errorMessage); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.7; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @title LibAsset * @author Connext <[email protected]> * @notice This library contains helpers for dealing with onchain transfers * of assets, including accounting for the native asset `assetId` * conventions and any noncompliant ERC20 transfers */ library LibAsset { /** * @dev All native assets use the empty address for their asset id * by convention */ address internal constant NATIVE_ASSETID = address(0); /** * @notice Determines whether the given assetId is the native asset * @param assetId The asset identifier to evaluate * @return Boolean indicating if the asset is the native asset */ function isNativeAsset(address assetId) internal pure returns (bool) { return assetId == NATIVE_ASSETID; } /** * @notice Gets the balance of the inheriting contract for the given asset * @param assetId The asset identifier to get the balance of * @return Balance held by contracts using this library */ function getOwnBalance(address assetId) internal view returns (uint256) { return isNativeAsset(assetId) ? address(this).balance : IERC20(assetId).balanceOf(address(this)); } /** * @notice Transfers ether from the inheriting contract to a given * recipient * @param recipient Address to send ether to * @param amount Amount to send to given recipient */ function transferNativeAsset(address payable recipient, uint256 amount) internal { // solhint-disable-next-line avoid-low-level-calls (bool success, ) = recipient.call{ value: amount }(""); require(success, "#TNA:028"); } /** * @notice Gives approval for another address to spend tokens * @param assetId Token address to transfer * @param spender Address to give spend approval to * @param amount Amount to approve for spending */ function approveERC20( IERC20 assetId, address spender, uint256 amount ) internal { if (isNativeAsset(address(assetId))) return; uint256 allowance = assetId.allowance(address(this), spender); if (allowance > 0) SafeERC20.safeApprove(IERC20(assetId), spender, 0); SafeERC20.safeIncreaseAllowance(IERC20(assetId), spender, amount); } /** * @notice Transfers tokens from the inheriting contract to a given * recipient * @param assetId Token address to transfer * @param recipient Address to send ether to * @param amount Amount to send to given recipient */ function transferERC20( address assetId, address recipient, uint256 amount ) internal { SafeERC20.safeTransfer(IERC20(assetId), recipient, amount); } /** * @notice Transfers tokens from a sender to a given recipient * @param assetId Token address to transfer * @param from Address of sender/owner * @param to Address of recipient/spender * @param amount Amount to transfer from owner to spender */ function transferFromERC20( address assetId, address from, address to, uint256 amount ) internal { SafeERC20.safeTransferFrom(IERC20(assetId), from, to, amount); } /** * @notice Increases the allowance of a token to a spender * @param assetId Token address of asset to increase allowance of * @param spender Account whos allowance is increased * @param amount Amount to increase allowance by */ function increaseERC20Allowance( address assetId, address spender, uint256 amount ) internal { require(!isNativeAsset(assetId), "#IA:034"); SafeERC20.safeIncreaseAllowance(IERC20(assetId), spender, amount); } /** * @notice Decreases the allowance of a token to a spender * @param assetId Token address of asset to decrease allowance of * @param spender Account whos allowance is decreased * @param amount Amount to decrease allowance by */ function decreaseERC20Allowance( address assetId, address spender, uint256 amount ) internal { require(!isNativeAsset(assetId), "#DA:034"); SafeERC20.safeDecreaseAllowance(IERC20(assetId), spender, amount); } /** * @notice Wrapper function to transfer a given asset (native or erc20) to * some recipient. Should handle all non-compliant return value * tokens as well by using the SafeERC20 contract by open zeppelin. * @param assetId Asset id for transfer (address(0) for native asset, * token address for erc20s) * @param recipient Address to send asset to * @param amount Amount to send to given recipient */ function transferAsset( address assetId, address payable recipient, uint256 amount ) internal { isNativeAsset(assetId) ? transferNativeAsset(recipient, amount) : transferERC20(assetId, recipient, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { LibAsset } from "./LibAsset.sol"; import { LibUtil } from "./LibUtil.sol"; library LibSwap { struct SwapData { address callTo; address approveTo; address sendingAssetId; address receivingAssetId; uint256 fromAmount; bytes callData; } event AssetSwapped( bytes32 transactionId, address dex, address fromAssetId, address toAssetId, uint256 fromAmount, uint256 toAmount, uint256 timestamp ); function swap(bytes32 transactionId, SwapData calldata _swapData) internal { uint256 fromAmount = _swapData.fromAmount; uint256 toAmount = LibAsset.getOwnBalance(_swapData.receivingAssetId); address fromAssetId = _swapData.sendingAssetId; if (!LibAsset.isNativeAsset(fromAssetId) && LibAsset.getOwnBalance(fromAssetId) < fromAmount) { LibAsset.transferFromERC20(_swapData.sendingAssetId, msg.sender, address(this), fromAmount); } if (!LibAsset.isNativeAsset(fromAssetId)) { LibAsset.approveERC20(IERC20(fromAssetId), _swapData.approveTo, fromAmount); } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory res) = _swapData.callTo.call{ value: msg.value }(_swapData.callData); if (!success) { string memory reason = LibUtil.getRevertMsg(res); revert(reason); } toAmount = LibAsset.getOwnBalance(_swapData.receivingAssetId) - toAmount; emit AssetSwapped( transactionId, _swapData.callTo, _swapData.sendingAssetId, _swapData.receivingAssetId, fromAmount, toAmount, block.timestamp ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; interface IAnyswapToken { function underlying() external returns (address); }
// SPDX-License-Identifier: MIT 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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, 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 pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; interface IDiamondCut { enum FacetCutAction { Add, Replace, Remove } // Add=0, Replace=1, Remove=2 struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut( FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata ) external; event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); }
// SPDX-License-Identifier: MIT 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 pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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 pragma solidity ^0.8.7; import "./LibBytes.sol"; library LibUtil { using LibBytes for bytes; function getRevertMsg(bytes memory _res) internal pure returns (string memory) { // If the _res length is less than 68, then the transaction failed silently (without a revert message) if (_res.length < 68) return "Transaction reverted silently"; bytes memory revertData = _res.slice(4, _res.length - 4); // Remove the selector which is the first 4 bytes return abi.decode(revertData, (string)); // All that remains is the revert string } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; library LibBytes { // solhint-disable no-inline-assembly function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore( 0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. ) ) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1, "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) // solhint-disable-next-line no-empty-blocks for { } eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ITransactionManager } from "../Interfaces/ITransactionManager.sol"; import { ILiFi } from "../Interfaces/ILiFi.sol"; import { LibAsset } from "../Libraries/LibAsset.sol"; import { LibSwap } from "../Libraries/LibSwap.sol"; import { LibDiamond } from "../Libraries/LibDiamond.sol"; contract NXTPFacet is ILiFi { /* ========== Storage ========== */ bytes32 internal constant NAMESPACE = keccak256("com.lifi.facets.nxtp"); struct Storage { ITransactionManager nxtpTxManager; } /* ========== Events ========== */ event NXTPBridgeStarted( bytes32 indexed lifiTransactionId, bytes32 nxtpTransactionId, ITransactionManager.TransactionData txData ); /* ========== Init ========== */ function initNXTP(ITransactionManager _txMgrAddr) external { Storage storage s = getStorage(); LibDiamond.enforceIsContractOwner(); s.nxtpTxManager = _txMgrAddr; } /* ========== Public Bridge Functions ========== */ /** * @notice This function starts a cross-chain transaction using the NXTP protocol * @param _lifiData data used purely for tracking and analytics * @param _nxtpData data needed to complete an NXTP cross-chain transaction */ function startBridgeTokensViaNXTP(LiFiData memory _lifiData, ITransactionManager.PrepareArgs memory _nxtpData) public payable { // Ensure sender has enough to complete the bridge transaction address sendingAssetId = _nxtpData.invariantData.sendingAssetId; if (sendingAssetId == address(0)) require(msg.value == _nxtpData.amount, "ERR_INVALID_AMOUNT"); else { uint256 _sendingAssetIdBalance = LibAsset.getOwnBalance(sendingAssetId); LibAsset.transferFromERC20(sendingAssetId, msg.sender, address(this), _nxtpData.amount); require( LibAsset.getOwnBalance(sendingAssetId) - _sendingAssetIdBalance == _nxtpData.amount, "ERR_INVALID_AMOUNT" ); } // Start the bridge process _startBridge(_lifiData.transactionId, _nxtpData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } /** * @notice This function performs a swap or multiple swaps and then starts a cross-chain transaction * using the NXTP protocol. * @param _lifiData data used purely for tracking and analytics * @param _swapData array of data needed for swaps * @param _nxtpData data needed to complete an NXTP cross-chain transaction */ function swapAndStartBridgeTokensViaNXTP( LiFiData memory _lifiData, LibSwap.SwapData[] calldata _swapData, ITransactionManager.PrepareArgs memory _nxtpData ) public payable { address sendingAssetId = _nxtpData.invariantData.sendingAssetId; uint256 _sendingAssetIdBalance = LibAsset.getOwnBalance(sendingAssetId); // Swap for (uint8 i; i < _swapData.length; i++) { LibSwap.swap(_lifiData.transactionId, _swapData[i]); } uint256 _postSwapBalance = LibAsset.getOwnBalance(sendingAssetId) - _sendingAssetIdBalance; require(_postSwapBalance > 0, "ERR_INVALID_AMOUNT"); _nxtpData.amount = _postSwapBalance; _startBridge(_lifiData.transactionId, _nxtpData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } /** * @notice Completes a cross-chain transaction on the receiving chain using the NXTP protocol. * @param _lifiData data used purely for tracking and analytics * @param assetId token received on the receiving chain * @param receiver address that will receive the tokens * @param amount number of tokens received */ function completeBridgeTokensViaNXTP( LiFiData memory _lifiData, address assetId, address receiver, uint256 amount ) public payable { if (LibAsset.isNativeAsset(assetId)) { require(msg.value == amount, "INVALID_ETH_AMOUNT"); } else { require(msg.value == 0, "ETH_WITH_ERC"); LibAsset.transferFromERC20(assetId, msg.sender, address(this), amount); } LibAsset.transferAsset(assetId, payable(receiver), amount); emit LiFiTransferCompleted(_lifiData.transactionId, assetId, receiver, amount, block.timestamp); } /** * @notice Performs a swap before completing a cross-chain transaction * on the receiving chain using the NXTP protocol. * @param _lifiData data used purely for tracking and analytics * @param _swapData array of data needed for swaps * @param finalAssetId token received on the receiving chain * @param receiver address that will receive the tokens */ function swapAndCompleteBridgeTokensViaNXTP( LiFiData memory _lifiData, LibSwap.SwapData[] calldata _swapData, address finalAssetId, address receiver ) public payable { uint256 startingBalance = LibAsset.getOwnBalance(finalAssetId); // Swap for (uint8 i; i < _swapData.length; i++) { LibSwap.swap(_lifiData.transactionId, _swapData[i]); } uint256 postSwapBalance = LibAsset.getOwnBalance(finalAssetId); uint256 finalBalance; if (postSwapBalance > startingBalance) { finalBalance = postSwapBalance - startingBalance; LibAsset.transferAsset(finalAssetId, payable(receiver), finalBalance); } emit LiFiTransferCompleted(_lifiData.transactionId, finalAssetId, receiver, finalBalance, block.timestamp); } /* ========== Internal Functions ========== */ function _startBridge(bytes32 _transactionId, ITransactionManager.PrepareArgs memory _nxtpData) internal { Storage storage s = getStorage(); IERC20 sendingAssetId = IERC20(_nxtpData.invariantData.sendingAssetId); // Give Connext approval to bridge tokens LibAsset.approveERC20(IERC20(sendingAssetId), address(s.nxtpTxManager), _nxtpData.amount); uint256 value = LibAsset.isNativeAsset(address(sendingAssetId)) ? msg.value : 0; // Initiate bridge transaction on sending chain ITransactionManager.TransactionData memory result = s.nxtpTxManager.prepare{ value: value }(_nxtpData); emit NXTPBridgeStarted(_transactionId, result.transactionId, result); } function getStorage() internal pure returns (Storage storage s) { bytes32 namespace = NAMESPACE; // solhint-disable-next-line no-inline-assembly assembly { s.slot := namespace } } /* ========== Getter Functions ========== */ /** * @notice show the NXTP transaction manager contract address */ function getNXTPTransactionManager() external view returns (address) { Storage storage s = getStorage(); return address(s.nxtpTxManager); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.7; interface ITransactionManager { // Structs // Holds all data that is constant between sending and // receiving chains. The hash of this is what gets signed // to ensure the signature can be used on both chains. struct InvariantTransactionData { address receivingChainTxManagerAddress; address user; address router; address initiator; // msg.sender of sending side address sendingAssetId; address receivingAssetId; address sendingChainFallback; // funds sent here on cancel address receivingAddress; address callTo; uint256 sendingChainId; uint256 receivingChainId; bytes32 callDataHash; // hashed to prevent free option bytes32 transactionId; } // Holds all data that varies between sending and receiving // chains. The hash of this is stored onchain to ensure the // information passed in is valid. struct VariantTransactionData { uint256 amount; uint256 expiry; uint256 preparedBlockNumber; } // All Transaction data, constant and variable struct TransactionData { address receivingChainTxManagerAddress; address user; address router; address initiator; // msg.sender of sending side address sendingAssetId; address receivingAssetId; address sendingChainFallback; address receivingAddress; address callTo; bytes32 callDataHash; bytes32 transactionId; uint256 sendingChainId; uint256 receivingChainId; uint256 amount; uint256 expiry; uint256 preparedBlockNumber; // Needed for removal of active blocks on fulfill/cancel } // The structure of the signed data for fulfill struct SignedFulfillData { bytes32 transactionId; uint256 relayerFee; string functionIdentifier; // "fulfill" or "cancel" uint256 receivingChainId; // For domain separation address receivingChainTxManagerAddress; // For domain separation } // The structure of the signed data for cancellation struct SignedCancelData { bytes32 transactionId; string functionIdentifier; uint256 receivingChainId; address receivingChainTxManagerAddress; // For domain separation } /** * Arguments for calling prepare() * @param invariantData The data for a crosschain transaction that will * not change between sending and receiving chains. * The hash of this data is used as the key to store * the inforamtion that does change between chains * (amount,expiry,preparedBlock) for verification * @param amount The amount of the transaction on this chain * @param expiry The block.timestamp when the transaction will no longer be * fulfillable and is freely cancellable on this chain * @param encryptedCallData The calldata to be executed when the tx is * fulfilled. Used in the function to allow the user * to reconstruct the tx from events. Hash is stored * onchain to prevent shenanigans. * @param encodedBid The encoded bid that was accepted by the user for this * crosschain transfer. It is supplied as a param to the * function but is only used in event emission * @param bidSignature The signature of the bidder on the encoded bid for * this transaction. Only used within the function for * event emission. The validity of the bid and * bidSignature are enforced offchain * @param encodedMeta The meta for the function */ struct PrepareArgs { InvariantTransactionData invariantData; uint256 amount; uint256 expiry; bytes encryptedCallData; bytes encodedBid; bytes bidSignature; bytes encodedMeta; } /** * @param txData All of the data (invariant and variant) for a crosschain * transaction. The variant data provided is checked against * what was stored when the `prepare` function was called. * @param relayerFee The fee that should go to the relayer when they are * calling the function on the receiving chain for the user * @param signature The users signature on the transaction id + fee that * can be used by the router to unlock the transaction on * the sending chain * @param callData The calldata to be sent to and executed by the * `FulfillHelper` * @param encodedMeta The meta for the function */ struct FulfillArgs { TransactionData txData; uint256 relayerFee; bytes signature; bytes callData; bytes encodedMeta; } /** * Arguments for calling cancel() * @param txData All of the data (invariant and variant) for a crosschain * transaction. The variant data provided is checked against * what was stored when the `prepare` function was called. * @param signature The user's signature that allows a transaction to be * cancelled by a relayer * @param encodedMeta The meta for the function */ struct CancelArgs { TransactionData txData; bytes signature; bytes encodedMeta; } // Adding/removing asset events event RouterAdded(address indexed addedRouter, address indexed caller); event RouterRemoved(address indexed removedRouter, address indexed caller); // Adding/removing router events event AssetAdded(address indexed addedAssetId, address indexed caller); event AssetRemoved(address indexed removedAssetId, address indexed caller); // Liquidity events event LiquidityAdded(address indexed router, address indexed assetId, uint256 amount, address caller); event LiquidityRemoved(address indexed router, address indexed assetId, uint256 amount, address recipient); // Transaction events event TransactionPrepared( address indexed user, address indexed router, bytes32 indexed transactionId, TransactionData txData, address caller, PrepareArgs args ); event TransactionFulfilled( address indexed user, address indexed router, bytes32 indexed transactionId, FulfillArgs args, bool success, bool isContract, bytes returnData, address caller ); event TransactionCancelled( address indexed user, address indexed router, bytes32 indexed transactionId, CancelArgs args, address caller ); // Getters function getChainId() external view returns (uint256); function getStoredChainId() external view returns (uint256); // Owner only methods function addRouter(address router) external; function removeRouter(address router) external; function addAssetId(address assetId) external; function removeAssetId(address assetId) external; // Router only methods function addLiquidityFor( uint256 amount, address assetId, address router ) external payable; function addLiquidity(uint256 amount, address assetId) external payable; function removeLiquidity( uint256 amount, address assetId, address payable recipient ) external; // Methods for crosschain transfers // called in the following order (in happy case) // 1. prepare by user on sending chain // 2. prepare by router on receiving chain // 3. fulfill by user on receiving chain // 4. fulfill by router on sending chain function prepare(PrepareArgs calldata args) external payable returns (TransactionData memory); function fulfill(FulfillArgs calldata args) external returns (TransactionData memory); function cancel(CancelArgs calldata args) external returns (TransactionData memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import { IDiamondCut } from "../Interfaces/IDiamondCut.sol"; import { LibDiamond } from "../Libraries/LibDiamond.sol"; contract DiamondCutFacet is IDiamondCut { /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut( FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata ) external override { LibDiamond.enforceIsContractOwner(); LibDiamond.diamondCut(_diamondCut, _init, _calldata); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { LibDiamond } from "../Libraries/LibDiamond.sol"; contract WithdrawFacet { using SafeERC20 for IERC20; address private constant NATIVE_ASSET = address(0); event LogWithdraw(address indexed _assetAddress, address _from, uint256 amount); /** * @dev Withdraw asset. * @param _assetAddress Asset to be withdrawn. * @param _to address to withdraw to. * @param _amount amount of asset to withdraw. */ function withdraw( address _assetAddress, address _to, uint256 _amount ) public { LibDiamond.enforceIsContractOwner(); address sendTo = (_to == address(0)) ? msg.sender : _to; uint256 assetBalance; if (_assetAddress == NATIVE_ASSET) { address self = address(this); // workaround for a possible solidity bug assert(_amount <= self.balance); payable(sendTo).transfer(_amount); } else { assetBalance = IERC20(_assetAddress).balanceOf(address(this)); assert(_amount <= assetBalance); IERC20(_assetAddress).safeTransfer(sendTo, _amount); } emit LogWithdraw(sendTo, _assetAddress, _amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ILiFi } from "../Interfaces/ILiFi.sol"; import { IHopBridge } from "../Interfaces/IHopBridge.sol"; import { LibAsset } from "../Libraries/LibAsset.sol"; import { LibSwap } from "../Libraries/LibSwap.sol"; import { LibDiamond } from "../Libraries/LibDiamond.sol"; contract HopFacet is ILiFi { /* ========== Storage ========== */ bytes32 internal constant NAMESPACE = keccak256("com.lifi.facets.hop"); struct Storage { mapping(string => IHopBridge.BridgeConfig) hopBridges; uint256 hopChainId; } /* ========== Types ========== */ struct HopData { string asset; address recipient; uint256 chainId; uint256 amount; uint256 bonderFee; uint256 amountOutMin; uint256 deadline; uint256 destinationAmountOutMin; uint256 destinationDeadline; } /* ========== Init ========== */ function initHop( string[] memory _tokens, IHopBridge.BridgeConfig[] memory _bridgeConfigs, uint256 _chainId ) external { Storage storage s = getStorage(); LibDiamond.enforceIsContractOwner(); for (uint8 i; i < _tokens.length; i++) { s.hopBridges[_tokens[i]] = _bridgeConfigs[i]; } s.hopChainId = _chainId; } /* ========== Public Bridge Functions ========== */ /** * @notice Bridges tokens via Hop Protocol * @param _lifiData data used purely for tracking and analytics * @param _hopData data specific to Hop Protocol */ function startBridgeTokensViaHop(LiFiData memory _lifiData, HopData calldata _hopData) public payable { address fromToken = _bridge(_hopData.asset).token; uint256 _fromTokenBalance = LibAsset.getOwnBalance(fromToken); LibAsset.transferFromERC20(fromToken, msg.sender, address(this), _hopData.amount); require(LibAsset.getOwnBalance(fromToken) - _fromTokenBalance == _hopData.amount, "ERR_INVALID_AMOUNT"); _startBridge(_hopData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } /** * @notice Performs a swap before bridging via Hop Protocol * @param _lifiData data used purely for tracking and analytics * @param _swapData an array of swap related data for performing swaps before bridging * @param _hopData data specific to Hop Protocol */ function swapAndStartBridgeTokensViaHop( LiFiData memory _lifiData, LibSwap.SwapData[] calldata _swapData, HopData calldata _hopData ) public payable { address fromToken = _bridge(_hopData.asset).token; uint256 _fromTokenBalance = LibAsset.getOwnBalance(fromToken); // Swap for (uint8 i; i < _swapData.length; i++) { LibSwap.swap(_lifiData.transactionId, _swapData[i]); } require(LibAsset.getOwnBalance(fromToken) - _fromTokenBalance >= _hopData.amount, "ERR_INVALID_AMOUNT"); _startBridge(_hopData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } /* ========== Internal Functions ========== */ /** * @dev Conatains the business logic for the bridge via Hop Protocol * @param _hopData data specific to Hop Protocol */ function _startBridge(HopData calldata _hopData) internal { Storage storage s = getStorage(); address fromToken = _bridge(_hopData.asset).token; address bridge; if (s.hopChainId == 1) { bridge = _bridge(_hopData.asset).bridge; } else { bridge = _bridge(_hopData.asset).ammWrapper; } // Do HOP stuff require(s.hopChainId != _hopData.chainId, "Cannot bridge to the same network."); // Give Hop approval to bridge tokens LibAsset.approveERC20(IERC20(fromToken), bridge, _hopData.amount); if (s.hopChainId == 1) { // Ethereum L1 IHopBridge(bridge).sendToL2( _hopData.chainId, _hopData.recipient, _hopData.amount, _hopData.destinationAmountOutMin, _hopData.destinationDeadline, address(0), 0 ); } else { // L2 // solhint-disable-next-line check-send-result IHopBridge(bridge).swapAndSend( _hopData.chainId, _hopData.recipient, _hopData.amount, _hopData.bonderFee, _hopData.amountOutMin, _hopData.deadline, _hopData.destinationAmountOutMin, _hopData.destinationDeadline ); } } function _bridge(string memory _asset) internal view returns (IHopBridge.BridgeConfig memory) { Storage storage s = getStorage(); return s.hopBridges[_asset]; } function getStorage() internal pure returns (Storage storage s) { bytes32 namespace = NAMESPACE; // solhint-disable-next-line no-inline-assembly assembly { s.slot := namespace } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; interface IHopBridge { struct BridgeConfig { address token; address bridge; address ammWrapper; } function sendToL2( uint256 chainId, address recipient, uint256 amount, uint256 amountOutMin, uint256 deadline, address relayer, uint256 relayerFee ) external payable; function swapAndSend( uint256 chainId, address recipient, uint256 amount, uint256 bonderFee, uint256 amountOutMin, uint256 deadline, uint256 destinationAmountOutMin, uint256 destinationDeadline ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ILiFi } from "../Interfaces/ILiFi.sol"; import { LibAsset } from "../Libraries/LibAsset.sol"; import { LibSwap } from "../Libraries/LibSwap.sol"; import { LibUtil } from "../Libraries/LibUtil.sol"; contract GenericBridgeFacet is ILiFi { /* ========== Types ========== */ struct BridgeData { uint256 amount; address assetId; address callTo; bytes callData; } /* ========== Public Bridge Functions ========== */ /** * @notice Bridges tokens via Generic Bridge * @param _lifiData data used purely for tracking and analytics * @param _bridgeData data used for bridging via various contracts */ function startBridgeTokensGeneric(LiFiData memory _lifiData, BridgeData memory _bridgeData) public payable { LibAsset.transferFromERC20(_bridgeData.assetId, msg.sender, address(this), _bridgeData.amount); _startBridge(_bridgeData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } /** * @notice Performs a swap before bridging via Hop Protocol * @param _lifiData data used purely for tracking and analytics * @param _swapData an array of swap related data for performing swaps before bridging * @param _bridgeData data used for bridging via various contracts */ function swapAndStartBridgeTokensGeneric( LiFiData memory _lifiData, LibSwap.SwapData[] calldata _swapData, BridgeData memory _bridgeData ) public payable { uint256 _fromTokenBalance = LibAsset.getOwnBalance(_bridgeData.assetId); // Swap for (uint8 i; i < _swapData.length; i++) { LibSwap.swap(_lifiData.transactionId, _swapData[i]); } require( LibAsset.getOwnBalance(_bridgeData.assetId) - _fromTokenBalance >= _bridgeData.amount, "ERR_INVALID_AMOUNT" ); _startBridge(_bridgeData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } /* ========== Internal Functions ========== */ /** * @dev Conatains the business logic for the bridge via Hop Protocol */ function _startBridge(BridgeData memory _bridgeData) internal { LibAsset.approveERC20(IERC20(_bridgeData.assetId), _bridgeData.callTo, _bridgeData.amount); (bool success, bytes memory res) = _bridgeData.callTo.call{ value: msg.value }(_bridgeData.callData); if (!success) { string memory reason = LibUtil.getRevertMsg(res); revert(reason); } } }
// SPDX-License-Identifier: MIT // for testing only not for production // solhint-disable pragma solidity ^0.8.3; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract USDT is ERC20 { constructor( address receiver, string memory name, string memory symbol ) ERC20(name, symbol) { // Mint 100 tokens to msg.sender // Similar to how // 1 dollar = 100 cents // 1 token = 1 * (10 ** decimals) _mint(receiver, 10000 * 10**uint256(6)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { LibAsset } from "../Libraries/LibAsset.sol"; import { ILiFi } from "../Interfaces/ILiFi.sol"; import { LibSwap } from "../Libraries/LibSwap.sol"; import { ICBridge } from "../Interfaces/ICBridge.sol"; import { LibDiamond } from "../Libraries/LibDiamond.sol"; contract CBridgeFacet is ILiFi { /* ========== Storage ========== */ bytes32 internal constant NAMESPACE = keccak256("com.lifi.facets.cbridge"); struct Storage { address cBridge; uint256 cBridgeChainId; } /* ========== Types ========== */ struct CBridgeData { address bridge; address token; uint256 amount; bytes32 hashlock; uint64 timelock; uint64 dstChainId; address dstAddress; } /* ========== Init ========== */ function initCbridge(address _cBridge, uint256 _chainId) external { Storage storage s = getStorage(); LibDiamond.enforceIsContractOwner(); s.cBridge = _cBridge; s.cBridgeChainId = _chainId; } /* ========== Public Bridge Functions ========== */ function startBridgeTokensViaCBridge(LiFiData memory _lifiData, CBridgeData calldata _cBridgeData) public payable { uint256 _fromTokenBalance = LibAsset.getOwnBalance(_cBridgeData.token); LibAsset.transferFromERC20(_cBridgeData.token, msg.sender, address(this), _cBridgeData.amount); require( LibAsset.getOwnBalance(_cBridgeData.token) - _fromTokenBalance == _cBridgeData.amount, "ERR_INVALID_AMOUNT" ); _startBridge(_cBridgeData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } function swapAndStartBridgeTokensViaCBridge( LiFiData memory _lifiData, LibSwap.SwapData[] calldata _swapData, CBridgeData calldata _cBridgeData ) public payable { uint256 _fromTokenBalance = LibAsset.getOwnBalance(_cBridgeData.token); LibAsset.transferFromERC20(_cBridgeData.token, msg.sender, address(this), _cBridgeData.amount); // Swap for (uint8 i; i < _swapData.length; i++) { LibSwap.swap(_lifiData.transactionId, _swapData[i]); } require( LibAsset.getOwnBalance(_cBridgeData.token) - _fromTokenBalance == _cBridgeData.amount, "ERR_INVALID_AMOUNT" ); _startBridge(_cBridgeData); emit LiFiTransferStarted( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } /* ========== Internal Functions ========== */ /* * @dev Conatains the business logic for the bridge via CBridge * @param _cBridgeData data specific to CBridge */ function _startBridge(CBridgeData calldata _cBridgeData) internal { Storage storage s = getStorage(); address bridge = _bridge(); // Do CBridge stuff require(s.cBridgeChainId != _cBridgeData.dstChainId, "Cannot bridge to the same network."); // Give CBridge approval to bridge tokens LibAsset.approveERC20(IERC20(_cBridgeData.token), bridge, _cBridgeData.amount); ICBridge(bridge).transferOut( _cBridgeData.bridge, _cBridgeData.token, _cBridgeData.amount, _cBridgeData.hashlock, _cBridgeData.timelock, _cBridgeData.dstChainId, _cBridgeData.dstAddress ); } function confirmTransaction( LiFiData memory _lifiData, bytes32 _transferId, bytes32 _preimage ) public { address bridge = _bridge(); ICBridge(bridge).confirm(_transferId, _preimage); emit LiFiTransferConfirmed( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } function refund(LiFiData memory _lifiData, bytes32 _transferId) public { address bridge = _bridge(); ICBridge(bridge).refund(_transferId); emit LiFiTransferRefunded( _lifiData.transactionId, _lifiData.integrator, _lifiData.referrer, _lifiData.sendingAssetId, _lifiData.receivingAssetId, _lifiData.receiver, _lifiData.amount, _lifiData.destinationChainId, block.timestamp ); } function _bridge() internal view returns (address) { Storage storage s = getStorage(); return s.cBridge; } function getStorage() internal pure returns (Storage storage s) { bytes32 namespace = NAMESPACE; // solhint-disable-next-line no-inline-assembly assembly { s.slot := namespace } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; interface ICBridge { struct BridgeConfig { address bridge; } function transferOut( address _bridge, address _token, uint256 _amount, bytes32 _hashlock, uint64 _timelock, uint64 _dstChinId, address _dstAddress ) external; function transferIn( address _dstAddress, address _token, uint256 _amount, bytes32 _hashlock, uint64 _timelock, uint64 _srcChainId, bytes32 _srcTransferId ) external; function confirm(bytes32 _transferId, bytes32 _preimage) external; function refund(bytes32 _transferId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import { LibDiamond } from "../Libraries/LibDiamond.sol"; import { IERC173 } from "../Interfaces/IERC173.sol"; contract OwnershipFacet is IERC173 { function transferOwnership(address _newOwner) external override { LibDiamond.enforceIsContractOwner(); LibDiamond.setContractOwner(_newOwner); } function owner() external view override returns (address owner_) { owner_ = LibDiamond.contractOwner(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; /// @title ERC-173 Contract Ownership Standard /// Note: the ERC-165 identifier for this interface is 0x7f5828d0 /* is ERC165 */ interface IERC173 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return owner_ The address of the owner. function owner() external view returns (address owner_); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership(address _newOwner) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import { LibDiamond } from "../Libraries/LibDiamond.sol"; import { IDiamondLoupe } from "../Interfaces/IDiamondLoupe.sol"; import { IERC165 } from "../Interfaces/IERC165.sol"; contract DiamondLoupeFacet is IDiamondLoupe, IERC165 { // Diamond Loupe Functions //////////////////////////////////////////////////////////////////// /// These functions are expected to be called frequently by tools. // // struct Facet { // address facetAddress; // bytes4[] functionSelectors; // } /// @notice Gets all facets and their selectors. /// @return facets_ Facet function facets() external view override returns (Facet[] memory facets_) { LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); uint256 numFacets = ds.facetAddresses.length; facets_ = new Facet[](numFacets); for (uint256 i; i < numFacets; i++) { address facetAddress_ = ds.facetAddresses[i]; facets_[i].facetAddress = facetAddress_; facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors; } } /// @notice Gets all the function selectors provided by a facet. /// @param _facet The facet address. /// @return facetFunctionSelectors_ function facetFunctionSelectors(address _facet) external view override returns (bytes4[] memory facetFunctionSelectors_) { LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors; } /// @notice Get all the facet addresses used by a diamond. /// @return facetAddresses_ function facetAddresses() external view override returns (address[] memory facetAddresses_) { LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); facetAddresses_ = ds.facetAddresses; } /// @notice Gets the facet that supports the given selector. /// @dev If facet is not found return address(0). /// @param _functionSelector The function selector. /// @return facetAddress_ The facet address. function facetAddress(bytes4 _functionSelector) external view override returns (address facetAddress_) { LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress; } // This implements ERC-165. function supportsInterface(bytes4 _interfaceId) external view override returns (bool) { LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); return ds.supportedInterfaces[_interfaceId]; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; // A loupe is a small magnifying glass used to look at diamonds. // These functions look at diamonds interface IDiamondLoupe { /// These functions are expected to be called frequently /// by tools. struct Facet { address facetAddress; bytes4[] functionSelectors; } /// @notice Gets all facet addresses and their four byte function selectors. /// @return facets_ Facet function facets() external view returns (Facet[] memory facets_); /// @notice Gets all the function selectors supported by a specific facet. /// @param _facet The facet address. /// @return facetFunctionSelectors_ function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_); /// @notice Get all the facet addresses used by a diamond. /// @return facetAddresses_ function facetAddresses() external view returns (address[] memory facetAddresses_); /// @notice Gets the facet that supports the given selector. /// @dev If facet is not found return address(0). /// @param _functionSelector The function selector. /// @return facetAddress_ The facet address. function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceId The interface identifier, as specified in ERC-165 /// @dev Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
[{"inputs":[{"internalType":"address","name":"_contractOwner","type":"address"},{"internalType":"address","name":"_diamondCutFacet","type":"address"}],"stateMutability":"payable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040526040516200269938038062002699833981016040819052620000269162001168565b6200003c826200015660201b620000b61760201c565b604080516001808252818301909252600091816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081620000535750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b81600081518110620000c657620000c6620013e2565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b0385168152908101600081526020018281525082600081518110620001195762000119620013e2565b60200260200101819052506200014c82600060405180602001604052806000815250620001da60201b620001391760201c565b50505050620013f8565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b03848116918217909355604051600080516020620025ed833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60005b8351811015620003e9576000848281518110620001fe57620001fe620013e2565b602002602001015160200151905060006002811115620002225762000222620013b6565b816002811115620002375762000237620013b6565b1415620002965762000290858381518110620002575762000257620013e2565b602002602001015160000151868481518110620002785762000278620013e2565b6020026020010151604001516200043860201b60201c565b620003d3565b6001816002811115620002ad57620002ad620013b6565b1415620003065762000290858381518110620002cd57620002cd620013e2565b602002602001015160000151868481518110620002ee57620002ee620013e2565b602002602001015160400151620006c260201b60201c565b60028160028111156200031d576200031d620013b6565b14156200037657620002908583815181106200033d576200033d620013e2565b6020026020010151600001518684815181106200035e576200035e620013e2565b6020026020010151604001516200095860201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b5080620003e08162001358565b915050620001dd565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738383836040516200041f93929190620011ec565b60405180910390a162000433828262000abe565b505050565b60008151116200048e5760405162461bcd60e51b815260206004820152602b60248201526000805160206200267983398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620003ca565b600080516020620025ed8339815191526001600160a01b038316620004fa5760405162461bcd60e51b815260206004820152602c60248201526000805160206200263583398151915260448201526b65206164647265737328302960a01b6064820152608401620003ca565b6001600160a01b03831660009081526001820160205260409020546001600160601b038116620005305762000530828562000cdd565b60005b8351811015620006bb576000848281518110620005545762000554620013e2565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03168015620005fc5760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401620003ca565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b03191617905583620006a08162001376565b94505050508080620006b29062001358565b91505062000533565b5050505050565b6000815111620007185760405162461bcd60e51b815260206004820152602b60248201526000805160206200267983398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620003ca565b600080516020620025ed8339815191526001600160a01b038316620007845760405162461bcd60e51b815260206004820152602c60248201526000805160206200263583398151915260448201526b65206164647265737328302960a01b6064820152608401620003ca565b6001600160a01b03831660009081526001820160205260409020546001600160601b038116620007ba57620007ba828562000cdd565b60005b8351811015620006bb576000848281518110620007de57620007de620013e2565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b039081169087168114156200088c5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401620003ca565b6200089985828462000d4a565b6001600160e01b0319821660008181526020878152604080832080546001600160a01b03908116600160a01b6001600160601b038c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281546001600160a01b031916179055836200093d8162001376565b945050505080806200094f9062001358565b915050620007bd565b6000815111620009ae5760405162461bcd60e51b815260206004820152602b60248201526000805160206200267983398151915260448201526a1858d95d081d1bc818dd5d60aa1b6064820152608401620003ca565b600080516020620025ed8339815191526001600160a01b0383161562000a3d5760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401620003ca565b60005b825181101562000ab857600083828151811062000a615762000a61620013e2565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031662000aa084828462000d4a565b5050808062000aaf9062001358565b91505062000a40565b50505050565b6001600160a01b03821662000b485780511562000b445760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401620003ca565b5050565b600081511162000bc15760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401620003ca565b6001600160a01b038216301462000bf75762000bf7826040518060600160405280602881526020016200260d6028913962001127565b600080836001600160a01b03168360405162000c149190620011ce565b600060405180830381855af49150503d806000811462000c51576040519150601f19603f3d011682016040523d82523d6000602084013e62000c56565b606091505b50915091508162000ab85780511562000c85578060405162461bcd60e51b8152600401620003ca9190620012f3565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401620003ca565b62000d0281604051806060016040528060248152602001620026556024913962001127565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160a01b03821662000dc85760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401620003ca565b6001600160a01b03821630141562000e3a5760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401620003ca565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b0316929162000e8b916200130f565b905080821462000f84576001600160a01b0384166000908152600186016020526040812080548390811062000ec45762000ec4620013e2565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811062000f185762000f18620013e2565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b0384166000908152600186016020526040902080548062000fb05762000fb0620013cc565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b031985168252869052604081205580620006bb57600285015460009062001012906001906200130f565b6001600160a01b0386166000908152600180890160205260409091200154909150808214620010c8576000876002018381548110620010555762001055620013e2565b6000918252602090912001546002890180546001600160a01b039092169250829184908110620010895762001089620013e2565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480620010de57620010de620013cc565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b818162000ab85760405162461bcd60e51b8152600401620003ca9190620012f3565b80516001600160a01b03811681146200116357600080fd5b919050565b600080604083850312156200117c57600080fd5b62001187836200114b565b915062001197602084016200114b565b90509250929050565b60008151808452620011ba81602086016020860162001329565b601f01601f19169290920160200192915050565b60008251620011e281846020870162001329565b9190910192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b84811015620012c157898403607f19018652815180516001600160a01b031685528381015189860190600381106200125d57634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620012ab5783516001600160e01b03191682529286019260019290920191908601906200127f565b5097850197955050509082019060010162001215565b50506001600160a01b038a16908801528681036040880152620012e58189620011a0565b9a9950505050505050505050565b602081526000620013086020830184620011a0565b9392505050565b600082821015620013245762001324620013a0565b500390565b60005b83811015620013465781810151838201526020016200132c565b8381111562000ab85750506000910152565b60006000198214156200136f576200136f620013a0565b5060010190565b60006001600160601b0382811680821415620013965762001396620013a0565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6111e580620014086000396000f3fe60806040523661000b57005b600080356001600160e01b0319168152600080516020611144833981519152602081905260409091205481906001600160a01b0316806100925760405162461bcd60e51b815260206004820181905260248201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f7420657869737460448201526064015b60405180910390fd5b3660008037600080366000845af43d6000803e8080156100b1573d6000f35b3d6000fd5b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b03848116918217909355604051600080516020611144833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60005b83518110156103025760008482815181106101595761015961112d565b60200260200101516020015190506000600281111561017a5761017a611101565b81600281111561018c5761018c611101565b14156101db576101d68583815181106101a7576101a761112d565b6020026020010151600001518684815181106101c5576101c561112d565b60200260200101516040015161034d565b6102ef565b60018160028111156101ef576101ef611101565b1415610239576101d685838151811061020a5761020a61112d565b6020026020010151600001518684815181106102285761022861112d565b6020026020010151604001516104c9565b600281600281111561024d5761024d611101565b1415610297576101d68583815181106102685761026861112d565b6020026020010151600001518684815181106102865761028661112d565b602002602001015160400151610657565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401610089565b50806102fa816110a9565b91505061013c565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161033693929190610eb5565b60405180910390a16103488282610775565b505050565b600081511161036e5760405162461bcd60e51b815260040161008990610fcf565b6000805160206111448339815191526001600160a01b0383166103a35760405162461bcd60e51b81526004016100899061101a565b6001600160a01b03831660009081526001820160205260409020546001600160601b0381166103d6576103d68285610982565b60005b83518110156104c25760008482815181106103f6576103f661112d565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b031680156104945760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b6064820152608401610089565b6104a08583868a6109ec565b836104aa816110c4565b945050505080806104ba906110a9565b9150506103d9565b5050505050565b60008151116104ea5760405162461bcd60e51b815260040161008990610fcf565b6000805160206111448339815191526001600160a01b03831661051f5760405162461bcd60e51b81526004016100899061101a565b6001600160a01b03831660009081526001820160205260409020546001600160601b038116610552576105528285610982565b60005b83518110156104c25760008482815181106105725761057261112d565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0390811690871681141561061e5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610089565b610629858284610a8c565b6106358583868a6109ec565b8361063f816110c4565b9450505050808061064f906110a9565b915050610555565b60008151116106785760405162461bcd60e51b815260040161008990610fcf565b6000805160206111448339815191526001600160a01b038316156106fd5760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b6064820152608401610089565b60005b825181101561076f57600083828151811061071d5761071d61112d565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031661075a848284610a8c565b50508080610767906110a9565b915050610700565b50505050565b6001600160a01b0382166107fc578051156107f85760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401610089565b5050565b60008151116108735760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401610089565b6001600160a01b03821630146108a5576108a58260405180606001604052806028815260200161116460289139610e4c565b600080836001600160a01b0316836040516108c09190610e99565b600060405180830381855af49150503d80600081146108fb576040519150601f19603f3d011682016040523d82523d6000602084013e610900565b606091505b50915091508161076f5780511561092b578060405162461bcd60e51b81526004016100899190610fb5565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401610089565b6109a48160405180606001604052806024815260200161118c60249139610e4c565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160e01b0319831660008181526020868152604080832080546001600160601b03909716600160a01b026001600160a01b0397881617815594909516808352600180890183529583208054968701815583528183206008870401805460e09890981c60046007909816979097026101000a96870263ffffffff9097021990971695909517909555529290915281546001600160a01b031916179055565b6001600160a01b038216610b085760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610089565b6001600160a01b038216301415610b785760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401610089565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b03169291610bc791611066565b9050808214610cb9576001600160a01b03841660009081526001860160205260408120805483908110610bfc57610bfc61112d565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110610c4d57610c4d61112d565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480610ce257610ce2611117565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812055806104c2576002850154600090610d4190600190611066565b6001600160a01b0386166000908152600180890160205260409091200154909150808214610df0576000876002018381548110610d8057610d8061112d565b6000918252602090912001546002890180546001600160a01b039092169250829184908110610db157610db161112d565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480610e0357610e03611117565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b818161076f5760405162461bcd60e51b81526004016100899190610fb5565b60008151808452610e8581602086016020860161107d565b601f01601f19169290920160200192915050565b60008251610eab81846020870161107d565b9190910192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b84811015610f8557898403607f19018652815180516001600160a01b03168552838101518986019060038110610f2457634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015610f705783516001600160e01b0319168252928601926001929092019190860190610f46565b50978501979550505090820190600101610ede565b50506001600160a01b038a16908801528681036040880152610fa78189610e6d565b9a9950505050505050505050565b602081526000610fc86020830184610e6d565b9392505050565b6020808252602b908201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660408201526a1858d95d081d1bc818dd5d60aa1b606082015260800190565b6020808252602c908201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260408201526b65206164647265737328302960a01b606082015260800190565b600082821015611078576110786110eb565b500390565b60005b83811015611098578181015183820152602001611080565b8381111561076f5750506000910152565b60006000198214156110bd576110bd6110eb565b5060010190565b60006001600160601b03808316818114156110e1576110e16110eb565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fdfec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220795ef6cc7673851b890285a5dba416996941361b46ed69aa34655dcb7d15532464736f6c63430008070033c8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204164642066616365742063616e277420624c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f64654c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e2066000000000000000000000000cb1e9fa11edd27098a6b2ff23cb6b79183ccf8ee000000000000000000000000c46304a0b2accc4462d9bdcaa0f6bf632510d617Deployed Bytecode
0x60806040523661000b57005b600080356001600160e01b0319168152600080516020611144833981519152602081905260409091205481906001600160a01b0316806100925760405162461bcd60e51b815260206004820181905260248201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f7420657869737460448201526064015b60405180910390fd5b3660008037600080366000845af43d6000803e8080156100b1573d6000f35b3d6000fd5b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c132080546001600160a01b031981166001600160a01b03848116918217909355604051600080516020611144833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60005b83518110156103025760008482815181106101595761015961112d565b60200260200101516020015190506000600281111561017a5761017a611101565b81600281111561018c5761018c611101565b14156101db576101d68583815181106101a7576101a761112d565b6020026020010151600001518684815181106101c5576101c561112d565b60200260200101516040015161034d565b6102ef565b60018160028111156101ef576101ef611101565b1415610239576101d685838151811061020a5761020a61112d565b6020026020010151600001518684815181106102285761022861112d565b6020026020010151604001516104c9565b600281600281111561024d5761024d611101565b1415610297576101d68583815181106102685761026861112d565b6020026020010151600001518684815181106102865761028661112d565b602002602001015160400151610657565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b6064820152608401610089565b50806102fa816110a9565b91505061013c565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161033693929190610eb5565b60405180910390a16103488282610775565b505050565b600081511161036e5760405162461bcd60e51b815260040161008990610fcf565b6000805160206111448339815191526001600160a01b0383166103a35760405162461bcd60e51b81526004016100899061101a565b6001600160a01b03831660009081526001820160205260409020546001600160601b0381166103d6576103d68285610982565b60005b83518110156104c25760008482815181106103f6576103f661112d565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b031680156104945760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6044820152746e207468617420616c72656164792065786973747360581b6064820152608401610089565b6104a08583868a6109ec565b836104aa816110c4565b945050505080806104ba906110a9565b9150506103d9565b5050505050565b60008151116104ea5760405162461bcd60e51b815260040161008990610fcf565b6000805160206111448339815191526001600160a01b03831661051f5760405162461bcd60e51b81526004016100899061101a565b6001600160a01b03831660009081526001820160205260409020546001600160601b038116610552576105528285610982565b60005b83518110156104c25760008482815181106105725761057261112d565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0390811690871681141561061e5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610089565b610629858284610a8c565b6106358583868a6109ec565b8361063f816110c4565b9450505050808061064f906110a9565b915050610555565b60008151116106785760405162461bcd60e51b815260040161008990610fcf565b6000805160206111448339815191526001600160a01b038316156106fd5760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604482015275657373206d757374206265206164647265737328302960501b6064820152608401610089565b60005b825181101561076f57600083828151811061071d5761071d61112d565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031661075a848284610a8c565b50508080610767906110a9565b915050610700565b50505050565b6001600160a01b0382166107fc578051156107f85760405162461bcd60e51b815260206004820152603c60248201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860448201527f3029206275745f63616c6c64617461206973206e6f7420656d707479000000006064820152608401610089565b5050565b60008151116108735760405162461bcd60e51b815260206004820152603d60248201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460448201527f7920627574205f696e6974206973206e6f7420616464726573732830290000006064820152608401610089565b6001600160a01b03821630146108a5576108a58260405180606001604052806028815260200161116460289139610e4c565b600080836001600160a01b0316836040516108c09190610e99565b600060405180830381855af49150503d80600081146108fb576040519150601f19603f3d011682016040523d82523d6000602084013e610900565b606091505b50915091508161076f5780511561092b578060405162461bcd60e51b81526004016100899190610fb5565b60405162461bcd60e51b815260206004820152602660248201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656044820152651d995c9d195960d21b6064820152608401610089565b6109a48160405180606001604052806024815260200161118c60249139610e4c565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160e01b0319831660008181526020868152604080832080546001600160601b03909716600160a01b026001600160a01b0397881617815594909516808352600180890183529583208054968701815583528183206008870401805460e09890981c60046007909816979097026101000a96870263ffffffff9097021990971695909517909555529290915281546001600160a01b031916179055565b6001600160a01b038216610b085760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610089565b6001600160a01b038216301415610b785760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401610089565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b03169291610bc791611066565b9050808214610cb9576001600160a01b03841660009081526001860160205260408120805483908110610bfc57610bfc61112d565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110610c4d57610c4d61112d565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480610ce257610ce2611117565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812055806104c2576002850154600090610d4190600190611066565b6001600160a01b0386166000908152600180890160205260409091200154909150808214610df0576000876002018381548110610d8057610d8061112d565b6000918252602090912001546002890180546001600160a01b039092169250829184908110610db157610db161112d565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480610e0357610e03611117565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b818161076f5760405162461bcd60e51b81526004016100899190610fb5565b60008151808452610e8581602086016020860161107d565b601f01601f19169290920160200192915050565b60008251610eab81846020870161107d565b9190910192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b84811015610f8557898403607f19018652815180516001600160a01b03168552838101518986019060038110610f2457634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015610f705783516001600160e01b0319168252928601926001929092019190860190610f46565b50978501979550505090820190600101610ede565b50506001600160a01b038a16908801528681036040880152610fa78189610e6d565b9a9950505050505050505050565b602081526000610fc86020830184610e6d565b9392505050565b6020808252602b908201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660408201526a1858d95d081d1bc818dd5d60aa1b606082015260800190565b6020808252602c908201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260408201526b65206164647265737328302960a01b606082015260800190565b600082821015611078576110786110eb565b500390565b60005b83811015611098578181015183820152602001611080565b8381111561076f5750506000910152565b60006000198214156110bd576110bd6110eb565b5060010190565b60006001600160601b03808316818114156110e1576110e16110eb565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fdfec8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220795ef6cc7673851b890285a5dba416996941361b46ed69aa34655dcb7d15532464736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cb1e9fa11edd27098a6b2ff23cb6b79183ccf8ee000000000000000000000000c46304a0b2accc4462d9bdcaa0f6bf632510d617
-----Decoded View---------------
Arg [0] : _contractOwner (address): 0xCB1e9fA11Edd27098A6B2Ff23cB6b79183ccf8Ee
Arg [1] : _diamondCutFacet (address): 0xC46304a0B2ACcC4462d9BDCAa0f6bf632510d617
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000cb1e9fa11edd27098a6b2ff23cb6b79183ccf8ee
Arg [1] : 000000000000000000000000c46304a0b2accc4462d9bdcaa0f6bf632510d617Deployed Bytecode Sourcemap
175:2212:25:-:0;;;;;;;;1072:36;1422:7;;-1:-1:-1;;;;;;1422:7:25;1392:38;;-1:-1:-1;;;;;;;;;;;1392:38:25;;;;;;;;:51;197:45:28;;-1:-1:-1;;;;;1392:51:25;;1453:64;;;;-1:-1:-1;;;1453:64:25;;5678:2:32;1453:64:25;;;5660:21:32;;;5697:18;;;5690:30;5756:34;5736:18;;;5729:62;5808:18;;1453:64:25;;;;;;;;;1771:14;1768:1;1765;1752:34;1915:1;1912;1896:14;1893:1;1886:5;1879;1866:51;1987:16;1984:1;1981;1966:38;2091:6;2110:66;;;;2225:16;2222:1;2215:27;2110:66;2145:16;2142:1;2135:27;1612:264:28;1754:16;;;-1:-1:-1;;;;;;1780:28:28;;-1:-1:-1;;;;;1780:28:28;;;;;;;;;1823:46;;-1:-1:-1;;;;;;;;;;;197:45:28;1754:16;;;;;;1823:46;;1676:25;;1823:46;1666:210;;1612:264;:::o;2324:1067::-;2480:18;2475:806;2513:11;:18;2500:10;:31;2475:806;;;2561:33;2597:11;2609:10;2597:23;;;;;;;;:::i;:::-;;;;;;;:30;;;2561:66;;2655:30;2645:40;;;;;;;;:::i;:::-;:6;:40;;;;;;;;:::i;:::-;;2641:630;;;2705:93;2718:11;2730:10;2718:23;;;;;;;;:::i;:::-;;;;;;;:36;;;2756:11;2768:10;2756:23;;;;;;;;:::i;:::-;;;;;;;:41;;;2705:12;:93::i;:::-;2641:630;;;2833:34;2823:6;:44;;;;;;;;:::i;:::-;;2819:452;;;2887:97;2904:11;2916:10;2904:23;;;;;;;;:::i;:::-;;;;;;;:36;;;2942:11;2954:10;2942:23;;;;;;;;:::i;:::-;;;;;;;:41;;;2887:16;:97::i;2819:452::-;3019:33;3009:6;:43;;;;;;;;:::i;:::-;;3005:266;;;3072:96;3088:11;3100:10;3088:23;;;;;;;;:::i;:::-;;;;;;;:36;;;3126:11;3138:10;3126:23;;;;;;;;:::i;:::-;;;;;;;:41;;;3072:15;:96::i;3005:266::-;3207:49;;-1:-1:-1;;;3207:49:28;;4857:2:32;3207:49:28;;;4839:21:32;4896:2;4876:18;;;4869:30;4935:34;4915:18;;;4908:62;-1:-1:-1;;;4986:18:32;;;4979:37;5033:19;;3207:49:28;4655:403:32;3005:266:28;-1:-1:-1;2533:12:28;;;;:::i;:::-;;;;2475:806;;;;3295:41;3306:11;3319:5;3326:9;3295:41;;;;;;;;:::i;:::-;;;;;;;;3346:38;3367:5;3374:9;3346:20;:38::i;:::-;2324:1067;;;:::o;3397:1069::-;3533:1;3505:18;:25;:29;3497:85;;;;-1:-1:-1;;;3497:85:28;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;3654:27:28;;3646:84;;;;-1:-1:-1;;;3646:84:28;;;;;;;:::i;:::-;-1:-1:-1;;;;;3773:40:28;;3740:23;3773:40;;;:25;;;:40;;;;;:65;-1:-1:-1;;;;;3907:21:28;;3903:79;;3944:27;3953:2;3957:13;3944:8;:27::i;:::-;3996:21;3991:469;4035:18;:25;4019:13;:41;3991:469;;;4093:15;4111:18;4130:13;4111:33;;;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;;4184:39:28;;4158:23;4184:39;;;;;;;;;;;:52;4111:33;;-1:-1:-1;;;;;;4184:52:28;4258:29;;4250:95;;;;-1:-1:-1;;;4250:95:28;;6884:2:32;4250:95:28;;;6866:21:32;6923:2;6903:18;;;6896:30;6962:34;6942:18;;;6935:62;-1:-1:-1;;;7013:18:32;;;7006:51;7074:19;;4250:95:28;6682:417:32;4250:95:28;4359:58;4371:2;4375:8;4385:16;4403:13;4359:11;:58::i;:::-;4431:18;;;;:::i;:::-;;;;4079:381;;4062:15;;;;;:::i;:::-;;;;3991:469;;;;3487:979;;3397:1069;;:::o;4472:1138::-;4612:1;4584:18;:25;:29;4576:85;;;;-1:-1:-1;;;4576:85:28;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;4733:27:28;;4725:84;;;;-1:-1:-1;;;4725:84:28;;;;;;;:::i;:::-;-1:-1:-1;;;;;4852:40:28;;4819:23;4852:40;;;:25;;;:40;;;;;:65;-1:-1:-1;;;;;4986:21:28;;4982:79;;5023:27;5032:2;5036:13;5023:8;:27::i;:::-;5075:21;5070:534;5114:18;:25;5098:13;:41;5070:534;;;5172:15;5190:18;5209:13;5190:33;;;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;;5263:39:28;;5237:23;5263:39;;;;;;;;;;;:52;5190:33;;-1:-1:-1;;;;;;5263:52:28;;;;5337:32;;;;;5329:101;;;;-1:-1:-1;;;5329:101:28;;7306:2:32;5329:101:28;;;7288:21:32;7345:2;7325:18;;;7318:30;7384:34;7364:18;;;7357:62;7455:26;7435:18;;;7428:54;7499:19;;5329:101:28;7104:420:32;5329:101:28;5444:45;5459:2;5463:15;5480:8;5444:14;:45::i;:::-;5503:58;5515:2;5519:8;5529:16;5547:13;5503:11;:58::i;:::-;5575:18;;;;:::i;:::-;;;;5158:446;;5141:15;;;;;:::i;:::-;;;;5070:534;;5616:742;5755:1;5727:18;:25;:29;5719:85;;;;-1:-1:-1;;;5719:85:28;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;5941:27:28;;;5933:94;;;;-1:-1:-1;;;5933:94:28;;7731:2:32;5933:94:28;;;7713:21:32;7770:2;7750:18;;;7743:30;7809:34;7789:18;;;7782:62;-1:-1:-1;;;7860:18:32;;;7853:52;7922:19;;5933:94:28;7529:418:32;5933:94:28;6042:21;6037:315;6081:18;:25;6065:13;:41;6037:315;;;6139:15;6157:18;6176:13;6157:33;;;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;;6230:39:28;;6204:23;6230:39;;;;;;;;;;;:52;6157:33;;-1:-1:-1;;;;;;6230:52:28;6296:45;6230:2;:52;6157:33;6296:14;:45::i;:::-;6125:227;;6108:15;;;;;:::i;:::-;;;;6037:315;;;;5709:649;5616:742;;:::o;9337:934::-;-1:-1:-1;;;;;9429:19:28;;9425:840;;9472:16;;:21;9464:94;;;;-1:-1:-1;;;9464:94:28;;3185:2:32;9464:94:28;;;3167:21:32;3224:2;3204:18;;;3197:30;3263:34;3243:18;;;3236:62;3334:30;3314:18;;;3307:58;3382:19;;9464:94:28;2983:424:32;9464:94:28;9337:934;;:::o;9425:840::-;9616:1;9597:9;:16;:20;9589:94;;;;-1:-1:-1;;;9589:94:28;;6039:2:32;9589:94:28;;;6021:21:32;6078:2;6058:18;;;6051:30;6117:34;6097:18;;;6090:62;6188:31;6168:18;;;6161:59;6237:19;;9589:94:28;5837:425:32;9589:94:28;-1:-1:-1;;;;;9701:22:28;;9718:4;9701:22;9697:134;;9743:73;9766:5;9743:73;;;;;;;;;;;;;;;;;:22;:73::i;:::-;9908:12;9922:18;9944:5;-1:-1:-1;;;;;9944:18:28;9963:9;9944:29;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9907:66;;;;9992:7;9987:268;;10023:12;;:16;10019:222;;10120:5;10106:21;;-1:-1:-1;;;10106:21:28;;;;;;;;:::i;10019:222::-;10174:48;;-1:-1:-1;;;10174:48:28;;3614:2:32;10174:48:28;;;3596:21:32;3653:2;3633:18;;;3626:30;3692:34;3672:18;;;3665:62;-1:-1:-1;;;3743:18:32;;;3736:36;3789:19;;10174:48:28;3412:402:32;6364:316:28;6451:77;6474:13;6451:77;;;;;;;;;;;;;;;;;:22;:77::i;:::-;6602:17;;;:24;;-1:-1:-1;;;;;6538:40:28;;;;;;;:25;;;;:40;;;;;;;:61;;:88;;;6636:37;;;;;;;;;;;;;;-1:-1:-1;;;;;;6636:37:28;;;;;;6364:316::o;6686:427::-;-1:-1:-1;;;;;;6858:40:28;;:29;:40;;;;;;;;;;;:85;;-1:-1:-1;;;;;6858:85:28;;;-1:-1:-1;;;6858:85:28;-1:-1:-1;;;;;6858:85:28;;;;;;6953:40;;;;;;;-1:-1:-1;6953:25:28;;;:40;;;;;:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6858:85;6953:74;;;;;;;;;;;;;;;;;;;7037:40;;;;;:69;;-1:-1:-1;;;;;;7037:69:28;;;;6686:427::o;7119:2212::-;-1:-1:-1;;;;;7268:27:28;;7260:95;;;;-1:-1:-1;;;7260:95:28;;4433:2:32;7260:95:28;;;4415:21:32;4472:2;4452:18;;;4445:30;4511:34;4491:18;;;4484:62;4582:25;4562:18;;;4555:53;4625:19;;7260:95:28;4231:419:32;7260:95:28;-1:-1:-1;;;;;7450:30:28;;7475:4;7450:30;;7442:89;;;;-1:-1:-1;;;7442:89:28;;6469:2:32;7442:89:28;;;6451:21:32;6508:2;6488:18;;;6481:30;6547:34;6527:18;;;6520:62;-1:-1:-1;;;6598:18:32;;;6591:44;6652:19;;7442:89:28;6267:410:32;7442:89:28;-1:-1:-1;;;;;;7642:40:28;;7615:24;7642:40;;;;;;;;;;;:65;-1:-1:-1;;;;;7748:40:28;;;;7816:1;7748:25;;;:40;;;;;;:65;-1:-1:-1;;;7642:65:28;;;-1:-1:-1;;;;;7642:65:28;;7615:24;7748:69;;;:::i;:::-;7717:100;;7919:20;7899:16;:40;7895:387;;-1:-1:-1;;;;;7977:40:28;;7955:19;7977:40;;;:25;;;:40;;;;;:80;;8036:20;;7977:80;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;8071:40:28;;;;:25;;;:40;;;;;;;:76;;7977:80;;;;;;;;;;;;;;-1:-1:-1;7977:80:28;;8071:40;8130:16;;8071:76;;;;;;:::i;:::-;;;;;;;;;;;;;:91;;;:76;;;;;;:91;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;8176:43:28;;;;;;;;;;;;:95;;-1:-1:-1;;;;;8176:95:28;-1:-1:-1;;;;;;;;8176:95:28;;;;;;7895:387;-1:-1:-1;;;;;8327:40:28;;;;;;:25;;;:40;;;;;:64;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;8327:64:28;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;8408:40:28;;;;;;;;;;8401:47;8543:25;8539:786;;8710:17;;;:24;8675:32;;8710:28;;8737:1;;8710:28;:::i;:::-;-1:-1:-1;;;;;8783:40:28;;8752:28;8783:40;;;:25;;;;:40;;;;;;:61;;8675:63;;-1:-1:-1;8862:48:28;;;8858:338;;8930:24;8957:2;:17;;8975:24;8957:43;;;;;;;;:::i;:::-;;;;;;;;;;;9018:17;;;:39;;-1:-1:-1;;;;;8957:43:28;;;;-1:-1:-1;8957:43:28;;9036:20;;9018:39;;;;;;:::i;:::-;;;;;;;;;;;;;:58;;-1:-1:-1;;;;;;9018:58:28;-1:-1:-1;;;;;9018:58:28;;;;;;9094:43;;;;;;-1:-1:-1;9094:25:28;;;:43;;;;;;:64;:87;;;8858:338;9209:2;:17;;:23;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;9209:23:28;;;;;-1:-1:-1;;;;;;9209:23:28;;;;;;;;;-1:-1:-1;;;;;9253:40:28;;;;9209:23;9253:25;;;:40;;;;;;:61;9246:68;-1:-1:-1;;7250:2081:28;;7119:2212;;;:::o;10277:317::-;10506:22;;10573:13;10555:16;10547:40;;;;-1:-1:-1;;;10547:40:28;;;;;;;;:::i;123:257:32:-;164:3;202:5;196:12;229:6;224:3;217:19;245:63;301:6;294:4;289:3;285:14;278:4;271:5;267:16;245:63;:::i;:::-;362:2;341:15;-1:-1:-1;;337:29:32;328:39;;;;369:4;324:50;;123:257;-1:-1:-1;;123:257:32:o;385:274::-;514:3;552:6;546:13;568:53;614:6;609:3;602:4;594:6;590:17;568:53;:::i;:::-;637:16;;;;;385:274;-1:-1:-1;;385:274:32:o;664:2090::-;932:4;961:2;1001;990:9;986:18;1031:2;1020:9;1013:21;1054:6;1089;1083:13;1120:6;1112;1105:22;1146:3;1136:13;;1180:2;1169:9;1165:18;1158:25;;1242:2;1232:6;1229:1;1225:14;1214:9;1210:30;1206:39;1264:4;1303:2;1295:6;1291:15;1324:1;1334:1249;1348:6;1345:1;1342:13;1334:1249;;;1413:22;;;-1:-1:-1;;1409:37:32;1397:50;;1470:13;;1557:9;;-1:-1:-1;;;;;1553:35:32;1538:51;;1628:11;;;1622:18;1510:15;;;;1680:1;1663:19;;1653:170;;1733:10;1728:3;1724:20;1721:1;1714:31;1772:4;1769:1;1762:15;1804:4;1801:1;1794:15;1653:170;1843:15;;;1836:37;1896:4;1941:11;;;1935:18;1973:15;;;1966:27;;;2054:21;;2088:24;;;;2178:23;;;;-1:-1:-1;;2134:15:32;;;;2239:236;2255:8;2250:3;2247:17;2239:236;;;2336:15;;-1:-1:-1;;;;;;2332:42:32;2318:57;;2444:17;;;;2283:1;2274:11;;;;;2401:14;;;;2239:236;;;-1:-1:-1;2561:12:32;;;;2498:5;-1:-1:-1;;;2526:15:32;;;;1370:1;1363:9;1334:1249;;;-1:-1:-1;;;;;;;80:31:32;;2619:18;;;68:44;2676:22;;;2669:4;2654:20;;2647:52;2716:32;2680:6;2733;2716:32;:::i;:::-;2708:40;664:2090;-1:-1:-1;;;;;;;;;;664:2090:32:o;2759:219::-;2908:2;2897:9;2890:21;2871:4;2928:44;2968:2;2957:9;2953:18;2945:6;2928:44;:::i;:::-;2920:52;2759:219;-1:-1:-1;;;2759:219:32:o;3819:407::-;4021:2;4003:21;;;4060:2;4040:18;;;4033:30;4099:34;4094:2;4079:18;;4072:62;-1:-1:-1;;;4165:2:32;4150:18;;4143:41;4216:3;4201:19;;3819:407::o;5063:408::-;5265:2;5247:21;;;5304:2;5284:18;;;5277:30;5343:34;5338:2;5323:18;;5316:62;-1:-1:-1;;;5409:2:32;5394:18;;5387:42;5461:3;5446:19;;5063:408::o;7952:125::-;7992:4;8020:1;8017;8014:8;8011:34;;;8025:18;;:::i;:::-;-1:-1:-1;8062:9:32;;7952:125::o;8082:258::-;8154:1;8164:113;8178:6;8175:1;8172:13;8164:113;;;8254:11;;;8248:18;8235:11;;;8228:39;8200:2;8193:10;8164:113;;;8295:6;8292:1;8289:13;8286:48;;;-1:-1:-1;;8330:1:32;8312:16;;8305:27;8082:258::o;8345:135::-;8384:3;-1:-1:-1;;8405:17:32;;8402:43;;;8425:18;;:::i;:::-;-1:-1:-1;8472:1:32;8461:13;;8345:135::o;8485:217::-;8523:3;-1:-1:-1;;;;;8612:2:32;8605:5;8601:14;8639:2;8630:7;8627:15;8624:41;;;8645:18;;:::i;:::-;8694:1;8681:15;;8485:217;-1:-1:-1;;;8485:217:32:o;8707:127::-;8768:10;8763:3;8759:20;8756:1;8749:31;8799:4;8796:1;8789:15;8823:4;8820:1;8813:15;8839:127;8900:10;8895:3;8891:20;8888:1;8881:31;8931:4;8928:1;8921:15;8955:4;8952:1;8945:15;8971:127;9032:10;9027:3;9023:20;9020:1;9013:31;9063:4;9060:1;9053:15;9087:4;9084:1;9077:15;9103:127;9164:10;9159:3;9155:20;9152:1;9145:31;9195:4;9192:1;9185:15;9219:4;9216:1;9209:15
Swarm Source
ipfs://795ef6cc7673851b890285a5dba416996941361b46ed69aa34655dcb7d155324
Loading...LoadingLoading...Loading
Loading...Loading
Loading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingMultichain Portfolio | 30 Chains
Chain Token Portfolio % Price Amount Value ETH 37.20% $3,704.68 0.0145 $53.76 ETH 29.53% $1 42.6749 $42.67 ETH 24.45% $1 35.2913 $35.33 ETH 0.23% $0.002455 137.0198 $0.3363 BSC 4.07% $0.283128 20.7952 $5.89 BSC 0.15% $96,839.25 0.00000227 $0.2196 AVAX 1.59% $0.004143 556.3432 $2.3 AVAX 0.20% $3,702.2 0.00007929 $0.2935 FTM 1.25% $0.283128 6.3753 $1.81 POL 0.60% $0.283128 3.0511 $0.8638 POL 0.07% $0.000664 161.05 $0.1069 POL Polygon (POL)0.06% $0.578954 0.14 $0.081054 OP 0.52% $1 0.7468 $0.7475 OP <0.01% $3,703.16 0.00000000000000003 <$0.000001 GNO 0.07% $0.999718 0.1 $0.099972 [ 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.
Address QR Code
My Address - Private Name Tag or Note
My Name Tag:
Private Name Tags (up to 35 characters) can be used for easy identification of addressesPrivate Note:
A private note (up to 500 characters) can be attached to this address.
Please DO NOT store any passwords or private keys here.Compiler specific version warnings:
The compiled contract might be susceptible to VerbatimInvalidDeduplication (low-severity), FullInlinerNonExpressionSplitArgumentEvaluationOrder (low-severity), MissingSideEffectsOnSelectorAccess (low-severity), AbiReencodingHeadOverflowWithStaticArrayCleanup (medium-severity), DirtyBytesArrayToStorage (low-severity), DataLocationChangeInInternalOverride (very low-severity), NestedCalldataArrayAbiReencodingSizeValidation (very low-severity), SignedImmutables (very low-severity) Solidity Compiler Bugs.
Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Before You Copy
Transaction Private Note
This website uses cookies to improve your experience. By continuing to use this website, you agree to its Terms and Privacy Policy.