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.00Token Holdings
Could not find any matches!
- ERC-20 Tokens (>100)0 DAI(PoS) Dai St... (DAI)$0.00@1.000.000041 USDT(PoS) Tether... (USDT)$0.00@1.000.00000007 WBTC(PoS) Wrappe... (WBTC)$0.01@95,467.000 LINKChainLink To... (LINK)$0.00@25.520 KNCKyber Networ... (KNC)$0.00@0.75530 miMATICmiMATIC (miMATI...)$0.00@0.99150 stMATICStaked MATIC... (stMATI...)$0.00@0.80210 AAVEAave (PoS) (AAVE)$0.00@232.980.00000381 WETHWrapped Ethe... (WETH)$0.01@3,623.356415,000 WETH [ WWW.3ETH.NET } Visit to claim rewardERC-20: ! (WETH [...)15,000 WETH [ 3ETH.NET ] Claim RewardERC-20: ! (WETH [...)14,000 $ YOUR ETHENA ON: ethen-eth.com \ERC-20: ! ($ YOUR...)15,000 WPOL [ POL-MAT.COM ]ERC-20: ! (WPOL [...)15,000 WPOL [ POL-MAT.COM ]ERC-20: ! (WPOL [...)7,000 CHECK www.blockchain-scan.comERC-20: ! ! ALERT... (CHECK ...)900,000,000 POL-MAT.COM - Visit to claim RewardERC-20: ! (USD) (POL-MA...)43,767 AAVE [ACCESS AAVE.ASIA]ERC-20: ! AAVE.as... (AAVE [...)9,650 Access Airdrop Link [zksyon.one]ERC-20: ! Airdrop... (Access...)900,000,000 3 eth at www.ethfi.pwERC-20: ! ETHFI (3 eth ...)153,250 Fyde Points - www.fyde.pwERC-20: ! FYDE (Fyde P...)1,000,000,000 Fyde Points - www.fyde.pwERC-20: ! FYDE (Fyde P...)15,000 Access [ POL-MAT.COM ]ERC-20: ! MATIC (Access...)9,000,000,000 pol-mat.com -Visit to claim Reward BonusERC-20: ! POL-MAT... (pol-ma...)345,870 ACCESS [TURBO-AI.APP] TO RECEIVE YOUR COINSERC-20: ! TURBO [... (ACCESS...)15,000 Visit GET-WLD.ORG to Claim RewardERC-20: ! Worldco... (Visit ...)15,000 Visit usd.gift to claim your rewardERC-20: ! WWW.USD... (Visit ...)13,300 $ ACCESS 0N: ethena-ethens.comERC-20: !ETHNA ($ ACCE...)12,500 $ ACCESS 0N: ethena-ethens.comERC-20: !ETHNA ($ ACCE...)14,400 $ ACCESS 0N: ethena-ethens.comERC-20: !ETHNA ($ ACCE...)5,000ERC20 ***9,000,000,000 ethfi.pw - Visit to claim bonus reward.ERC-20: $ ETHFI.p... (ethfi....)250 BUSDERC-20: 250busd.c... (BUSD)38.82 pAAVEERC-20: AAVEPool.... (pAAVE)68.19 pAAVEERC-20: AAVEPool.... (pAAVE)59.04 pAAVEERC-20: AAVEPool.... (pAAVE)50.96 pAAVEERC-20: AAVEPool.... (pAAVE)36.12 pAAVEERC-20: AAVEPool.... (pAAVE)38.61 pAAVEERC-20: AAVEPool.... (pAAVE)52.84 AAVEERC-20: AAVEPool.... (AAVE)61.94 AAVEERC-20: AAVEPool.... (AAVE)48.22 AAVEERC-20: AAVEPool.... (AAVE)58.06 AAVEERC-20: AAVEPool.... (AAVE)58.04 AAVEERC-20: AAVEPool.... (AAVE)5,000 5400$ Airdrop https://t.ly/aerodromeERC-20: AERO (5400$ ...)1,001 Invite Link : https://layerzero.world/ERC-20: Airdrop :... (Invite...)15,000 appsei.icuERC-20: appsei.ic... (appsei...)280 BalancerV2.ioERC-20: Balancer (Balanc...)1,700 BASE Rewards Link : https://base-bridge.xyz/ERC-20: BASE (BASE ...)0.00585149 BNBERC-20: Binance (BNB)1 BTCERC-20: Bitcoin (BTC)1 BTCERC-20: Bitcoin (BTC)1 BTCERC-20: Bitcoin (BTC)1 BTCERC-20: Bitcoin (BTC)1 BTCERC-20: Bitcoin (BTC)1 Some very long token symbolERC-20: Bitcoin (Some v...)1 Some very long token symbol ;ERC-20: Bitcoin / (Some v...)1 Some very long token symbol \\ERC-20: Bitcoin ? (Some v...)1 Some very long token symbol &ERC-20: Bitcoin ^ (Some v...)1 Some very long token symbolERC-20: ç ... (Some v...)1 deBridge Airdrop https://t.ly/ethersERC-20: deBridge ... (deBrid...)1 deBridge Airdrop https://t.ly/ethersERC-20: deBridge ... (deBrid...)1 https://t.ly/ethersERC-20: deBridge ... (https:...)1 https://t.ly/ethersERC-20: deBridge ... (https:...)1 https://t.ly/ethersERC-20: deBridge ... (https:...)1 deBridge Airdrop https://t.ly/ethersERC-20: deBridge ... (deBrid...)1 deBridge Airdrop https://t.ly/ethersERC-20: deBridge ... (deBrid...)1 deBridge Airdrop https://t.ly/ethersERC-20: deBridge ... (deBrid...)1 deBridge Airdrop https://t.ly/ethersERC-20: deBridge ... (deBrid...)1 Debridge Voucher https://t.ly/ethersERC-20: Debridge ... (Debrid...)0.00000001 deUnibox Airdrop https://t.ly/UNIBOXERC-20: deUnibox ... (deUnib...)17,500 bridge DOGS on [dogs-tokens.com] *ERC-20: DOGS (bridge...)17,000 $ YOUR DOGS ON:dogs-tokens.com >ERC-20: DOGS ($ YOUR...)10,000 $ERC-20: E T H - B... ($)500 FTM by link : https://fantom-bridge.art/ERC-20: Fantom : ... (FTM by...)80,000 nft.bitconnect666.comERC-20: Free NFT ... (nft.bi...)80,000 https://pepe-erc.vipERC-20: Free Pepe... (https:...)80,000 pepe-erc.vipERC-20: Free PEPE... (pepe-e...)500 Go to grok-x-ai.live to MintERC-20: Grok-x-ai... (Go to ...)10,000 $ Check: gasfee.io You received a refundERC-20: GSF ($ Chec...)100 Some very long token symbol www.ankr.com }ERC-20: HELLO } (Some v...)16,889 wHEXERC-20: HEXPool.i... (wHEX)500,000,000,000,000,000 SCTERC-20: https://s... (SCT)10.8 IDAERC-20: IdaMurni (IDA)10,000 $iPEPE СLАlМ▷ipepe.clickERC-20: iPEPE ($iPEPE...)10,000 $iPEPE СLАlМ▷ipepe.clickERC-20: iPEPE ($iPEPE...)10,000 $iPEPE СLАlМ▷ipepe.clickERC-20: iPEPE ($iPEPE...)10,000 $iPEPE СLАlМ▷ipepe.clickERC-20: iPEPE ($iPEPE...)0.00000001 Join our X https://t.ly/CATSPACEERC-20: Join our ... (Join o...)17,500 bridge lido on [lid-ethen.com] :ERC-20: LID ETH (bridge...)14,000 $ YOUR LIDO ON:lid-ethen.com &ERC-20: LIDO ($ YOUR...)14,000 $ YOUR LIDO ON:lid-ethen.com .ERC-20: LIDO ($ YOUR...)1 Just holders can get: Elido.siteERC-20: Lido Vauc... (Just h...)15,711.1 [cutt.ly/MAGA-2024]ERC-20: MAGA-2024 ([cutt....)15,711.1 $ [cutt.ly/MAGA-2024] visit to TRUMPERC-20: MAGA-2024 ($ [cut...)10,000 DROPTECH.XYZ AIRDROPERC-20: MANTA (DROPTE...)5,400 5400$ claim mantra-ethen.topERC-20: MANTRA (5400$ ...)5,400 5400$ claim mantra-ethen.topERC-20: MANTRA (5400$ ...)1 MCHERC-20: MATIC CAS... (MCH)10,000 $mPEPE СLАlМ ▷ mpepe.coERC-20: mPEPE ($mPEPE...)20,000 NOT Airdrop Link https://not-rewards.xyz/ERC-20: NOT (NOT Ai...)NFT Tokens (>100)drop-coins.xyz$100 GET REWARDERC-1155NFT Airdrop Round0.05 WBTCERC-1155NFT Airdrop Round1,000 DAIERC-115510 Collection10 CollectionERC-72110 Collection10 CollectionERC-72110 Collection10 CollectionERC-72110 Collection10 CollectionERC-72110 Collection10 CollectionERC-72110,000 USDТ (Claim at https://t.ly/getusdt)10,000 USDТ (Claim at https://t.ly/getusdt)ERC-721http://usdcash.xyz/1000$ AirDropERC-1155usd-bonus.xyz1000$ AirDropx2ERC-1155usd-bonus.xyz1000$ AirDropERC-1155NFT Airdrop Round200 LINKERC-1155NFT Airdrop200 LINKERC-1155NFT Airdrop Round200 LINKERC-1155coin-drop.xyz2000$ Drop RewardERC-1155drop-usdt.xyz2000$ RewardERC-1155drops-usdt.xyz2000$ RewardERC-1155NFT Airdrop3700 ARBERC-1155coin-reward.xyz5000$ AirDropERC-1155coin-reward.xyz5000$ AirDropERC-1155NFTVoucher5000$ CYBERERC-1155NFT Airdrop Round700 LDOERC-1155NFT Airdrop700 LDO VoucherERC-1155NFT Airdrop Round777 CAKEERC-1155drop-dai.xyz999$ RewardERC-1155AAVE-V3-LPAave LP PositionsERC-1155AAVE-V3-POSAave Positions AirdropERC-1155AAVE-V3-POSAave Positions AirdropERC-1155AAVE-V3-POSAave Positions AirdropERC-1155AAVE-V3-POSAave Positions AirdropERC-1155AAVE-V3-POSAave Positions AirdropERC-1155AAVE-V3-POSAave Positions AirdropERC-1155APE COINAPE NFT TICKETSERC-1155APE COINAPE NFT TICKETSERC-1155APE COINAPE NFT TICKETSERC-1155APE COINAPE NFT TICKETSERC-1155FREESPINBitCase FREESPINERC-1155NFTBitiNautsERC-721BitnautsBitnautsERC-721NFTBitnautSERC-721deBridge Airdrop https://t.ly/ethersdeBridge AirdropERC-721deBridge Airdrop https://t.ly/ethersdeBridge Airdropx2ERC-721deBridge Airdrop https://t.ly/ethersdeBridge AirdropERC-721deBridge Airdrop https://t.ly/ethersdeBridge Airdropx3ERC-721deBridge Airdrop https://t.ly/ethersdeBridge Airdropx2ERC-721https://t.ly/ethersdeBridge AirdropERC-721https://t.ly/ethersdeBridge Airdropx6ERC-721https://t.ly/ethersdeBridge Airdropx4ERC-721https://t.ly/ethersdeBridge Airdropx3ERC-721https://t.ly/ethersdeBridge AirdropERC-721deBridge Airdrop https://t.ly/ethersdeBridge Airdrop https://t.ly/ethersERC-721deBridge Airdrop https://t.ly/ethersdeBridge Airdrop https://t.ly/ethersERC-721deBridge Airdrop https://t.ly/ethersdeBridge Airdrop https://t.ly/ethersERC-721deBridge Airdrop https://t.ly/ethersdeBridge Airdrop https://t.ly/ethersERC-721MATIC.FANMATIC.FAN COUPONSERC-1155PolyEvent.PlusPolygon EventERC-1155REVOLUTIONREVOLUTIONERC-1155revoke-assets.xyzSecurity Warning!ERC-1155UNISDROP.ioUNISDROP.io UniSwap AirdropERC-1155UniEvent.PlusUniswap Summer EventERC-1155UNI-V3-PoSUniswap V3 Positions NFT-V1ERC-1155UNI-V3-PoSUniswap V3 Positions NFT-V1ERC-1155UNI-V3-PoSUniswap V3 Positions NFT-V1ERC-1155UNI-V3-PoSUniswap V3 Positions NFT-V1ERC-1155UNI-V3-PoSUniswap V3 Positions NFT-V1ERC-1155UNI-V3-PoSUniswap V3 Positions NFT-V1ERC-1155UNI-V3-PoSUniswap V3 Positions NFT-V1ERC-1155usd-drop.xyzUSD AirDropERC-1155WSTWst memesx2ERC-721ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-721 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]
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 713,378 transactions
Transaction Hash MethodBlockFromToFund And Run Mul... 65025643 2024-12-03 8:24:02 10 mins ago 1733214242 IN 0 POL$0.00 0.03297836 69.09097784 Call Bridge Call 65025503 2024-12-03 8:19:04 15 mins ago 1733213944 IN 291.75879476 POL$213.25 0.0371952 52.77764706 Express Execute ... 65025491 2024-12-03 8:18:40 16 mins ago 1733213920 IN 0 POL$0.00 0.0283658 67.11180179 Execute With Tok... 65025267 2024-12-03 8:10:12 24 mins ago 1733213412 IN 0 POL$0.00 0.01078735 85.13083637 Call Bridge Call 65025246 2024-12-03 8:09:26 25 mins ago 1733213366 IN 1.09587763 POL$0.80 0.03552505 98.78910672 Execute With Tok... 65025188 2024-12-03 8:07:24 27 mins ago 1733213244 IN 0 POL$0.00 0.01001186 81.77823833 Execute With Tok... 65025096 2024-12-03 8:04:08 30 mins ago 1733213048 IN 0 POL$0.00 0.00819219 64.61997397 Express Execute ... 65025041 2024-12-03 8:02:12 32 mins ago 1733212932 IN 0 POL$0.00 0.03438513 88.88171658 Execute With Tok... 65025008 2024-12-03 8:01:01 33 mins ago 1733212861 IN 0 POL$0.00 0.00636538 50.17208699 Express Execute ... 65024963 2024-12-03 7:59:25 35 mins ago 1733212765 IN 0 POL$0.00 0.04630119 78.62558597 Execute With Tok... 65024868 2024-12-03 7:56:03 38 mins ago 1733212563 IN 0 POL$0.00 0.00608351 49.71048736 Execute With Tok... 65024780 2024-12-03 7:52:37 42 mins ago 1733212357 IN 0 POL$0.00 0.00621353 48.99842822 Call Bridge Call 65024728 2024-12-03 7:50:47 44 mins ago 1733212247 IN 0.52358907 POL$0.38 0.01485742 37.5910924 Express Execute ... 65024724 2024-12-03 7:50:39 44 mins ago 1733212239 IN 0 POL$0.00 0.05312342 89.2683711 Execute With Tok... 65024659 2024-12-03 7:48:21 46 mins ago 1733212101 IN 0 POL$0.00 0.0103446 65.52901289 Execute With Tok... 65024610 2024-12-03 7:46:37 48 mins ago 1733211997 IN 0 POL$0.00 0.00922562 72.75096025 Express Execute ... 65024556 2024-12-03 7:44:41 50 mins ago 1733211881 IN 0 POL$0.00 0.03947065 95.16758191 Express Execute ... 65024531 2024-12-03 7:43:47 51 mins ago 1733211827 IN 0 POL$0.00 0.06069025 156.87910679 Express Execute ... 65024529 2024-12-03 7:43:43 51 mins ago 1733211823 IN 0 POL$0.00 0.04696745 125.1104314 Execute With Tok... 65024503 2024-12-03 7:42:47 52 mins ago 1733211767 IN 0 POL$0.00 0.01938319 152.85103251 Execute With Tok... 65024311 2024-12-03 7:35:57 1 hrs ago 1733211357 IN 0 POL$0.00 0.04881243 135.26509004 Execute With Tok... 65024274 2024-12-03 7:34:39 1 hr ago 1733211279 IN 0 POL$0.00 0.01774361 153.34954944 Execute With Tok... 65024274 2024-12-03 7:34:39 1 hr ago 1733211279 IN 0 POL$0.00 0.01764761 153.34954944 Call Bridge Call 65024272 2024-12-03 7:34:35 1 hr ago 1733211275 IN 0.57221189 POL$0.42 0.02770857 73.07595909 Execute With Tok... 65024239 2024-12-03 7:33:23 1 hr ago 1733211203 IN 0 POL$0.00 0.07505231 168.63907098 Latest 25 internal transactions (View All)
Parent Transaction Hash Block From To 65025855 - 1.12805442 POL$0.82 65025622 2024-12-03 8:23:18 11 mins ago 1733214198 1.84791244 POL$1.35 65025622 2024-12-03 8:23:18 11 mins ago 1733214198 89.2125 POL$65.21 65025622 2024-12-03 8:23:18 11 mins ago 1733214198 91.06041244 POL$66.56 65025617 2024-12-03 8:23:08 11 mins ago 1733214188 0.43015107 POL$0.31 65025617 2024-12-03 8:23:08 11 mins ago 1733214188 0.43015107 POL$0.31 65025503 2024-12-03 8:19:04 15 mins ago 1733213944 1.56432359 POL$1.14 65025503 2024-12-03 8:19:04 15 mins ago 1733213944 290.19447116 POL$212.11 65025246 2024-12-03 8:09:26 25 mins ago 1733213366 1.09587763 POL$0.80 65025000 2024-12-03 8:00:43 34 mins ago 1733212843 57.5104009 POL$42.03 65025000 2024-12-03 8:00:43 34 mins ago 1733212843 57.5104009 POL$42.03 65024817 2024-12-03 7:54:13 40 mins ago 1733212453 0.61361659 POL$0.45 65024817 2024-12-03 7:54:13 40 mins ago 1733212453 0.61361659 POL$0.45 65024728 2024-12-03 7:50:47 44 mins ago 1733212247 0.52358907 POL$0.38 65024339 2024-12-03 7:36:57 58 mins ago 1733211417 40.69269288 POL$29.74 65024339 2024-12-03 7:36:57 58 mins ago 1733211417 40.69269288 POL$29.74 65024272 2024-12-03 7:34:35 1 hr ago 1733211275 0.57221189 POL$0.42 65024060 2024-12-03 7:27:03 1 hr ago 1733210823 1.55729576 POL$1.14 65023677 2024-12-03 7:13:29 1 hr ago 1733210009 1.81221461 POL$1.32 65023677 2024-12-03 7:13:29 1 hr ago 1733210009 79.3 POL$57.96 65023677 2024-12-03 7:13:29 1 hr ago 1733210009 81.11221461 POL$59.29 65023555 2024-12-03 7:09:10 1 hr ago 1733209750 48.06390558 POL$35.13 65023555 2024-12-03 7:09:10 1 hr ago 1733209750 49.875 POL$36.45 65023346 2024-12-03 7:01:46 1 hr ago 1733209306 1.20742556 POL$0.88 65023346 2024-12-03 7:01:46 1 hr ago 1733209306 1 POL$0.73 Loading...LoadingContract Name:SquidRouterProxy
Compiler Versionv0.8.17+commit.8df45f5f
Optimization Enabled:Yes with 99999 runs
Other Settings:default evmVersionContract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {Proxy} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradables/Proxy.sol"; contract SquidRouterProxy is Proxy { function contractId() internal pure override returns (bytes32 id) { id = keccak256("squid-router"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import './IUpgradable.sol'; // This should be owned by the microservice that is paying for gas. interface IAxelarGasService is IUpgradable { error NothingReceived(); error TransferFailed(); error InvalidAddress(); event GasPaidForContractCall( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, address gasToken, uint256 gasFeeAmount, address refundAddress ); event GasPaidForContractCallWithToken( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, string symbol, uint256 amount, address gasToken, uint256 gasFeeAmount, address refundAddress ); event NativeGasPaidForContractCall( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, uint256 gasFeeAmount, address refundAddress ); event NativeGasPaidForContractCallWithToken( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, string symbol, uint256 amount, uint256 gasFeeAmount, address refundAddress ); event GasAdded(bytes32 indexed txHash, uint256 indexed logIndex, address gasToken, uint256 gasFeeAmount, address refundAddress); event NativeGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress); // This is called on the source chain before calling the gateway to execute a remote contract. function payGasForContractCall( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, address gasToken, uint256 gasFeeAmount, address refundAddress ) external; // This is called on the source chain before calling the gateway to execute a remote contract. function payGasForContractCallWithToken( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, string calldata symbol, uint256 amount, address gasToken, uint256 gasFeeAmount, address refundAddress ) external; // This is called on the source chain before calling the gateway to execute a remote contract. function payNativeGasForContractCall( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, address refundAddress ) external payable; // This is called on the source chain before calling the gateway to execute a remote contract. function payNativeGasForContractCallWithToken( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, string calldata symbol, uint256 amount, address refundAddress ) external payable; function addGas( bytes32 txHash, uint256 txIndex, address gasToken, uint256 gasFeeAmount, address refundAddress ) external; function addNativeGas( bytes32 txHash, uint256 logIndex, address refundAddress ) external payable; function collectFees(address payable receiver, address[] calldata tokens) external; function refund( address payable receiver, address token, uint256 amount ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; // General interface for upgradable contracts interface IUpgradable { error NotOwner(); error InvalidOwner(); error InvalidCodeHash(); error InvalidImplementation(); error SetupFailed(); error NotProxy(); event Upgraded(address indexed newImplementation); event OwnershipTransferred(address indexed newOwner); // Get current owner function owner() external view returns (address); function contractId() external pure returns (bytes32); function implementation() external view returns (address); function upgrade( address newImplementation, bytes32 newImplementationCodeHash, bytes calldata params ) external; function setup(bytes calldata data) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol'; import { IERC20 } from '../interfaces/IERC20.sol'; import { IAxelarForecallable } from '../interfaces/IAxelarForecallable.sol'; contract AxelarForecallable is IAxelarForecallable { IAxelarGateway public immutable gateway; //keccak256('forecallers'); uint256 public constant FORECALLERS_SALT = 0xdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f; constructor(address gateway_) { if (gateway_ == address(0)) revert InvalidAddress(); gateway = IAxelarGateway(gateway_); } function getForecaller( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) public view override returns (address forecaller) { bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, FORECALLERS_SALT)); // solhint-disable-next-line no-inline-assembly assembly { forecaller := sload(pos) } } function _setForecaller( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, address forecaller ) internal { bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, FORECALLERS_SALT)); // solhint-disable-next-line no-inline-assembly assembly { sstore(pos, forecaller) } } function forecall( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external { _checkForecall(sourceChain, sourceAddress, payload, msg.sender); if (getForecaller(sourceChain, sourceAddress, payload) != address(0)) revert AlreadyForecalled(); _setForecaller(sourceChain, sourceAddress, payload, msg.sender); _execute(sourceChain, sourceAddress, payload); } function execute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external override { bytes32 payloadHash = keccak256(payload); if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash)) revert NotApprovedByGateway(); address forecaller = getForecaller(sourceChain, sourceAddress, payload); if (forecaller != address(0)) { _setForecaller(sourceChain, sourceAddress, payload, address(0)); } else { _execute(sourceChain, sourceAddress, payload); } } function getForecallerWithToken( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata symbol, uint256 amount ) public view override returns (address forecaller) { bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, symbol, amount, FORECALLERS_SALT)); // solhint-disable-next-line no-inline-assembly assembly { forecaller := sload(pos) } } function _setForecallerWithToken( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata symbol, uint256 amount, address forecaller ) internal { bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, symbol, amount, FORECALLERS_SALT)); // solhint-disable-next-line no-inline-assembly assembly { sstore(pos, forecaller) } } function forecallWithToken( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata tokenSymbol, uint256 amount ) external override { address token = gateway.tokenAddresses(tokenSymbol); uint256 amountPost = amountPostFee(amount, payload); _safeTransferFrom(token, msg.sender, amountPost); _checkForecallWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, msg.sender); if (getForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount) != address(0)) revert AlreadyForecalled(); _setForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, msg.sender); _executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amountPost); } function executeWithToken( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata tokenSymbol, uint256 amount ) external override { bytes32 payloadHash = keccak256(payload); if ( !gateway.validateContractCallAndMint( commandId, sourceChain, sourceAddress, payloadHash, tokenSymbol, amount ) ) revert NotApprovedByGateway(); address forecaller = getForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount); if (forecaller != address(0)) { _setForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, address(0)); address token = gateway.tokenAddresses(tokenSymbol); _safeTransfer(token, forecaller, amount); } else { _executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount); } } function _execute( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) internal virtual {} function _executeWithToken( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata tokenSymbol, uint256 amount ) internal virtual {} // Override this to keep a fee. function amountPostFee( uint256 amount, bytes calldata /*payload*/ ) public virtual override returns (uint256) { return amount; } // Override this and revert if you want to only allow certain people/calls to be able to forecall. function _checkForecall( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, address forecaller ) internal virtual {} // Override this and revert if you want to only allow certain people/calls to be able to forecall. function _checkForecallWithToken( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata tokenSymbol, uint256 amount, address forecaller ) internal virtual {} function _safeTransfer( address tokenAddress, address receiver, uint256 amount ) internal { (bool success, bytes memory returnData) = tokenAddress.call( abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount) ); bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || tokenAddress.code.length == 0) revert TransferFailed(); } function _safeTransferFrom( address tokenAddress, address from, uint256 amount ) internal { (bool success, bytes memory returnData) = tokenAddress.call( abi.encodeWithSelector(IERC20.transferFrom.selector, from, address(this), amount) ); bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || tokenAddress.code.length == 0) revert TransferFailed(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol'; interface IAxelarExecutable { error InvalidAddress(); error NotApprovedByGateway(); function gateway() external view returns (IAxelarGateway); function execute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external; function executeWithToken( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata tokenSymbol, uint256 amount ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol'; interface IAxelarForecallable is IAxelarExecutable { error AlreadyForecalled(); error TransferFailed(); function forecall( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external; function forecallWithToken( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata tokenSymbol, uint256 amount ) external; function getForecaller( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external returns (address forecaller); function getForecallerWithToken( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata symbol, uint256 amount ) external returns (address forecaller); function amountPostFee(uint256 amount, bytes calldata payload) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IAxelarGateway { /**********\ |* Errors *| \**********/ error NotSelf(); error NotProxy(); error InvalidCodeHash(); error SetupFailed(); error InvalidAuthModule(); error InvalidTokenDeployer(); error InvalidAmount(); error InvalidChainId(); error InvalidCommands(); error TokenDoesNotExist(string symbol); error TokenAlreadyExists(string symbol); error TokenDeployFailed(string symbol); error TokenContractDoesNotExist(address token); error BurnFailed(string symbol); error MintFailed(string symbol); error InvalidSetMintLimitsParams(); error ExceedMintLimit(string symbol); /**********\ |* Events *| \**********/ event TokenSent( address indexed sender, string destinationChain, string destinationAddress, string symbol, uint256 amount ); event ContractCall( address indexed sender, string destinationChain, string destinationContractAddress, bytes32 indexed payloadHash, bytes payload ); event ContractCallWithToken( address indexed sender, string destinationChain, string destinationContractAddress, bytes32 indexed payloadHash, bytes payload, string symbol, uint256 amount ); event Executed(bytes32 indexed commandId); event TokenDeployed(string symbol, address tokenAddresses); event ContractCallApproved( bytes32 indexed commandId, string sourceChain, string sourceAddress, address indexed contractAddress, bytes32 indexed payloadHash, bytes32 sourceTxHash, uint256 sourceEventIndex ); event ContractCallApprovedWithMint( bytes32 indexed commandId, string sourceChain, string sourceAddress, address indexed contractAddress, bytes32 indexed payloadHash, string symbol, uint256 amount, bytes32 sourceTxHash, uint256 sourceEventIndex ); event TokenMintLimitUpdated(string symbol, uint256 limit); event OperatorshipTransferred(bytes newOperatorsData); event Upgraded(address indexed implementation); /********************\ |* Public Functions *| \********************/ function sendToken( string calldata destinationChain, string calldata destinationAddress, string calldata symbol, uint256 amount ) external; function callContract( string calldata destinationChain, string calldata contractAddress, bytes calldata payload ) external; function callContractWithToken( string calldata destinationChain, string calldata contractAddress, bytes calldata payload, string calldata symbol, uint256 amount ) external; function isContractCallApproved( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, address contractAddress, bytes32 payloadHash ) external view returns (bool); function isContractCallAndMintApproved( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, address contractAddress, bytes32 payloadHash, string calldata symbol, uint256 amount ) external view returns (bool); function validateContractCall( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash ) external returns (bool); function validateContractCallAndMint( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash, string calldata symbol, uint256 amount ) external returns (bool); /***********\ |* Getters *| \***********/ function authModule() external view returns (address); function tokenDeployer() external view returns (address); function tokenMintLimit(string memory symbol) external view returns (uint256); function tokenMintAmount(string memory symbol) external view returns (uint256); function allTokensFrozen() external view returns (bool); function implementation() external view returns (address); function tokenAddresses(string memory symbol) external view returns (address); function tokenFrozen(string memory symbol) external view returns (bool); function isCommandExecuted(bytes32 commandId) external view returns (bool); function adminEpoch() external view returns (uint256); function adminThreshold(uint256 epoch) external view returns (uint256); function admins(uint256 epoch) external view returns (address[] memory); /*******************\ |* Admin Functions *| \*******************/ function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external; function upgrade( address newImplementation, bytes32 newImplementationCodeHash, bytes calldata setupParams ) external; /**********************\ |* External Functions *| \**********************/ function setup(bytes calldata params) external; function execute(bytes calldata input) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { error InvalidAccount(); /** * @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; // General interface for upgradable contracts interface IUpgradable { error NotOwner(); error InvalidOwner(); error InvalidCodeHash(); error InvalidImplementation(); error SetupFailed(); error NotProxy(); event Upgraded(address indexed newImplementation); event OwnershipTransferred(address indexed newOwner); // Get current owner function owner() external view returns (address); function contractId() external pure returns (bytes32); function upgrade( address newImplementation, bytes32 newImplementationCodeHash, bytes calldata params ) external; function setup(bytes calldata data) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library StringToAddress { function toAddress(string memory _a) internal pure returns (address) { bytes memory tmp = bytes(_a); if (tmp.length != 42) return address(0); uint160 iaddr = 0; uint8 b; for (uint256 i = 2; i < 42; i++) { b = uint8(tmp[i]); if ((b >= 97) && (b <= 102)) b -= 87; else if ((b >= 65) && (b <= 70)) b -= 55; else if ((b >= 48) && (b <= 57)) b -= 48; else return address(0); iaddr |= uint160(uint256(b) << ((41 - i) << 2)); } return address(iaddr); } } library AddressToString { function toString(address a) internal pure returns (string memory) { bytes memory data = abi.encodePacked(a); bytes memory characters = '0123456789abcdef'; bytes memory byteString = new bytes(2 + data.length * 2); byteString[0] = '0'; byteString[1] = 'x'; for (uint256 i; i < data.length; ++i) { byteString[2 + i * 2] = characters[uint256(uint8(data[i] >> 4))]; byteString[3 + i * 2] = characters[uint256(uint8(data[i] & 0x0f))]; } return string(byteString); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IUpgradable } from '../interfaces/IUpgradable.sol'; contract Proxy { error InvalidImplementation(); error SetupFailed(); error EtherNotAccepted(); error NotOwner(); error AlreadyInitialized(); // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; // keccak256('owner') bytes32 internal constant _OWNER_SLOT = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0; constructor() { // solhint-disable-next-line no-inline-assembly assembly { sstore(_OWNER_SLOT, caller()) } } function init( address implementationAddress, address newOwner, bytes memory params ) external { address owner; // solhint-disable-next-line no-inline-assembly assembly { owner := sload(_OWNER_SLOT) } if (msg.sender != owner) revert NotOwner(); if (implementation() != address(0)) revert AlreadyInitialized(); if (IUpgradable(implementationAddress).contractId() != contractId()) revert InvalidImplementation(); // solhint-disable-next-line no-inline-assembly assembly { sstore(_IMPLEMENTATION_SLOT, implementationAddress) sstore(_OWNER_SLOT, newOwner) } // solhint-disable-next-line avoid-low-level-calls (bool success, ) = implementationAddress.delegatecall( //0x9ded06df is the setup selector. abi.encodeWithSelector(0x9ded06df, params) ); if (!success) revert SetupFailed(); } // solhint-disable-next-line no-empty-blocks function contractId() internal pure virtual returns (bytes32) {} function implementation() public view returns (address implementation_) { // solhint-disable-next-line no-inline-assembly assembly { implementation_ := sload(_IMPLEMENTATION_SLOT) } } // solhint-disable-next-line no-empty-blocks function setup(bytes calldata data) public {} // solhint-disable-next-line no-complex-fallback fallback() external payable { address implementaion_ = implementation(); // solhint-disable-next-line no-inline-assembly assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), implementaion_, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } receive() external payable virtual { revert EtherNotAccepted(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../interfaces/IUpgradable.sol'; abstract contract Upgradable is IUpgradable { // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; // keccak256('owner') bytes32 internal constant _OWNER_SLOT = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0; modifier onlyOwner() { if (owner() != msg.sender) revert NotOwner(); _; } function owner() public view returns (address owner_) { // solhint-disable-next-line no-inline-assembly assembly { owner_ := sload(_OWNER_SLOT) } } function transferOwnership(address newOwner) external virtual onlyOwner { if (newOwner == address(0)) revert InvalidOwner(); emit OwnershipTransferred(newOwner); // solhint-disable-next-line no-inline-assembly assembly { sstore(_OWNER_SLOT, newOwner) } } function implementation() public view returns (address implementation_) { // solhint-disable-next-line no-inline-assembly assembly { implementation_ := sload(_IMPLEMENTATION_SLOT) } } function upgrade( address newImplementation, bytes32 newImplementationCodeHash, bytes calldata params ) external override onlyOwner { if (IUpgradable(newImplementation).contractId() != IUpgradable(this).contractId()) revert InvalidImplementation(); if (newImplementationCodeHash != newImplementation.codehash) revert InvalidCodeHash(); if (params.length > 0) { // solhint-disable-next-line avoid-low-level-calls (bool success, ) = newImplementation.delegatecall(abi.encodeWithSelector(this.setup.selector, params)); if (!success) revert SetupFailed(); } emit Upgraded(newImplementation); // solhint-disable-next-line no-inline-assembly assembly { sstore(_IMPLEMENTATION_SLOT, newImplementation) } } function setup(bytes calldata data) external override { // Prevent setup from being called on the implementation if (implementation() == address(0)) revert NotProxy(); _setup(data); } // solhint-disable-next-line no-empty-blocks function _setup(bytes calldata data) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
pragma solidity >=0.6.2; interface IPangolinRouter { function factory() external pure returns (address); function WAVAX() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityAVAX( address token, uint amountTokenDesired, uint amountTokenMin, uint amountAVAXMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountAVAX, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityAVAX( address token, uint liquidity, uint amountTokenMin, uint amountAVAXMin, address to, uint deadline ) external returns (uint amountToken, uint amountAVAX); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityAVAXWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountAVAXMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountAVAX); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactAVAXForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactAVAX(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForAVAX(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapAVAXForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); function removeLiquidityAVAXSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountAVAXMin, address to, uint deadline ) external returns (uint amountAVAX); function removeLiquidityAVAXWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountAVAXMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountAVAX); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactAVAXForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForAVAXSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity >0.0.0; import '@pangolindex/exchange-contracts/contracts/pangolin-periphery/interfaces/IPangolinRouter.sol';
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IRoledPausable { event PauserProposed(address indexed currentPauser, address indexed pendingPauser); event PauserUpdated(address indexed pendingPauser); event Paused(); event Unpaused(); error ContractIsPaused(); error NotPauser(); error NotPendingPauser(); function updatePauser(address _newPauser) external; function acceptPauser() external; function pause() external; function unpause() external; function paused() external view returns (bool value); function pauser() external view returns (address value); function pendingPauser() external view returns (address value); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface ISquidFeeCollector { event FeeCollected(address token, address integrator, uint256 squidFee, uint256 integratorFee); event FeeWithdrawn(address token, address account, uint256 amount); error TransferFailed(); error ExcessiveIntegratorFee(); function collectFee( address token, uint256 amountToTax, address integratorAddress, uint256 integratorFee ) external; function withdrawFee(address token) external; function getBalance(address token, address account) external view returns (uint256 accountBalance); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface ISquidMulticall { enum CallType { Default, FullTokenBalance, FullNativeBalance, CollectTokenBalance } struct Call { CallType callType; address target; uint256 value; bytes callData; bytes payload; } error AlreadyRunning(); error CallFailed(uint256 callPosition, bytes reason); function run(Call[] calldata calls) external payable; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ISquidMulticall} from "./ISquidMulticall.sol"; interface ISquidRouter { event CrossMulticallExecuted(bytes32 indexed payloadHash); event CrossMulticallFailed(bytes32 indexed payloadHash, bytes reason, address indexed refundRecipient); function bridgeCall( string calldata destinationChain, string calldata bridgedTokenSymbol, uint256 amount, ISquidMulticall.Call[] calldata calls, address refundRecipient, bool forecallEnabled ) external payable; function callBridge( address token, uint256 amount, string calldata destinationChain, string calldata destinationAddress, string calldata bridgedTokenSymbol, ISquidMulticall.Call[] calldata calls ) external payable; function callBridgeCall( address token, uint256 amount, string calldata destinationChain, string calldata bridgedTokenSymbol, ISquidMulticall.Call[] calldata sourceCalls, ISquidMulticall.Call[] calldata destinationCalls, address refundRecipient, bool forecallEnabled ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library StorageSlot { function setUint256(bytes32 slot, uint256 value) internal { assembly { sstore(slot, value) } } function getUint256(bytes32 slot) internal view returns (uint256 value) { assembly { value := sload(slot) } } function setAddress(bytes32 slot, address value) internal { assembly { sstore(slot, value) } } function getAddress(bytes32 slot) internal view returns (address value) { assembly { value := sload(slot) } } function setBool(bytes32 slot, bool value) internal { assembly { sstore(slot, value) } } function getBool(bytes32 slot) internal view returns (bool value) { assembly { value := sload(slot) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IRoledPausable} from "./interfaces/IRoledPausable.sol"; import {StorageSlot} from "./libraries/StorageSlot.sol"; abstract contract RoledPausable is IRoledPausable { using StorageSlot for bytes32; bytes32 internal constant PAUSED_SLOT = keccak256("RoledPausable.paused"); bytes32 internal constant PAUSER_SLOT = keccak256("RoledPausable.pauser"); bytes32 internal constant PENDING_PAUSER_SLOT = keccak256("RoledPausable.pendingPauser"); modifier whenNotPaused() { if (paused()) revert ContractIsPaused(); _; } modifier onlyPauser() { if (msg.sender != pauser()) revert NotPauser(); _; } constructor() { _setPauser(msg.sender); } function updatePauser(address newPauser) external onlyPauser { PENDING_PAUSER_SLOT.setAddress(newPauser); emit PauserProposed(msg.sender, newPauser); } function acceptPauser() external { if (msg.sender != pendingPauser()) revert NotPendingPauser(); _setPauser(msg.sender); PENDING_PAUSER_SLOT.setAddress(address(0)); } function pause() external virtual onlyPauser { PAUSED_SLOT.setBool(true); emit Paused(); } function unpause() external virtual onlyPauser { PAUSED_SLOT.setBool(false); emit Unpaused(); } function pauser() public view returns (address value) { value = PAUSER_SLOT.getAddress(); } function paused() public view returns (bool value) { value = PAUSED_SLOT.getBool(); } function pendingPauser() public view returns (address value) { value = PENDING_PAUSER_SLOT.getAddress(); } function _setPauser(address _pauser) internal { PAUSER_SLOT.setAddress(_pauser); emit PauserUpdated(_pauser); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {Upgradable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradables/Upgradable.sol"; import {ISquidFeeCollector} from "./interfaces/ISquidFeeCollector.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract SquidFeeCollector is ISquidFeeCollector, Upgradable { bytes32 private constant BALANCES_PREFIX = keccak256("SquidFeeCollector.balances"); bytes32 private constant SPECIFIC_FEES_PREFIX = keccak256("SquidFeeCollector.specificFees"); address public immutable squidTeam; // Value expected with 2 decimals /// eg. 825 is 8.25% uint256 public immutable squidDefaultFee; error ZeroAddressProvided(); constructor(address _squidTeam, uint256 _squidDefaultFee) { if (_squidTeam == address(0)) revert ZeroAddressProvided(); squidTeam = _squidTeam; squidDefaultFee = _squidDefaultFee; } /// @param integratorFee Value expected with 2 decimals /// eg. 825 is 8.25% function collectFee( address token, uint256 amountToTax, address integratorAddress, uint256 integratorFee ) external { if (integratorFee > 1000) revert ExcessiveIntegratorFee(); uint256 specificFee = getSpecificFee(integratorAddress); uint256 squidFee = specificFee == 0 ? squidDefaultFee : specificFee; uint256 baseFeeAmount = (amountToTax * integratorFee) / 10000; uint256 squidFeeAmount = (baseFeeAmount * squidFee) / 10000; uint256 integratorFeeAmount = baseFeeAmount - squidFeeAmount; _safeTransferFrom(token, msg.sender, baseFeeAmount); _setBalance(token, squidTeam, getBalance(token, squidTeam) + squidFeeAmount); _setBalance(token, integratorAddress, getBalance(token, integratorAddress) + integratorFeeAmount); emit FeeCollected(token, integratorAddress, squidFeeAmount, integratorFeeAmount); } function withdrawFee(address token) external { uint256 balance = getBalance(token, msg.sender); _setBalance(token, msg.sender, 0); _safeTransfer(token, msg.sender, balance); emit FeeWithdrawn(token, msg.sender, balance); } function setSpecificFee(address integrator, uint256 fee) external onlyOwner { bytes32 slot = _computeSpecificFeeSlot(integrator); assembly { sstore(slot, fee) } } function getBalance(address token, address account) public view returns (uint256 value) { bytes32 slot = _computeBalanceSlot(token, account); assembly { value := sload(slot) } } function getSpecificFee(address integrator) public view returns (uint256 value) { bytes32 slot = _computeSpecificFeeSlot(integrator); assembly { value := sload(slot) } } function contractId() external pure returns (bytes32 id) { id = keccak256("squid-fee-collector"); } function _setBalance( address token, address account, uint256 amount ) private { bytes32 slot = _computeBalanceSlot(token, account); assembly { sstore(slot, amount) } } function _computeBalanceSlot(address token, address account) private pure returns (bytes32 slot) { slot = keccak256(abi.encodePacked(BALANCES_PREFIX, token, account)); } function _computeSpecificFeeSlot(address integrator) private pure returns (bytes32 slot) { slot = keccak256(abi.encodePacked(SPECIFIC_FEES_PREFIX, integrator)); } function _safeTransferFrom( address token, address from, uint256 amount ) internal { (bool success, bytes memory returnData) = token.call( abi.encodeWithSelector(IERC20.transferFrom.selector, from, address(this), amount) ); bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || token.code.length == 0) revert TransferFailed(); } function _safeTransfer( address token, address to, uint256 amount ) internal { (bool success, bytes memory returnData) = token.call( abi.encodeWithSelector(IERC20.transfer.selector, to, amount) ); bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || token.code.length == 0) revert TransferFailed(); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {Proxy} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradables/Proxy.sol"; contract SquidFeeCollectorProxy is Proxy { function contractId() internal pure override returns (bytes32 id) { id = keccak256("squid-fee-collector"); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ISquidMulticall} from "./interfaces/ISquidMulticall.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract SquidMulticall is ISquidMulticall { bool private isRunning; error TransferFailed(); function run(Call[] calldata calls) external payable { // Prevents reentrancy if (isRunning) revert AlreadyRunning(); isRunning = true; for (uint256 i = 0; i < calls.length; i++) { Call memory call = calls[i]; if (call.callType == CallType.FullTokenBalance) { (address token, uint256 amountParameterPosition) = abi.decode(call.payload, (address, uint256)); uint256 amount = IERC20(token).balanceOf(address(this)); _setCallDataParameter(call.callData, amountParameterPosition, amount); } else if (call.callType == CallType.FullNativeBalance) { call.value = address(this).balance; } else if (call.callType == CallType.CollectTokenBalance) { address token = abi.decode(call.payload, (address)); _safeTransferFrom(token, msg.sender, IERC20(token).balanceOf(msg.sender)); continue; } (bool success, bytes memory data) = call.target.call{value: call.value}(call.callData); if (!success) revert CallFailed(i, data); } isRunning = false; } function _safeTransferFrom( address token, address from, uint256 amount ) internal { (bool success, bytes memory returnData) = token.call( abi.encodeWithSelector(IERC20.transferFrom.selector, from, address(this), amount) ); bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || token.code.length == 0) revert TransferFailed(); } function _setCallDataParameter( bytes memory callData, uint256 parameterPosition, uint256 value ) private pure { assembly { // 36 bytes shift because 32 for prefix + 4 for selector mstore(add(callData, add(36, mul(parameterPosition, 32))), value) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ISquidRouter} from "./interfaces/ISquidRouter.sol"; import {ISquidMulticall} from "./interfaces/ISquidMulticall.sol"; import {AxelarForecallable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/executables/AxelarForecallable.sol"; import {IAxelarGasService} from "@axelar-network/axelar-cgp-solidity/contracts/interfaces/IAxelarGasService.sol"; import {IAxelarGateway} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol"; import {AddressToString} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/StringAddressUtils.sol"; import {Upgradable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradables/Upgradable.sol"; import {RoledPausable} from "./RoledPausable.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract SquidRouter is ISquidRouter, AxelarForecallable, Upgradable, RoledPausable { using AddressToString for address; IAxelarGasService private immutable gasService; IAxelarGasService private immutable forecallGasService; ISquidMulticall private immutable squidMulticall; error ZeroAddressProvided(); constructor( address _gateway, address _gasService, address _forecallGasService, address _multicall ) AxelarForecallable(_gateway) { if ( _gateway == address(0) || _gasService == address(0) || _forecallGasService == address(0) || _multicall == address(0) ) revert ZeroAddressProvided(); gasService = IAxelarGasService(_gasService); forecallGasService = IAxelarGasService(_forecallGasService); squidMulticall = ISquidMulticall(_multicall); } function bridgeCall( string calldata destinationChain, string calldata bridgedTokenSymbol, uint256 amount, ISquidMulticall.Call[] calldata calls, address refundRecipient, bool enableForecall ) external payable whenNotPaused { address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol); _safeTransferFrom(bridgedTokenAddress, msg.sender, amount); _bridgeCall(destinationChain, bridgedTokenSymbol, bridgedTokenAddress, calls, refundRecipient, enableForecall); } function callBridge( address token, uint256 amount, string calldata destinationChain, string calldata destinationAddress, string calldata bridgedTokenSymbol, ISquidMulticall.Call[] calldata calls ) external payable whenNotPaused { fundAndRunMulticall(token, amount, calls); address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol); uint256 bridgedTokenAmount = IERC20(bridgedTokenAddress).balanceOf(address(this)); _approve(bridgedTokenAddress, address(gateway), bridgedTokenAmount); gateway.sendToken(destinationChain, destinationAddress, bridgedTokenSymbol, bridgedTokenAmount); } function callBridgeCall( address token, uint256 amount, string calldata destinationChain, string calldata bridgedTokenSymbol, ISquidMulticall.Call[] calldata sourceCalls, ISquidMulticall.Call[] calldata destinationCalls, address refundRecipient, bool enableForecall ) external payable whenNotPaused { fundAndRunMulticall(token, amount, sourceCalls); address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol); _bridgeCall( destinationChain, bridgedTokenSymbol, bridgedTokenAddress, destinationCalls, refundRecipient, enableForecall ); } function contractId() external pure override returns (bytes32 id) { id = keccak256("squid-router"); } function fundAndRunMulticall( address token, uint256 amount, ISquidMulticall.Call[] memory calls ) public payable whenNotPaused { uint256 valueToSend; if (token == address(0)) { valueToSend = amount; } else { _transferTokenToMulticall(token, amount); } squidMulticall.run{value: valueToSend}(calls); } function _executeWithToken( string calldata, string calldata, bytes calldata payload, string calldata bridgedTokenSymbol, uint256 ) internal override { (ISquidMulticall.Call[] memory calls, address refundRecipient) = abi.decode( payload, (ISquidMulticall.Call[], address) ); address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol); uint256 contractBalance = IERC20(bridgedTokenAddress).balanceOf(address(this)); _approve(bridgedTokenAddress, address(squidMulticall), contractBalance); try squidMulticall.run(calls) { emit CrossMulticallExecuted(keccak256(payload)); } catch (bytes memory reason) { // Refund tokens to refund recepient if swap fails _safeTransfer(bridgedTokenAddress, refundRecipient, contractBalance); emit CrossMulticallFailed(keccak256(payload), reason, refundRecipient); } } function _bridgeCall( string calldata destinationChain, string calldata bridgedTokenSymbol, address bridgedTokenAddress, ISquidMulticall.Call[] calldata calls, address refundRecipient, bool enableForecall ) private { if (refundRecipient == address(0)) revert ZeroAddressProvided(); bytes memory payload = abi.encode(calls, refundRecipient); // Only works if destination router has same address string memory destinationContractAddress = address(this).toString(); uint256 bridgedTokenBalance = IERC20(bridgedTokenAddress).balanceOf(address(this)); if (address(this).balance > 0) { IAxelarGasService executionService = enableForecall ? forecallGasService : gasService; executionService.payNativeGasForContractCallWithToken{value: address(this).balance}( address(this), destinationChain, destinationContractAddress, payload, bridgedTokenSymbol, bridgedTokenBalance, refundRecipient ); } _approve(bridgedTokenAddress, address(gateway), bridgedTokenBalance); gateway.callContractWithToken( destinationChain, destinationContractAddress, payload, bridgedTokenSymbol, bridgedTokenBalance ); } function _approve( address tokenAddress, address spender, uint256 amount ) private { if (IERC20(tokenAddress).allowance(address(this), spender) < amount) { // Not a security issue since the contract doesn't store tokens IERC20(tokenAddress).approve(spender, type(uint256).max); } } function _transferTokenToMulticall(address token, uint256 amount) private { (bool success, bytes memory returnData) = token.call( abi.encodeWithSelector(IERC20.transferFrom.selector, msg.sender, address(squidMulticall), amount) ); bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || token.code.length == 0) revert TransferFailed(); } function _setup(bytes calldata data) internal override { address _pauser = abi.decode(data, (address)); if (_pauser == address(0)) revert("Invalid pauser address"); _setPauser(_pauser); } }
{ "optimizer": { "enabled": true, "runs": 99999 }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
[{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"EtherNotAccepted","type":"error"},{"inputs":[],"name":"InvalidImplementation","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"SetupFailed","type":"error"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"implementationAddress","type":"address"},{"internalType":"address","name":"newOwner","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6080806040523461003957337f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05561069a908161003f8239f35b600080fdfe6080604052600436101561002c575b361561001f575b61001d6105f7565b005b610027610639565b610015565b6000803560e01c908163378dfd8e1461006b575080635c60da1b1461006257639ded06df0361000e5761005d61029f565b61000e565b5061005d61022d565b346101185760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610118576100a261011b565b6100aa610143565b6044359067ffffffffffffffff8211610114573660238301121561011457816004013592846100d8856101e4565b936100e66040519586610196565b8585523660248783010111610110578561010d9660246020930183880137850101526103b8565b80f35b5080fd5b8380fd5b80fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361013e57565b600080fd5b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361013e57565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176101d757604052565b6101df610166565b604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610220575b01160190565b610228610166565b61021a565b503461013e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261013e5760207f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461013e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261013e5760043567ffffffffffffffff80821161013e573660238301121561013e57816004013590811161013e573691016024011161013e57005b9081602091031261013e575190565b506040513d6000823e3d90fd5b60208082528251818301819052939260005b858110610374575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006040809697860101520116010190565b818101830151848201604001528201610334565b3d156103b3573d90610399826101e4565b916103a76040519384610196565b82523d6000602084013e565b606090565b91909173ffffffffffffffffffffffffffffffffffffffff917f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0938385541633036105cd577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc93808554166105a357600460207fc097d45e5a99ca772ab5ec2e5457c2e249760944b95b0b97cbb6b03ec55bae8492604051928380927f8291286c00000000000000000000000000000000000000000000000000000000825289165afa908115610596575b600091610568575b500361053e576000948386955555604051610500816104d460208201947f9ded06df00000000000000000000000000000000000000000000000000000000865260248301610322565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610196565b51915af461050c610388565b501561051457565b60046040517f97905dfb000000000000000000000000000000000000000000000000000000008152fd5b60046040517f68155f9a000000000000000000000000000000000000000000000000000000008152fd5b610589915060203d811161058f575b6105818183610196565b810190610306565b3861048b565b503d610577565b61059e610315565b610483565b60046040517f0dc149f0000000000000000000000000000000000000000000000000000000008152fd5b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546000808092368280378136915af43d82803e15610635573d90f35b3d90fd5b5060046040517f37334834000000000000000000000000000000000000000000000000000000008152fdfea26469706673582212205a1ae4e4554ee5e5b30712df541f3571c30f56cc0963334dec2abbb4f5176f4d64736f6c63430008110033Deployed Bytecode
0x6080604052600436101561002c575b361561001f575b61001d6105f7565b005b610027610639565b610015565b6000803560e01c908163378dfd8e1461006b575080635c60da1b1461006257639ded06df0361000e5761005d61029f565b61000e565b5061005d61022d565b346101185760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610118576100a261011b565b6100aa610143565b6044359067ffffffffffffffff8211610114573660238301121561011457816004013592846100d8856101e4565b936100e66040519586610196565b8585523660248783010111610110578561010d9660246020930183880137850101526103b8565b80f35b5080fd5b8380fd5b80fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361013e57565b600080fd5b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361013e57565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176101d757604052565b6101df610166565b604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610220575b01160190565b610228610166565b61021a565b503461013e5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261013e5760207f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461013e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261013e5760043567ffffffffffffffff80821161013e573660238301121561013e57816004013590811161013e573691016024011161013e57005b9081602091031261013e575190565b506040513d6000823e3d90fd5b60208082528251818301819052939260005b858110610374575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006040809697860101520116010190565b818101830151848201604001528201610334565b3d156103b3573d90610399826101e4565b916103a76040519384610196565b82523d6000602084013e565b606090565b91909173ffffffffffffffffffffffffffffffffffffffff917f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0938385541633036105cd577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc93808554166105a357600460207fc097d45e5a99ca772ab5ec2e5457c2e249760944b95b0b97cbb6b03ec55bae8492604051928380927f8291286c00000000000000000000000000000000000000000000000000000000825289165afa908115610596575b600091610568575b500361053e576000948386955555604051610500816104d460208201947f9ded06df00000000000000000000000000000000000000000000000000000000865260248301610322565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610196565b51915af461050c610388565b501561051457565b60046040517f97905dfb000000000000000000000000000000000000000000000000000000008152fd5b60046040517f68155f9a000000000000000000000000000000000000000000000000000000008152fd5b610589915060203d811161058f575b6105818183610196565b810190610306565b3861048b565b503d610577565b61059e610315565b610483565b60046040517f0dc149f0000000000000000000000000000000000000000000000000000000008152fd5b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546000808092368280378136915af43d82803e15610635573d90f35b3d90fd5b5060046040517f37334834000000000000000000000000000000000000000000000000000000008152fdfea26469706673582212205a1ae4e4554ee5e5b30712df541f3571c30f56cc0963334dec2abbb4f5176f4d64736f6c63430008110033
Loading...LoadingLoading...LoadingABI for the implementation contract at 0xf46cfea9481fb6b0d84953e956d51a6ea7b5658d, using the EIP-1967 Transparent Proxy pattern.
Previously recorded to be on 0x0c05bbc439c59861ebc7d504b5d74d2701f91e62.Learn more about proxy contracts in our Knowledge Base
Loading...LoadingABI for the implementation contract at 0xf46cfea9481fb6b0d84953e956d51a6ea7b5658d, using the EIP-1967 Transparent Proxy pattern.
Previously recorded to be on 0x0c05bbc439c59861ebc7d504b5d74d2701f91e62.Learn more about proxy contracts in our Knowledge Base
Loading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...Loading[ Download: CSV Export ][ Download: CSV Export ]A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.
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) 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.Notice
Maintenance in progress, block data might not be up to date
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.