20M+ users trust MoonPay worldwide. Checkout with your preferred payment method.
Ready to onboard to Ethereum? With MetaMask Portfolio, you're in control.
Don’t invest unless you’re prepared to lose all the money you invest.
Everyday giveaways up to 100 ETH, Lucky Spins. Deposit BONUS 300% and Cashbacks!
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
Slots, Roulette, Poker & more - Proud sponsors of UFC, Everton & StakeF1 team!
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
Anonymous play on awesome games - sign up now for 25 free jackpot spins - worth $100s!
100s of games, generous bonuses, 20+ years of trusted gaming. Join CryptoWins & start winning today!
Overview
ETH Balance
Eth Value
$0.00Token Holdings
Could not find any matches!
- ERC-20 Tokens (>200)0 AGLDAdventure Go... (AGLD)$0.00@1.37470 ABONDApeBond (ABOND)$0.00@0.00480.00064992 DNODEDecentraNode (DNODE)$0.00@1.960 ICSAIcosa (ICSA)$0.00@0.136256.29555877 MAZZEMAZZE (MAZZE)$0.11@0.00190.00000059 STRDYSturdy Token (STRDY)$0.00@3.09138,511.97409798 PODThe Other Pa... (POD)$0.00@0.000.00000001 VECVector (VEC)$0.00@1.560 WSMWall Street ... (WSM)$0.00@0.001210 WEBAIWebsite AI (WEBAI)1.59234843 OxN0xNumber (OxN)$0.03@0.01670 1INCH1INCH Token (1INCH)$0.00@0.36430.00000001 BAKE404 Bakery (BAKE)$0.00@0.00070 AAVEAave Token (AAVE)$0.00@179.350.25790393 AEVOAevo (AEVO)$0.10@0.38170.02336907 AGRSAgoras Token (AGRS)$0.04@1.650 AINAI Network (AIN)$0.00@0.00760 AIOZAIOZ Network (AIOZ)$0.00@0.81730 NXRAAllianceBloc... (NXRA)$0.00@0.03220 ALTAltLayer Tok... (ALT)$0.00@0.12140 AMOAmino (AMO)$0.00@0.00020.00005669 AMMXAMMX (AMMX)$0.00@0.00041.8547577 ANGLEANGLE (ANGLE)$0.04@0.02310 ANKRAnkr Network (ANKR)$0.00@0.03690 ankrETHAnkr Staked ... (ankrET...)$0.00@3,947.920 APEApeCoin (APE)$0.00@1.240 APUAPU (APU)$0.00@0.000.00001463 APUFFAPUFF (APUFF)$0.00@0.00480.01245039 AIUSArbius (AIUS)$0.40@32.22230 ABTArcBlock (ABT)$0.00@1.350.03353718 ARCXArchitex (ARCX)$0.02@0.46990 ARIA20ARIANEE (ARIA20)$0.00@0.13180 ARKMArkham (ARKM)$0.00@2.12470 ASTXAsterix (ASTX)$0.00@639.49140.000004 AXLAxelar (AXL)$0.00@0.76170 BADGERBadger (BADGER)$0.00@3.510.00785654 BANANABanana (BANANA)$0.51@64.810 BANANABanana (BANANA)$0.00@0.26730 BDIDBDID (BDID)$0.00@0.00029.26578657 BEAMBeam (BEAM)$0.21@0.02280 BEARDYBearded Drag... (BEARDY)$0.00@0.00027,546,638.26372812 BEBEBEBE (BEBE)$0.35@0.000 FINALEBens Finale (FINALE)$0.00@0.000 BTCINUBitcoin Inu (BTCINU)$0.00@0.01680 BITBitDAO (BIT)$0.00@0.83820 BRISEBitgert (BRISE)$0.00@0.000 VEEBLOCKv (VEE)$0.00@0.0089179,937.06526123 BOBOBOBO (BOBO)$0.29@0.0012.99423724 BOTTOBotto (BOTTO)$8.31@0.63960 AuctionBounce Token (Auctio...)$0.00@14.31166.44242819 BRETTBrett (BRETT)$5.15@0.03090 BYTESBYTES (BYTES)$0.00@5.97450.005 CRECarryToken (CRE)$0.00@0.01280 CTSICartesi Toke... (CTSI)$0.00@0.16770 COBECastle of Bl... (COBE)$0.00@0.05850.46716294 FLIPChainflip (FLIP)$0.54@1.150 CHEXChintai Exch... (CHEX)$0.00@0.27850 CNDCindicator (CND)$0.00@0.00030.00000463 cbETHCoinbase Wra... (cbETH)$0.02@3,654.9841,149.03830427 CONANConan (CONAN)$0.04@0.000 CoreDAOCORE DAO (CoreDA...)$0.00@0.41870 CRETH2Cream ETH To... (CRETH2)0.00000001 CROCronos Coin (CRO)$0.00@0.18994.49802479 crvUSDCurve.Fi USD... (crvUSD)$4.48@0.99660 DXNDBXen Token (DXN)$0.00@0.66490 DIPDecentralize... (DIP)$0.00@0.01180 USDDDecentralize... (USDD)$0.00@0.99850 DWEBDecentraweb (DWEB)$0.00@0.01390 DCHFDefi Franc (DCHF)$0.00@1.150 DEVVEDevvE (DEVVE)$0.00@0.34440 DCKDexCheck (DCK)$0.00@0.0240 DGIDGI Game (DGI)$0.00@0.00040 DINODinoLFG (DINO)$0.00@0.005312.43419685 DioneDione (Dione)$0.07@0.00530 DZHVDizzyHavoc (DZHV)$0.00@0.00080 DOGE20Dogecoin20 (DOGE20)$0.00@0.000 DRGNDragon (DRGN)$0.00@0.019621,644.85031219 DBZDragonball Z... (DBZ)$0.00@0.006.5292814 DUSKDusk Network (DUSK)$1.33@0.20430 DYDXdYdX (DYDX)$0.00@1.400 EMPEmpyreal (EMP)$0.00@88.540 ENQAIenqAI (ENQAI)$0.00@0.01810.00000022 NGLEntangle (NGL)$0.00@0.10540 EPOCHEpoch (EPOCH)0 ETH2x-FLIETH 2x Flexi... (ETH2x-...)$0.00@21.01270.00000133 ENAEthena (ENA)$0.00@0.66660 eETHether.fi ETH (eETH)$0.00@3,377.480 ETHFIether.fi gov... (ETHFI)$0.00@1.951,817,157,577,619.26 EDOGEEtherDoge (EDOGE)0 OSEthereans (OS)$0.00@0.50170 ELANDEtherland (ELAND)$0.00@0.05140.00425174 ETHxETHx (ETHx)$15.09@3,548.230 EULEuler (EUL)$0.00@3.59410 EURAEURA (previo... (EURA)$0.00@1.0410 NEXTEverclear (NEXT)$0.00@0.09923.58945629 IDEverest ID (ID)$0.14@0.040.00251805 Renzo Restaked ETHezETH (Renzo ...)$8.75@3,476.010 FIFideum (FI)$0.00@0.00470.5967835 FJOFjord Foundr... (FJO)$0.37@0.61240 FLRBRGFloor Cheese... (FLRBRG)$0.00@0.000 FLCFlooring Lab... (FLC)$0.00@0.00310 FLTFluence (FLT)$0.00@0.2490 FORTForta (FORT)$0.00@0.10551.81034828 $FORWARDForward ($FORWA...)$0.00@0.00110 FRAXFrax (FRAX)$0.00@0.99680.00023824 frxETHFrax Ether (frxETH)$0.80@3,361.44980.00000007 FXSFrax Share (FXS)$0.00@2.610 FRICFrictionless (FRIC)$0.00@0.00140 FWBFriends With... (FWB)$0.00@1.48820 FUNGFung Token (FUNG)$0.00@0.011724.05634096 $MUSICGala Music ($MUSIC)$0.80@0.03320 GELGelato Netwo... (GEL)$0.00@0.21320 GHOGHO Token (GHO)$0.00@0.99710.45701638 GTCGitcoin (GTC)$0.37@0.81090.000123 GYENGMO JPY (GYEN)$0.00@0.00620 GFIGoldfinch (GFI)$0.00@1.470 GMTGoMining Tok... (GMT)$0.00@0.41060 gOHMGovernance O... (gOHM)$0.00@5,559.600 GPTGPT Protocol (GPT)$0.00@0.0030 GRTGraph Token (GRT)$0.00@0.24560.00000534 GLQGraphLinq (GLQ)$0.00@0.08030.00000102 GRAIGravita Debt... (GRAI)$0.00@0.9760 GBTCGreen Bitcoi... (GBTC)$0.00@0.24690 GROKGROK (GROK)$0.00@0.0080 HABIBIHABIBI (HABIBI)$0.00@0.000 HAIRHairDAO Toke... (HAIR)$0.00@141.360 HAMSHamsters (HAMS)0 HAIHapticAI (HAI)$0.00@0.00140 HashAIHashAI (HashAI)$0.00@0.00090 HAYHayCoin (HAY)$0.00@246,677.0024291.41615514 HELLOHello (HELLO)$5.38@0.01850.00000008 HEXHEX (HEX)$0.00@0.0031416,942,095.648852 HOKKHokkaidu Inu (HOKK)$0.00@0.000 HOPHop (HOP)$0.00@0.0193797,800.55891343 HOPPYHoppy (HOPPY)$0.00@0.000.296608 HyPCHyperCycle T... (HyPC)$0.06@0.19940 ICHIICHI (ICHI)$0.00@1.0530 IMXImmutable X (IMX)$0.00@1.530 INDEXIndex (INDEX)$0.00@3.010 INJInjective To... (INJ)$0.00@28.55350.00000453 INSInscribe (INS)$0.00@0.01680 INSPInspect (INSP)$0.00@0.04460 IPORIPOR Token (IPOR)$0.00@0.32870.36770393 IXSIxs Token (IXS)$0.14@0.38911,728.97160068 KAIJUKAIJUNO8 (KAIJU)$0.00@0.000.0000013 KARRATKarratCoin (KARRAT)$0.00@0.45650.00000003 KASKaspa (KAS)$0.00@0.1490.00000488 KEPKelp Earned ... (KEP)$0.00@0.05870 LL (L)$0.00@0.000.000006 LNDXLandX Govern... (LNDX)$0.00@0.35099.08288238 LAILayerAI Toke... (LAI)$0.13@0.01470 LCXLCX (LCX)$0.00@0.12330 LDOLido DAO Tok... (LDO)$0.00@1.290 LIF3LIF3 (LIF3)$0.00@0.01670.00003911 LINALinear Token (LINA)$0.00@0.00560 LINQLinq (LINQ)$0.00@0.00111.4601395 LNQLinqAI (LNQ)$0.20@0.13520.02886504 LPTLivepeer Tok... (LPT)$0.33@11.54110.31152938 LMEOWlmeow (LMEOW)$6.73@0.0610 LORDSLords (LORDS)$0.00@0.11560 LQTYLQTY (LQTY)$0.00@1.26850.00000004 LMRLumerin (LMR)$0.00@0.0254712.776239 LUNALUNA (Wormho... (LUNA)$0.08@0.00013,609.52604158 M2M2 (M2)$1.07@0.00030 MIMMagic Intern... (MIM)$0.00@0.99970.06582327 MAHAMAHA.xyz (MAHA)$0.05@0.81040 MELDMeld (MELD)$0.00@0.00030 MEMEMemecoin (MEME)$0.00@0.0140 MEMAGXMeta Masters... (MEMAGX)$0.00@0.00160 mETHmETH (mETH)$0.00@3,533.630 MetisMetis Token (Metis)$0.00@51.51635,549.13216134 MICKEYMickey Meme (MICKEY)$0.00@0.000 MAIMicro AI (MAI)$0.00@0.910151.55605076 MNSMINESHIELD (MNS)$0.00@0.00010 MLMLTToken (ML)$0.00@0.09580 MONAIMONAI (MONAI)$0.00@0.06480 EUReMonerium EUR... (EURe)$0.00@1.035310.3978798 MarkMoneyArk Tok... (Mark)$0.01@0.00050.00138332 CAHMoon Tropica (CAH)$0.01@9.90190 MUMUMumu (MUMU)$0.00@0.000 BULLMumu the Bul... (BULL)$0.00@0.000 MYRIAMyria (MYRIA)$0.00@0.00230 NEWSNewsly (NEWS)$0.00@0.00560.00000487 ONDOOndo (ONDO)$0.00@1.0740 USDYOndo U.S. Do... (USDY)$0.00@1.0610 OPNOpen Ecosyst... (OPN)$0.00@0.00070 OLMOpenLM RevSh... (OLM)$0.00@0.01580 OCHOrchai Token (OCH)$0.00@0.420112.09124274 ORDSOrdiswap (ORDS)$0.03@0.00280 OETHOrigin Ether (OETH)$0.00@3,381.790.00011378 OXOX Coin (OX)$0.00@0.01320.00000001 $PAALPAAL AI ($PAAL)$0.00@0.16290 PAINTPaint (PAINT)$0.00@0.000 PLTPalette (PLT)$0.00@60.78640 PRQParsiq Token (PRQ)$0.00@0.09140.00000044 PEASPeapods (PEAS)$0.00@5.671955,051.98295757 PEPEPepe (PEPE)$1.18@0.000 PEPEPepe (PEPE)$0.00@8.283.78441512 pepecoinpepeCoin (pepeco...)$15.05@3.97650 PERPPerpetual (PERP)$0.00@0.8058NFT Tokens (63)MNRCHMonarchx33ERC-721zeronewyear.com'0x0ai Mysterybox NFTERC-1155claim rewards on beamprotocol.netbeamprotocol.netERC-1155claim rewards on dydxnetwork.orgdydxnetwork.orgERC-1155claim rewards on ensfoundation.orgensfoundation.orgERC-1155claim rewards on fraxprotocol.comfraxprotocol.comERC-1155GNUSGenius Token & NFT CollectionsERC-1155INSC+INSC PlusERC-721IItemsERC-1155claim rewards on o-ether.orgo-ether.orgERC-1155claim rewards on ondonetwork.orgondonetwork.orgERC-1155Puffer Mystery Box NFT pufether.orgPuffer Mystery Box NFT pufether.orgERC-1155claim rewards qntnetwork.orgqntnetwork.orgERC-1155claim rewards on renderpool.orgrenderpool.orgERC-1155claim rewards riotoken.orgriotoken.orgERC-1155t.me/shibarmy_botShiba Inu Token AirdropERC-1155claim rewards on shibprotocol.comshibprotocol.comERC-1155claim rewards on snxtoken.comsnxtoken.comERC-1155claim rewards on stakedeth.iostakedeth.ioERC-1155claim rewards on woonetwork.netwoonetwork.netERC-1155claim rewards on wrappedbtc.netwrappedbtc.netERC-1155Let's Go!🎁ERC-1155Let's Go!🎁ERC-1155ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 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]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
1 address found via- Transactions
- Internal Transactions
- Token Transfers (ERC-20)
- NFT Transfers
- Contract
- Events
- Analytics
- Multichain Portfolio
- Cards New
Advanced Filter- Filter by Tx Type:
- Tx
- Internal Tx
- ERC-20
- NFTs
Latest 25 from a total of 151,829 transactions
Transaction Hash MethodBlockFromToSettle Orders 20142099 2024-06-21 19:11:35 154 days ago 1718997095 IN 0 ETH$0.00 0.00080852 7.05264551 Settle Orders 20142095 2024-06-21 19:10:47 154 days ago 1718997047 IN 0 ETH$0.00 0.00024709 6.87578116 Settle Orders 20142060 2024-06-21 19:03:47 154 days ago 1718996627 IN 0 ETH$0.00 0.00092968 8.1104247 Settle Orders 20141967 2024-06-21 18:44:59 154 days ago 1718995499 IN 0 ETH$0.00 0.00049099 4.95907104 Settle Orders 20141940 2024-06-21 18:39:35 154 days ago 1718995175 IN 0 ETH$0.00 0.00058248 5.89170576 Settle Orders 20141863 2024-06-21 18:23:59 154 days ago 1718994239 IN 0 ETH$0.00 0.00064538 6.42157121 Settle Orders 20141772 2024-06-21 18:04:59 154 days ago 1718993099 IN 0 ETH$0.00 0.00018493 6.52731216 Settle Orders 19882723 2024-05-16 13:05:35 190 days ago 1715864735 IN 0 ETH$0.00 0.00257613 9.50754889 Settle Orders 19882661 2024-05-16 12:52:59 190 days ago 1715863979 IN 0 ETH$0.00 0.00144218 7.44576253 Settle Orders 19882629 2024-05-16 12:46:35 190 days ago 1715863595 IN 0 ETH$0.00 0.00140706 6.37105872 Settle Orders 19882569 2024-05-16 12:34:35 190 days ago 1715862875 IN 0 ETH$0.00 0.00189979 6.4139273 Settle Orders 19882448 2024-05-16 12:10:23 190 days ago 1715861423 IN 0 ETH$0.00 0.0019903 7.21375494 Settle Orders 19882384 2024-05-16 11:57:23 190 days ago 1715860643 IN 0 ETH$0.00 0.00121948 5.0410393 Settle Orders 19882381 2024-05-16 11:56:47 190 days ago 1715860607 IN 0 ETH$0.00 0.00129326 5.08907344 Settle Orders 19881971 2024-05-16 10:34:23 190 days ago 1715855663 IN 0 ETH$0.00 0.0024449 8.81233871 Settle Orders 19881852 2024-05-16 10:10:35 190 days ago 1715854235 IN 0 ETH$0.00 0.00142166 5.45186198 Settle Orders 19881452 2024-05-16 8:50:11 191 days ago 1715849411 IN 0 ETH$0.00 0.00128417 5.76977473 Settle Orders 19881344 2024-05-16 8:28:35 191 days ago 1715848115 IN 0 ETH$0.00 0.0014164 6.08969158 Settle Orders 19881266 2024-05-16 8:12:47 191 days ago 1715847167 IN 0 ETH$0.00 0.00145843 6.72750653 Settle Orders 19880580 2024-05-16 5:54:23 191 days ago 1715838863 IN 0 ETH$0.00 0.00111809 5.3159457 Settle Orders 19880323 2024-05-16 5:02:35 191 days ago 1715835755 IN 0 ETH$0.00 0.00114343 4.51213356 Settle Orders 19879914 2024-05-16 3:39:47 191 days ago 1715830787 IN 0 ETH$0.00 0.00174098 5.75409261 Settle Orders 19879230 2024-05-16 1:22:35 191 days ago 1715822555 IN 0 ETH$0.00 0.00097623 4.76578442 Settle Orders 19878774 2024-05-15 23:50:35 191 days ago 1715817035 IN 0 ETH$0.00 0.00154009 5.84527848 Settle Orders 19877932 2024-05-15 21:00:59 191 days ago 1715806859 IN 0 ETH$0.00 0.00265773 11.76656812 Latest 3 internal transactions
Advanced mode:Parent Transaction Hash Block From To 20599344 2024-08-24 15:26:47 90 days ago 1724513207 0 ETH$0.00 19972407 2024-05-29 2:01:59 178 days ago 1716948119 0 ETH$0.00 16241236 2022-12-22 15:47:59 701 days ago 1671724079 Contract Creation 0 ETH$0.00 Loading...LoadingContract Name:Settlement
Compiler Versionv0.8.17+commit.8df45f5f
Optimization Enabled:Yes with 1000000 runs
Other Settings:default evmVersionContract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@1inch/limit-order-protocol-contract/contracts/interfaces/IOrderMixin.sol"; import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; import "./interfaces/ISettlement.sol"; import "./interfaces/IResolver.sol"; import "./libraries/DynamicSuffix.sol"; import "./libraries/OrderSaltParser.sol"; import "./libraries/OrderSuffix.sol"; import "./FeeBankCharger.sol"; contract Settlement is ISettlement, FeeBankCharger { using SafeERC20 for IERC20; using OrderSaltParser for uint256; using DynamicSuffix for bytes; using AddressLib for Address; using OrderSuffix for OrderLib.Order; using TakingFee for TakingFee.Data; error AccessDenied(); error IncorrectCalldataParams(); error FailedExternalCall(); error ResolverIsNotWhitelisted(); error WrongInteractionTarget(); bytes1 private constant _FINALIZE_INTERACTION = 0x01; uint256 private constant _ORDER_FEE_BASE_POINTS = 1e15; uint256 private constant _BASE_POINTS = 10_000_000; // 100% IOrderMixin private immutable _limitOrderProtocol; modifier onlyThis(address account) { if (account != address(this)) revert AccessDenied(); _; } modifier onlyLimitOrderProtocol { if (msg.sender != address(_limitOrderProtocol)) revert AccessDenied(); _; } constructor(IOrderMixin limitOrderProtocol, IERC20 token) FeeBankCharger(token) { _limitOrderProtocol = limitOrderProtocol; } function settleOrders(bytes calldata data) external { _settleOrder(data, msg.sender, 0, new bytes(0)); } function fillOrderInteraction( address taker, uint256, /* makingAmount */ uint256 takingAmount, bytes calldata interactiveData ) external onlyThis(taker) onlyLimitOrderProtocol returns (uint256 result) { (DynamicSuffix.Data calldata suffix, bytes calldata tokensAndAmounts, bytes calldata interaction) = interactiveData.decodeSuffix(); IERC20 token = IERC20(suffix.token.get()); result = takingAmount * (_BASE_POINTS + suffix.rateBump) / _BASE_POINTS; uint256 takingFee = result * suffix.takingFee.ratio() / TakingFee._TAKING_FEE_BASE; bytes memory allTokensAndAmounts = new bytes(tokensAndAmounts.length + 0x40); assembly { let ptr := add(allTokensAndAmounts, 0x20) calldatacopy(ptr, tokensAndAmounts.offset, tokensAndAmounts.length) ptr := add(ptr, tokensAndAmounts.length) mstore(ptr, token) mstore(add(ptr, 0x20), add(result, takingFee)) } if (interactiveData[0] == _FINALIZE_INTERACTION) { _chargeFee(suffix.resolver.get(), suffix.totalFee); address target = address(bytes20(interaction)); bytes calldata data = interaction[20:]; IResolver(target).resolveOrders(suffix.resolver.get(), allTokensAndAmounts, data); } else { _settleOrder( interaction, suffix.resolver.get(), suffix.totalFee, allTokensAndAmounts ); } if (takingFee > 0) { token.safeTransfer(suffix.takingFee.receiver(), takingFee); } token.forceApprove(address(_limitOrderProtocol), result); } bytes4 private constant _FILL_ORDER_TO_SELECTOR = 0xe5d7bde6; // IOrderMixin.fillOrderTo.selector bytes4 private constant _WRONG_INTERACTION_TARGET_SELECTOR = 0x5b34bf89; // WrongInteractionTarget.selector function _settleOrder(bytes calldata data, address resolver, uint256 totalFee, bytes memory tokensAndAmounts) private { OrderLib.Order calldata order; assembly { order := add(data.offset, calldataload(data.offset)) } if (!order.checkResolver(resolver)) revert ResolverIsNotWhitelisted(); TakingFee.Data takingFeeData = order.takingFee(); totalFee += order.salt.getFee() * _ORDER_FEE_BASE_POINTS; uint256 rateBump = order.rateBump(); uint256 suffixLength = DynamicSuffix._STATIC_DATA_SIZE + tokensAndAmounts.length + 0x20; IOrderMixin limitOrderProtocol = _limitOrderProtocol; assembly { function memcpy(dst, src, len) { pop(staticcall(gas(), 0x4, src, len, dst, len)) } let interactionLengthOffset := calldataload(add(data.offset, 0x40)) let interactionOffset := add(interactionLengthOffset, 0x20) let interactionLength := calldataload(add(data.offset, interactionLengthOffset)) { // stack too deep let target := shr(96, calldataload(add(data.offset, interactionOffset))) if or(lt(interactionLength, 20), iszero(eq(target, address()))) { mstore(0, _WRONG_INTERACTION_TARGET_SELECTOR) revert(0, 4) } } // Copy calldata and patch interaction.length let ptr := mload(0x40) mstore(ptr, _FILL_ORDER_TO_SELECTOR) calldatacopy(add(ptr, 4), data.offset, data.length) mstore(add(add(ptr, interactionLengthOffset), 4), add(interactionLength, suffixLength)) { // stack too deep // Append suffix fields let offset := add(add(ptr, interactionOffset), interactionLength) mstore(add(offset, 0x04), totalFee) mstore(add(offset, 0x24), resolver) mstore(add(offset, 0x44), calldataload(add(order, 0x40))) // takerAsset mstore(add(offset, 0x64), rateBump) mstore(add(offset, 0x84), takingFeeData) let tokensAndAmountsLength := mload(tokensAndAmounts) memcpy(add(offset, 0xa4), add(tokensAndAmounts, 0x20), tokensAndAmountsLength) mstore(add(offset, add(0xa4, tokensAndAmountsLength)), tokensAndAmountsLength) } // Call fillOrderTo if iszero(call(gas(), limitOrderProtocol, 0, ptr, add(add(4, suffixLength), data.length), ptr, 0)) { returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; pragma abicoder v1; /** * @title Interface for interactor which acts after `taker -> maker` transfers. * @notice The order filling steps are `preInteraction` =>` Transfer "maker -> taker"` => **`Interaction`** => `Transfer "taker -> maker"` => `postInteraction` */ interface IInteractionNotificationReceiver { /** * @notice Callback method that gets called after all funds transfers * @param taker Taker address (tx sender) * @param makingAmount Actual making amount * @param takingAmount Actual taking amount * @param interactionData Interaction calldata * @return offeredTakingAmount Suggested amount. Order is filled with this amount if maker or taker getter functions are not defined. */ function fillOrderInteraction( address taker, uint256 makingAmount, uint256 takingAmount, bytes memory interactionData ) external returns(uint256 offeredTakingAmount); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "../OrderLib.sol"; interface IOrderMixin { /** * @notice Returns unfilled amount for order. Throws if order does not exist * @param orderHash Order's hash. Can be obtained by the `hashOrder` function * @return amount Unfilled amount */ function remaining(bytes32 orderHash) external view returns(uint256 amount); /** * @notice Returns unfilled amount for order * @param orderHash Order's hash. Can be obtained by the `hashOrder` function * @return rawAmount Unfilled amount of order plus one if order exists. Otherwise 0 */ function remainingRaw(bytes32 orderHash) external view returns(uint256 rawAmount); /** * @notice Same as `remainingRaw` but for multiple orders * @param orderHashes Array of hashes * @return rawAmounts Array of amounts for each order plus one if order exists or 0 otherwise */ function remainingsRaw(bytes32[] memory orderHashes) external view returns(uint256[] memory rawAmounts); /** * @notice Checks order predicate * @param order Order to check predicate for * @return result Predicate evaluation result. True if predicate allows to fill the order, false otherwise */ function checkPredicate(OrderLib.Order calldata order) external view returns(bool result); /** * @notice Returns order hash according to EIP712 standard * @param order Order to get hash for * @return orderHash Hash of the order */ function hashOrder(OrderLib.Order calldata order) external view returns(bytes32 orderHash); /** * @notice Delegates execution to custom implementation. Could be used to validate if `transferFrom` works properly * @dev The function always reverts and returns the simulation results in revert data. * @param target Addresses that will be delegated * @param data Data that will be passed to delegatee */ function simulate(address target, bytes calldata data) external; /** * @notice Cancels order. * @dev Order is cancelled by setting remaining amount to _ORDER_FILLED value * @param order Order quote to cancel * @return orderRemaining Unfilled amount of order before cancellation * @return orderHash Hash of the filled order */ function cancelOrder(OrderLib.Order calldata order) external returns(uint256 orderRemaining, bytes32 orderHash); /** * @notice Fills an order. If one doesn't exist (first fill) it will be created using order.makerAssetData * @param order Order quote to fill * @param signature Signature to confirm quote ownership * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. * @param makingAmount Making amount * @param takingAmount Taking amount * @param skipPermitAndThresholdAmount Specifies maximum allowed takingAmount when takingAmount is zero, otherwise specifies minimum allowed makingAmount. Top-most bit specifies whether taker wants to skip maker's permit. * @return actualMakingAmount Actual amount transferred from maker to taker * @return actualTakingAmount Actual amount transferred from taker to maker * @return orderHash Hash of the filled order */ function fillOrder( OrderLib.Order calldata order, bytes calldata signature, bytes calldata interaction, uint256 makingAmount, uint256 takingAmount, uint256 skipPermitAndThresholdAmount ) external payable returns(uint256 actualMakingAmount, uint256 actualTakingAmount, bytes32 orderHash); /** * @notice Same as `fillOrderTo` but calls permit first, * allowing to approve token spending and make a swap in one transaction. * Also allows to specify funds destination instead of `msg.sender` * @dev See tests for examples * @param order Order quote to fill * @param signature Signature to confirm quote ownership * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. * @param makingAmount Making amount * @param takingAmount Taking amount * @param skipPermitAndThresholdAmount Specifies maximum allowed takingAmount when takingAmount is zero, otherwise specifies minimum allowed makingAmount. Top-most bit specifies whether taker wants to skip maker's permit. * @param target Address that will receive swap funds * @param permit Should consist of abiencoded token address and encoded `IERC20Permit.permit` call. * @return actualMakingAmount Actual amount transferred from maker to taker * @return actualTakingAmount Actual amount transferred from taker to maker * @return orderHash Hash of the filled order */ function fillOrderToWithPermit( OrderLib.Order calldata order, bytes calldata signature, bytes calldata interaction, uint256 makingAmount, uint256 takingAmount, uint256 skipPermitAndThresholdAmount, address target, bytes calldata permit ) external returns(uint256 actualMakingAmount, uint256 actualTakingAmount, bytes32 orderHash); /** * @notice Same as `fillOrder` but allows to specify funds destination instead of `msg.sender` * @param order_ Order quote to fill * @param signature Signature to confirm quote ownership * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. * @param makingAmount Making amount * @param takingAmount Taking amount * @param skipPermitAndThresholdAmount Specifies maximum allowed takingAmount when takingAmount is zero, otherwise specifies minimum allowed makingAmount. Top-most bit specifies whether taker wants to skip maker's permit. * @param target Address that will receive swap funds * @return actualMakingAmount Actual amount transferred from maker to taker * @return actualTakingAmount Actual amount transferred from taker to maker * @return orderHash Hash of the filled order */ function fillOrderTo( OrderLib.Order calldata order_, bytes calldata signature, bytes calldata interaction, uint256 makingAmount, uint256 takingAmount, uint256 skipPermitAndThresholdAmount, address target ) external payable returns(uint256 actualMakingAmount, uint256 actualTakingAmount, bytes32 orderHash); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "@1inch/solidity-utils/contracts/libraries/ECDSA.sol"; library OrderLib { struct Order { uint256 salt; address makerAsset; address takerAsset; address maker; address receiver; address allowedSender; // equals to Zero address on public orders uint256 makingAmount; uint256 takingAmount; uint256 offsets; // bytes makerAssetData; // bytes takerAssetData; // bytes getMakingAmount; // this.staticcall(abi.encodePacked(bytes, swapTakerAmount)) => (swapMakerAmount) // bytes getTakingAmount; // this.staticcall(abi.encodePacked(bytes, swapMakerAmount)) => (swapTakerAmount) // bytes predicate; // this.staticcall(bytes) => (bool) // bytes permit; // On first fill: permit.1.call(abi.encodePacked(permit.selector, permit.2)) // bytes preInteraction; // bytes postInteraction; bytes interactions; // concat(makerAssetData, takerAssetData, getMakingAmount, getTakingAmount, predicate, permit, preIntercation, postInteraction) } bytes32 constant internal _LIMIT_ORDER_TYPEHASH = keccak256( "Order(" "uint256 salt," "address makerAsset," "address takerAsset," "address maker," "address receiver," "address allowedSender," "uint256 makingAmount," "uint256 takingAmount," "uint256 offsets," "bytes interactions" ")" ); enum DynamicField { MakerAssetData, TakerAssetData, GetMakingAmount, GetTakingAmount, Predicate, Permit, PreInteraction, PostInteraction } function getterIsFrozen(bytes calldata getter) internal pure returns(bool) { return getter.length == 1 && getter[0] == "x"; } function _get(Order calldata order, DynamicField field) private pure returns(bytes calldata) { uint256 bitShift = uint256(field) << 5; // field * 32 return order.interactions[ uint32((order.offsets << 32) >> bitShift): uint32(order.offsets >> bitShift) ]; } function makerAssetData(Order calldata order) internal pure returns(bytes calldata) { return _get(order, DynamicField.MakerAssetData); } function takerAssetData(Order calldata order) internal pure returns(bytes calldata) { return _get(order, DynamicField.TakerAssetData); } function getMakingAmount(Order calldata order) internal pure returns(bytes calldata) { return _get(order, DynamicField.GetMakingAmount); } function getTakingAmount(Order calldata order) internal pure returns(bytes calldata) { return _get(order, DynamicField.GetTakingAmount); } function predicate(Order calldata order) internal pure returns(bytes calldata) { return _get(order, DynamicField.Predicate); } function permit(Order calldata order) internal pure returns(bytes calldata) { return _get(order, DynamicField.Permit); } function preInteraction(Order calldata order) internal pure returns(bytes calldata) { return _get(order, DynamicField.PreInteraction); } function postInteraction(Order calldata order) internal pure returns(bytes calldata) { return _get(order, DynamicField.PostInteraction); } function hash(Order calldata order, bytes32 domainSeparator) internal pure returns(bytes32 result) { bytes calldata interactions = order.interactions; bytes32 typehash = _LIMIT_ORDER_TYPEHASH; /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) // keccak256(abi.encode(_LIMIT_ORDER_TYPEHASH, orderWithoutInteractions, keccak256(order.interactions))); calldatacopy(ptr, interactions.offset, interactions.length) mstore(add(ptr, 0x140), keccak256(ptr, interactions.length)) calldatacopy(add(ptr, 0x20), order, 0x120) mstore(ptr, typehash) result := keccak256(ptr, 0x160) } result = ECDSA.toTypedDataHash(domainSeparator, result); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma abicoder v1; interface IDaiLikePermit { function permit( address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma abicoder v1; import "@openzeppelin/contracts/interfaces/IERC1271.sol"; library ECDSA { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. uint256 private constant _S_BOUNDARY = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 + 1; uint256 private constant _COMPACT_S_MASK = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; uint256 private constant _COMPACT_V_SHIFT = 255; function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal view returns (address signer) { /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly if lt(s, _S_BOUNDARY) { let ptr := mload(0x40) mstore(ptr, hash) mstore(add(ptr, 0x20), v) mstore(add(ptr, 0x40), r) mstore(add(ptr, 0x60), s) mstore(0, 0) pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20)) signer := mload(0) } } } function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal view returns (address signer) { /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let s := and(vs, _COMPACT_S_MASK) if lt(s, _S_BOUNDARY) { let ptr := mload(0x40) mstore(ptr, hash) mstore(add(ptr, 0x20), add(27, shr(_COMPACT_V_SHIFT, vs))) mstore(add(ptr, 0x40), r) mstore(add(ptr, 0x60), s) mstore(0, 0) pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20)) signer := mload(0) } } } /// @dev WARNING!!! /// There is a known signature malleability issue with two representations of signatures! /// Even though this function is able to verify both standard 65-byte and compact 64-byte EIP-2098 signatures /// one should never use raw signatures for any kind of invalidation logic in their code. /// As the standard and compact representations are interchangeable any invalidation logic that relies on /// signature uniqueness will get rekt. /// More info: https://github.com/OpenZeppelin/openzeppelin-contracts/security/advisories/GHSA-4h98-2769-gh6h function recover(bytes32 hash, bytes calldata signature) internal view returns (address signer) { /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) // memory[ptr:ptr+0x80] = (hash, v, r, s) switch signature.length case 65 { // memory[ptr+0x20:ptr+0x80] = (v, r, s) mstore(add(ptr, 0x20), byte(0, calldataload(add(signature.offset, 0x40)))) calldatacopy(add(ptr, 0x40), signature.offset, 0x40) } case 64 { // memory[ptr+0x20:ptr+0x80] = (v, r, s) let vs := calldataload(add(signature.offset, 0x20)) mstore(add(ptr, 0x20), add(27, shr(_COMPACT_V_SHIFT, vs))) calldatacopy(add(ptr, 0x40), signature.offset, 0x20) mstore(add(ptr, 0x60), and(vs, _COMPACT_S_MASK)) } default { ptr := 0 } if ptr { if lt(mload(add(ptr, 0x60)), _S_BOUNDARY) { // memory[ptr:ptr+0x20] = (hash) mstore(ptr, hash) mstore(0, 0) pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20)) signer := mload(0) } } } } function recoverOrIsValidSignature( address signer, bytes32 hash, bytes calldata signature ) internal view returns (bool success) { if (signer == address(0)) return false; if ((signature.length == 64 || signature.length == 65) && recover(hash, signature) == signer) { return true; } return isValidSignature(signer, hash, signature); } function recoverOrIsValidSignature( address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal view returns (bool success) { if (signer == address(0)) return false; if (recover(hash, v, r, s) == signer) { return true; } return isValidSignature(signer, hash, v, r, s); } function recoverOrIsValidSignature( address signer, bytes32 hash, bytes32 r, bytes32 vs ) internal view returns (bool success) { if (signer == address(0)) return false; if (recover(hash, r, vs) == signer) { return true; } return isValidSignature(signer, hash, r, vs); } function recoverOrIsValidSignature65( address signer, bytes32 hash, bytes32 r, bytes32 vs ) internal view returns (bool success) { if (signer == address(0)) return false; if (recover(hash, r, vs) == signer) { return true; } return isValidSignature65(signer, hash, r, vs); } function isValidSignature( address signer, bytes32 hash, bytes calldata signature ) internal view returns (bool success) { // (bool success, bytes memory data) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)); // return success && data.length >= 4 && abi.decode(data, (bytes4)) == IERC1271.isValidSignature.selector; bytes4 selector = IERC1271.isValidSignature.selector; /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) mstore(ptr, selector) mstore(add(ptr, 0x04), hash) mstore(add(ptr, 0x24), 0x40) mstore(add(ptr, 0x44), signature.length) calldatacopy(add(ptr, 0x64), signature.offset, signature.length) if staticcall(gas(), signer, ptr, add(0x64, signature.length), 0, 0x20) { success := and(eq(selector, mload(0)), eq(returndatasize(), 0x20)) } } } function isValidSignature( address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal view returns (bool success) { bytes4 selector = IERC1271.isValidSignature.selector; /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) mstore(ptr, selector) mstore(add(ptr, 0x04), hash) mstore(add(ptr, 0x24), 0x40) mstore(add(ptr, 0x44), 65) mstore(add(ptr, 0x64), r) mstore(add(ptr, 0x84), s) mstore8(add(ptr, 0xa4), v) if staticcall(gas(), signer, ptr, 0xa5, 0, 0x20) { success := and(eq(selector, mload(0)), eq(returndatasize(), 0x20)) } } } function isValidSignature( address signer, bytes32 hash, bytes32 r, bytes32 vs ) internal view returns (bool success) { // (bool success, bytes memory data) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, abi.encodePacked(r, vs))); // return success && data.length >= 4 && abi.decode(data, (bytes4)) == IERC1271.isValidSignature.selector; bytes4 selector = IERC1271.isValidSignature.selector; /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) mstore(ptr, selector) mstore(add(ptr, 0x04), hash) mstore(add(ptr, 0x24), 0x40) mstore(add(ptr, 0x44), 64) mstore(add(ptr, 0x64), r) mstore(add(ptr, 0x84), vs) if staticcall(gas(), signer, ptr, 0xa4, 0, 0x20) { success := and(eq(selector, mload(0)), eq(returndatasize(), 0x20)) } } } function isValidSignature65( address signer, bytes32 hash, bytes32 r, bytes32 vs ) internal view returns (bool success) { // (bool success, bytes memory data) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, abi.encodePacked(r, vs & ~uint256(1 << 255), uint8(vs >> 255)))); // return success && data.length >= 4 && abi.decode(data, (bytes4)) == IERC1271.isValidSignature.selector; bytes4 selector = IERC1271.isValidSignature.selector; /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) mstore(ptr, selector) mstore(add(ptr, 0x04), hash) mstore(add(ptr, 0x24), 0x40) mstore(add(ptr, 0x44), 65) mstore(add(ptr, 0x64), r) mstore(add(ptr, 0x84), and(vs, _COMPACT_S_MASK)) mstore8(add(ptr, 0xa4), add(27, shr(_COMPACT_V_SHIFT, vs))) if staticcall(gas(), signer, ptr, 0xa5, 0, 0x20) { success := and(eq(selector, mload(0)), eq(returndatasize(), 0x20)) } } } function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 res) { // 32 is the length in bytes of hash, enforced by the type signature above // return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly mstore(0, 0x19457468657265756d205369676e6564204d6573736167653a0a333200000000) // "\x19Ethereum Signed Message:\n32" mstore(28, hash) res := keccak256(0, 60) } } function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 res) { // return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) mstore(ptr, 0x1901000000000000000000000000000000000000000000000000000000000000) // "\x19\x01" mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) res := keccak256(ptr, 66) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma abicoder v1; /// @title Revert reason forwarder. library RevertReasonForwarder { /// @dev Forwards latest externall call revert. function reRevert() internal pure { // bubble up revert reason from latest external call /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma abicoder v1; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol"; import "../interfaces/IDaiLikePermit.sol"; import "../libraries/RevertReasonForwarder.sol"; /// @title Implements efficient safe methods for ERC20 interface. library SafeERC20 { error SafeTransferFailed(); error SafeTransferFromFailed(); error ForceApproveFailed(); error SafeIncreaseAllowanceFailed(); error SafeDecreaseAllowanceFailed(); error SafePermitBadLength(); /// @dev Ensures method do not revert or return boolean `true`, admits call to non-smart-contract. function safeTransferFrom( IERC20 token, address from, address to, uint256 amount ) internal { bytes4 selector = token.transferFrom.selector; bool success; /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let data := mload(0x40) mstore(data, selector) mstore(add(data, 0x04), from) mstore(add(data, 0x24), to) mstore(add(data, 0x44), amount) success := call(gas(), token, 0, data, 100, 0x0, 0x20) if success { switch returndatasize() case 0 { success := gt(extcodesize(token), 0) } default { success := and(gt(returndatasize(), 31), eq(mload(0), 1)) } } } if (!success) revert SafeTransferFromFailed(); } /// @dev Ensures method do not revert or return boolean `true`, admits call to non-smart-contract. function safeTransfer( IERC20 token, address to, uint256 value ) internal { if (!_makeCall(token, token.transfer.selector, to, value)) { revert SafeTransferFailed(); } } /// @dev If `approve(from, to, amount)` fails, try to `approve(from, to, 0)` before retry. function forceApprove( IERC20 token, address spender, uint256 value ) internal { if (!_makeCall(token, token.approve.selector, spender, value)) { if ( !_makeCall(token, token.approve.selector, spender, 0) || !_makeCall(token, token.approve.selector, spender, value) ) { revert ForceApproveFailed(); } } } /// @dev Allowance increase with safe math check. function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 allowance = token.allowance(address(this), spender); if (value > type(uint256).max - allowance) revert SafeIncreaseAllowanceFailed(); forceApprove(token, spender, allowance + value); } /// @dev Allowance decrease with safe math check. function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 allowance = token.allowance(address(this), spender); if (value > allowance) revert SafeDecreaseAllowanceFailed(); forceApprove(token, spender, allowance - value); } /// @dev Calls either ERC20 or Dai `permit` for `token`, if unsuccessful forwards revert from external call. function safePermit(IERC20 token, bytes calldata permit) internal { if (!tryPermit(token, permit)) RevertReasonForwarder.reRevert(); } function tryPermit(IERC20 token, bytes calldata permit) internal returns(bool) { if (permit.length == 32 * 7) { return _makeCalldataCall(token, IERC20Permit.permit.selector, permit); } if (permit.length == 32 * 8) { return _makeCalldataCall(token, IDaiLikePermit.permit.selector, permit); } revert SafePermitBadLength(); } function _makeCall( IERC20 token, bytes4 selector, address to, uint256 amount ) private returns (bool success) { /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let data := mload(0x40) mstore(data, selector) mstore(add(data, 0x04), to) mstore(add(data, 0x24), amount) success := call(gas(), token, 0, data, 0x44, 0x0, 0x20) if success { switch returndatasize() case 0 { success := gt(extcodesize(token), 0) } default { success := and(gt(returndatasize(), 31), eq(mload(0), 1)) } } } } function _makeCalldataCall( IERC20 token, bytes4 selector, bytes calldata args ) private returns (bool success) { /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let len := add(4, args.length) let data := mload(0x40) mstore(data, selector) calldatacopy(add(data, 0x04), args.offset, args.length) success := call(gas(), token, 0, data, len, 0x0, 0x20) if success { switch returndatasize() case 0 { success := gt(extcodesize(token), 0) } default { success := and(gt(returndatasize(), 31), eq(mload(0), 1)) } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC1271 standard signature validation method for * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. * * _Available since v4.1._ */ interface IERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param hash Hash of the data to be signed * @param signature Signature byte array associated with _data */ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) 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.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./interfaces/IFeeBankCharger.sol"; import "./interfaces/IFeeBank.sol"; /// @title Contract with fee mechanism for solvers to pay for using the system contract FeeBank is IFeeBank, Ownable { using SafeERC20 for IERC20; IERC20 private immutable _token; IFeeBankCharger private immutable _charger; mapping(address => uint256) private _accountDeposits; constructor(IFeeBankCharger charger, IERC20 inch, address owner) { _charger = charger; _token = inch; transferOwnership(owner); } function availableCredit(address account) external view returns (uint256) { return _charger.availableCredit(account); } /** * @notice Increment sender's availableCredit in Settlement contract. * @param amount The amount of 1INCH sender pay for incresing. * @return totalAvailableCredit The total sender's availableCredit after deposit. */ function deposit(uint256 amount) external returns (uint256 totalAvailableCredit) { return _depositFor(msg.sender, amount); } /** * @notice Increases account's availableCredit in Settlement contract. * @param account The account whose availableCredit is increased by the sender. * @param amount The amount of 1INCH sender pay for incresing. * @return totalAvailableCredit The total account's availableCredit after deposit. */ function depositFor(address account, uint256 amount) external returns (uint256 totalAvailableCredit) { return _depositFor(account, amount); } /** * @notice See {deposit}. This method uses permit for deposit without prior approves. * @param amount The amount of 1INCH sender pay for incresing. * @param permit The data with sender's permission via token. * @return totalAvailableCredit The total sender's availableCredit after deposit. */ function depositWithPermit(uint256 amount, bytes calldata permit) external returns (uint256 totalAvailableCredit) { return depositForWithPermit(msg.sender, amount, permit); } /** * @notice See {depositFor} and {depositWithPermit}. */ function depositForWithPermit( address account, uint256 amount, bytes calldata permit ) public returns (uint256 totalAvailableCredit) { _token.safePermit(permit); return _depositFor(account, amount); } /** * @notice Returns unspent availableCredit. * @param amount The amount of 1INCH sender returns. * @return totalAvailableCredit The total sender's availableCredit after withdrawal. */ function withdraw(uint256 amount) external returns (uint256 totalAvailableCredit) { return _withdrawTo(msg.sender, amount); } /** * @notice Returns unspent availableCredit to specific account. * @param account The account which get withdrawaled tokens. * @param amount The amount of withdrawaled tokens. * @return totalAvailableCredit The total sender's availableCredit after withdrawal. */ function withdrawTo(address account, uint256 amount) external returns (uint256 totalAvailableCredit) { return _withdrawTo(account, amount); } /** * @notice Admin method returns commissions spent by users. * @param accounts Accounts whose commissions are being withdrawn. * @return totalAccountFees The total amount of accounts commissions. */ function gatherFees(address[] memory accounts) external onlyOwner returns (uint256 totalAccountFees) { uint256 accountsLength = accounts.length; for (uint256 i = 0; i < accountsLength; ++i) { address account = accounts[i]; uint256 accountDeposit = _accountDeposits[account]; uint256 availableCredit_ = _charger.availableCredit(account); _accountDeposits[account] = availableCredit_; totalAccountFees += accountDeposit - availableCredit_; } _token.safeTransfer(msg.sender, totalAccountFees); } function _depositFor(address account, uint256 amount) internal returns (uint256 totalAvailableCredit) { _token.safeTransferFrom(msg.sender, address(this), amount); _accountDeposits[account] += amount; totalAvailableCredit = _charger.increaseAvailableCredit(account, amount); } function _withdrawTo(address account, uint256 amount) internal returns (uint256 totalAvailableCredit) { totalAvailableCredit = _charger.decreaseAvailableCredit(msg.sender, amount); _accountDeposits[msg.sender] -= amount; _token.safeTransfer(account, amount); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./interfaces/IFeeBankCharger.sol"; import "./FeeBank.sol"; contract FeeBankCharger is IFeeBankCharger { error OnlyFeeBankAccess(); error NotEnoughCredit(); IFeeBank public immutable feeBank; mapping(address => uint256) private _creditAllowance; modifier onlyFeeBank() { if (msg.sender != address(feeBank)) revert OnlyFeeBankAccess(); _; } constructor(IERC20 token) { feeBank = new FeeBank(this, token, msg.sender); } function availableCredit(address account) external view returns (uint256) { return _creditAllowance[account]; } function increaseAvailableCredit(address account, uint256 amount) external onlyFeeBank returns (uint256 allowance) { allowance = _creditAllowance[account]; allowance += amount; _creditAllowance[account] = allowance; } function decreaseAvailableCredit(address account, uint256 amount) external onlyFeeBank returns (uint256 allowance) { allowance = _creditAllowance[account]; allowance -= amount; _creditAllowance[account] = allowance; } function _chargeFee(address account, uint256 fee) internal { if (fee > 0) { uint256 currentAllowance = _creditAllowance[account]; if (currentAllowance < fee) revert NotEnoughCredit(); unchecked { _creditAllowance[account] = currentAllowance - fee; } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IFeeBank { function deposit(uint256 amount) external returns (uint256 totalAvailableCredit); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IFeeBankCharger { function availableCredit(address account) external view returns (uint256); function increaseAvailableCredit(address account, uint256 amount) external returns (uint256 allowance); function decreaseAvailableCredit(address account, uint256 amount) external returns (uint256 allowance); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "../libraries/DynamicSuffix.sol"; interface IResolver { function resolveOrders(address resolver, bytes calldata tokensAndAmounts, bytes calldata data) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "@1inch/limit-order-protocol-contract/contracts/interfaces/IInteractionNotificationReceiver.sol"; import "./IFeeBankCharger.sol"; interface ISettlement is IInteractionNotificationReceiver, IFeeBankCharger { function settleOrders(bytes calldata order) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; type Address is uint256; library AddressLib { function get(Address a) internal pure returns (address) { return address(uint160(Address.unwrap(a))); } function getFlag(Address a, uint256 flag) internal pure returns (bool) { return Address.unwrap(a) & flag != 0; } function getUint32(Address a, uint256 offset) internal pure returns (uint32) { return uint32(Address.unwrap(a) >> offset); } function getUint64(Address a, uint256 offset) internal pure returns (uint64) { return uint64(Address.unwrap(a) >> offset); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./Address.sol"; import "./TakingFee.sol"; // layout of dynamic suffix is as follows: // 0x00 - 0x19: totalFee // 0x20 - 0x39: resolver // 0x40 - 0x59: token // 0x60 - 0x79: rateBump // 0x80 - 0x99: takingFee // 0xa0 - 0x..: tokensAndAmounts bytes // 0x.. - 0x..: tokensAndAmounts length in bytes library DynamicSuffix { struct Data { uint256 totalFee; Address resolver; Address token; uint256 rateBump; TakingFee.Data takingFee; } uint256 internal constant _STATIC_DATA_SIZE = 0xa0; function decodeSuffix(bytes calldata cd) internal pure returns(Data calldata suffix, bytes calldata tokensAndAmounts, bytes calldata interaction) { assembly { let lengthOffset := sub(add(cd.offset, cd.length), 0x20) tokensAndAmounts.length := calldataload(lengthOffset) tokensAndAmounts.offset := sub(lengthOffset, tokensAndAmounts.length) suffix := sub(tokensAndAmounts.offset, _STATIC_DATA_SIZE) interaction.offset := add(cd.offset, 1) interaction.length := sub(suffix, interaction.offset) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// @title Library for parsing parameters from salt. library OrderSaltParser { uint256 private constant _TIME_START_MASK = 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000; // prettier-ignore uint256 private constant _DURATION_MASK = 0x00000000FFFFFF00000000000000000000000000000000000000000000000000; // prettier-ignore uint256 private constant _INITIAL_RATE_BUMP_MASK = 0x00000000000000FFFFFF00000000000000000000000000000000000000000000; // prettier-ignore uint256 private constant _FEE_MASK = 0x00000000000000000000FFFFFFFF000000000000000000000000000000000000; // prettier-ignore uint256 private constant _SALT_MASK = 0x0000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 private constant _TIME_START_SHIFT = 224; // orderTimeMask 224-255 uint256 private constant _DURATION_SHIFT = 200; // durationMask 200-223 uint256 private constant _INITIAL_RATE_BUMP_SHIFT = 176; // initialRateMask 176-200 uint256 private constant _FEE_SHIFT = 144; // orderFee 144-175 function getStartTime(uint256 salt) internal pure returns (uint256) { return (salt & _TIME_START_MASK) >> _TIME_START_SHIFT; } function getDuration(uint256 salt) internal pure returns (uint256) { return (salt & _DURATION_MASK) >> _DURATION_SHIFT; } function getInitialRateBump(uint256 salt) internal pure returns (uint256) { return (salt & _INITIAL_RATE_BUMP_MASK) >> _INITIAL_RATE_BUMP_SHIFT; } function getFee(uint256 salt) internal pure returns (uint256) { return (salt & _FEE_MASK) >> _FEE_SHIFT; } function getSalt(uint256 salt) internal pure returns (uint256) { return salt & _SALT_MASK; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "@1inch/limit-order-protocol-contract/contracts/OrderLib.sol"; import "./OrderSaltParser.sol"; import "./TakingFee.sol"; // Placed in the end of the order interactions data // Last byte contains flags and lengths, can have up to 15 resolvers and 7 points library OrderSuffix { using OrderSaltParser for uint256; // `Order.interactions` suffix structure: // M*(1 + 3 bytes) - auction points coefficients with seconds delays // N*(4 + 20 bytes) - resolver with corresponding time limit // 4 bytes - public time limit // 32 bytes - taking fee (optional if flags has _HAS_TAKING_FEE_FLAG) // 1 bytes - flags uint256 private constant _HAS_TAKING_FEE_FLAG = 0x80; uint256 private constant _RESOLVERS_LENGTH_MASK = 0x78; uint256 private constant _RESOLVERS_LENGTH_BIT_SHIFT = 3; uint256 private constant _POINTS_LENGTH_MASK = 0x07; uint256 private constant _POINTS_LENGTH_BIT_SHIFT = 0; uint256 private constant _TAKING_FEE_BYTES_SIZE = 32; uint256 private constant _PUBLIC_TIME_LIMIT_BYTES_SIZE = 4; uint256 private constant _PUBLIC_TIME_LIMIT_BIT_SHIFT = 224; // 256 - _PUBLIC_TIME_LIMIT_BYTES_SIZE * 8 uint256 private constant _AUCTION_POINT_DELAY_BYTES_SIZE = 2; uint256 private constant _AUCTION_POINT_BUMP_BYTES_SIZE = 3; uint256 private constant _AUCTION_POINT_BYTES_SIZE = 5; // _AUCTION_POINT_DELAY_BYTES_SIZE + _AUCTION_POINT_BUMP_BYTES_SIZE; uint256 private constant _AUCTION_POINT_DELAY_BIT_SHIFT = 240; // 256 - _AUCTION_POINT_DELAY_BYTES_SIZE * 8; uint256 private constant _AUCTION_POINT_BUMP_BIT_SHIFT = 232; // 256 - _AUCTION_POINT_BUMP_BYTES_SIZE * 8; uint256 private constant _RESOLVER_TIME_LIMIT_BYTES_SIZE = 4; uint256 private constant _RESOLVER_ADDRESS_BYTES_SIZE = 20; uint256 private constant _RESOLVER_BYTES_SIZE = 24; // _RESOLVER_TIME_LIMIT_BYTES_SIZE + _RESOLVER_ADDRESS_BYTES_SIZE; uint256 private constant _RESOLVER_TIME_LIMIT_BIT_SHIFT = 224; // 256 - _RESOLVER_TIME_LIMIT_BYTES_SIZE * 8; uint256 private constant _RESOLVER_ADDRESS_BIT_SHIFT = 96; // 256 - _RESOLVER_ADDRESS_BYTES_SIZE * 8; function takingFee(OrderLib.Order calldata order) internal pure returns (TakingFee.Data ret) { bytes calldata interactions = order.interactions; assembly { let ptr := sub(add(interactions.offset, interactions.length), 1) if and(_HAS_TAKING_FEE_FLAG, byte(0, calldataload(ptr))) { ret := calldataload(sub(ptr, _TAKING_FEE_BYTES_SIZE)) } } } function checkResolver(OrderLib.Order calldata order, address resolver) internal view returns (bool valid) { bytes calldata interactions = order.interactions; assembly { let ptr := sub(add(interactions.offset, interactions.length), 1) let flags := byte(0, calldataload(ptr)) ptr := sub(ptr, _PUBLIC_TIME_LIMIT_BYTES_SIZE) if and(flags, _HAS_TAKING_FEE_FLAG) { ptr := sub(ptr, _TAKING_FEE_BYTES_SIZE) } let resolversCount := shr(_RESOLVERS_LENGTH_BIT_SHIFT, and(flags, _RESOLVERS_LENGTH_MASK)) // Check public time limit let publicLimit := shr(_PUBLIC_TIME_LIMIT_BIT_SHIFT, calldataload(ptr)) valid := gt(timestamp(), publicLimit) // Check resolvers and corresponding time limits if not(valid) { for { let end := sub(ptr, mul(_RESOLVER_BYTES_SIZE, resolversCount)) } gt(ptr, end) { } { ptr := sub(ptr, _RESOLVER_ADDRESS_BYTES_SIZE) let account := shr(_RESOLVER_ADDRESS_BIT_SHIFT, calldataload(ptr)) ptr := sub(ptr, _RESOLVER_TIME_LIMIT_BYTES_SIZE) let limit := shr(_RESOLVER_TIME_LIMIT_BIT_SHIFT, calldataload(ptr)) if eq(account, resolver) { valid := iszero(lt(timestamp(), limit)) break } } } } } function rateBump(OrderLib.Order calldata order) internal view returns (uint256 bump) { uint256 startBump = order.salt.getInitialRateBump(); uint256 cumulativeTime = order.salt.getStartTime(); uint256 lastTime = cumulativeTime + order.salt.getDuration(); if (block.timestamp <= cumulativeTime) { return startBump; } else if (block.timestamp >= lastTime) { return 0; } bytes calldata interactions = order.interactions; assembly { function linearInterpolation(t1, t2, v1, v2, t) -> v { v := div( add(mul(sub(t, t1), v2), mul(sub(t2, t), v1)), sub(t2, t1) ) } let ptr := sub(add(interactions.offset, interactions.length), 1) // move ptr to the last point let pointsCount { // stack too deep let flags := byte(0, calldataload(ptr)) let resolversCount := shr(_RESOLVERS_LENGTH_BIT_SHIFT, and(flags, _RESOLVERS_LENGTH_MASK)) pointsCount := and(flags, _POINTS_LENGTH_MASK) if and(flags, _HAS_TAKING_FEE_FLAG) { ptr := sub(ptr, _TAKING_FEE_BYTES_SIZE) } ptr := sub(ptr, add(mul(_RESOLVER_BYTES_SIZE, resolversCount), _PUBLIC_TIME_LIMIT_BYTES_SIZE)) // 24 byte for each wl entry + 4 bytes for public time limit } // Check points sequentially let prevCoefficient := startBump let prevCumulativeTime := cumulativeTime for { let end := sub(ptr, mul(_AUCTION_POINT_BYTES_SIZE, pointsCount)) } gt(ptr, end) { } { ptr := sub(ptr, _AUCTION_POINT_BUMP_BYTES_SIZE) let coefficient := shr(_AUCTION_POINT_BUMP_BIT_SHIFT, calldataload(ptr)) ptr := sub(ptr, _AUCTION_POINT_DELAY_BYTES_SIZE) let delay := shr(_AUCTION_POINT_DELAY_BIT_SHIFT, calldataload(ptr)) cumulativeTime := add(cumulativeTime, delay) if gt(cumulativeTime, timestamp()) { // prevCumulativeTime <passed> time <elapsed> cumulativeTime // prevCoefficient <passed> X <elapsed> coefficient bump := linearInterpolation( prevCumulativeTime, cumulativeTime, prevCoefficient, coefficient, timestamp() ) break } prevCumulativeTime := cumulativeTime prevCoefficient := coefficient } if iszero(bump) { bump := linearInterpolation( prevCumulativeTime, lastTime, prevCoefficient, 0, timestamp() ) } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; library TakingFee { type Data is uint256; uint256 internal constant _TAKING_FEE_BASE = 1e9; uint256 private constant _TAKING_FEE_RATIO_OFFSET = 160; function init(address receiver_, uint256 ratio_) internal pure returns (Data) { if (ratio_ == 0) { return Data.wrap(uint160(receiver_)); } return Data.wrap(uint160(receiver_) | (ratio_ << _TAKING_FEE_RATIO_OFFSET)); } function enabled(Data self) internal pure returns (bool) { return ratio(self) != 0; } function ratio(Data self) internal pure returns (uint256) { return uint32(Data.unwrap(self) >> _TAKING_FEE_RATIO_OFFSET); } function receiver(Data self) internal pure returns (address) { return address(uint160(Data.unwrap(self))); } }
{ "optimizer": { "enabled": true, "runs": 1000000 }, "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":[{"internalType":"contract IOrderMixin","name":"limitOrderProtocol","type":"address"},{"internalType":"contract IERC20","name":"token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessDenied","type":"error"},{"inputs":[],"name":"FailedExternalCall","type":"error"},{"inputs":[],"name":"ForceApproveFailed","type":"error"},{"inputs":[],"name":"IncorrectCalldataParams","type":"error"},{"inputs":[],"name":"NotEnoughCredit","type":"error"},{"inputs":[],"name":"OnlyFeeBankAccess","type":"error"},{"inputs":[],"name":"ResolverIsNotWhitelisted","type":"error"},{"inputs":[],"name":"SafeTransferFailed","type":"error"},{"inputs":[],"name":"WrongInteractionTarget","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"availableCredit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"decreaseAvailableCredit","outputs":[{"internalType":"uint256","name":"allowance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeBank","outputs":[{"internalType":"contract IFeeBank","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"takingAmount","type":"uint256"},{"internalType":"bytes","name":"interactiveData","type":"bytes"}],"name":"fillOrderInteraction","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"increaseAvailableCredit","outputs":[{"internalType":"uint256","name":"allowance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"settleOrders","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c060405234801561001057600080fd5b50604051620023a0380380620023a0833981016040819052610031916100c1565b803081336040516100419061009b565b6001600160a01b03938416815291831660208301529091166040820152606001604051809103906000f08015801561007d573d6000803e3d6000fd5b506001600160a01b039081166080529290921660a052506100fb9050565b611120806200128083390190565b6001600160a01b03811681146100be57600080fd5b50565b600080604083850312156100d457600080fd5b82516100df816100a9565b60208401519092506100f0816100a9565b809150509250929050565b60805160a0516111436200013d6000396000818161035b015281816106a4015261077f01526000818161010001528181610197015261026901526111436000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806385eda2de1161005057806385eda2de146100e8578063af15d786146100fb578063ccee33d71461014757600080fd5b80630965d04b146100775780633ee5ef1f1461008c5780635886216f146100b2575b600080fd5b61008a610085366004610d52565b61015a565b005b61009f61009a366004610dbd565b61017d565b6040519081526020015b60405180910390f35b61009f6100c0366004610de7565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61009f6100f6366004610dbd565b61024f565b6101227f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a9565b61009f610155366004610e09565b6102f1565b60408051600080825260208201909252610179918491849133916106db565b5050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101ee576040517fa454419900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205461021f8282610ecf565b73ffffffffffffffffffffffffffffffffffffffff90931660009081526020819052604090208390555090919050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102c0576040517fa454419900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205461021f8282610ee8565b60008573ffffffffffffffffffffffffffffffffffffffff81163014610343576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146103b2576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8284017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081810135918290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff40810192918101919060018801908881037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f01907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80810135906298968090610489907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0013582610ecf565b610493908d610efb565b61049d9190610f12565b97506000633b9aca006104bd63ffffffff60808a013560a01c168b610efb565b6104c79190610f12565b905060006104d6866040610ecf565b67ffffffffffffffff8111156104ee576104ee610e71565b6040519080825280601f01601f191660200182016040528015610518576020820181803683370190505b509050602081018688823786018381528a83016020909101527f01000000000000000000000000000000000000000000000000000000000000008c8c60008161056357610563610f4d565b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361064b576105a3602089013589356108a3565b60006105af8587610f7c565b60601c90503660006105c4876014818b610fc4565b915091508273ffffffffffffffffffffffffffffffffffffffff16631944799f6105ef8d6020013590565b8685856040518563ffffffff1660e01b81526004016106119493929190610fee565b600060405180830381600087803b15801561062b57600080fd5b505af115801561063f573d6000803e3d6000fd5b5050505050505061065d565b61065d858560208b01358b35856106db565b81156106885761068873ffffffffffffffffffffffffffffffffffffffff841660808a013584610936565b6106c973ffffffffffffffffffffffffffffffffffffffff84167f00000000000000000000000000000000000000000000000000000000000000008c61099d565b50505050505050505095945050505050565b843585016106e98185610a66565b61071f576040517f4b57606900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061072a82610b37565b905061074766038d7ea4c6800063ffffffff843560901c16610efb565b6107519085610ecf565b9350600061075e83610b70565b90506000845160a06107709190610ecf565b61077b906020610ecf565b90507f00000000000000000000000000000000000000000000000000000000000000006107b1565b8281848460045afa50505050565b60408a013560208101818c0135818d013560601c308114156014831017156107fd577f5b34bf890000000000000000000000000000000000000000000000000000000060005260046000fd5b506040517fe5d7bde60000000000000000000000000000000000000000000000000000000081528c8e600483013785820160048583010152818382010193508a60048501528b60248501526040890135604485015286606485015287608485015289516108718160208d0160a488016107a3565b84810160a40152600081878f016004018183895af1610893573d6000823e3d81fd5b5050505050505050505050505050565b80156101795773ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610909576040517fa7fd379200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff92909216600090815260208190526040902091039055565b610962837fa9059cbb000000000000000000000000000000000000000000000000000000008484610cb5565b610998576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6109c9837f095ea7b3000000000000000000000000000000000000000000000000000000008484610cb5565b610998576109fa837f095ea7b300000000000000000000000000000000000000000000000000000000846000610cb5565b1580610a2f5750610a2d837f095ea7b3000000000000000000000000000000000000000000000000000000008484610cb5565b155b15610998576040517f19be9a9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003681610a786101208601866110a8565b91509150600181830103803560001a6004820391506080811615610a9d576020820391505b813560e01c4211945060031c600f16841915610b2d578060180282035b80831115610b2b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe88301927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec013560601c833560e01c888203610b24574210159650610b2b9050565b5050610aba565b505b5050505092915050565b60003681610b496101208501856110a8565b91509150600181830103803560001a60801615610b6857602081033593505b505050919050565b600062ffffff823560b081901c82169160e082901c918491610b969160c81c1683610ecf565b9050814211610ba85750909392505050565b804210610bba57506000949350505050565b366000610bcb6101208801886110a8565b915091506001818301036000813560001a6078811660031c6007821692506080821615610bf9576020840393505b6004816018020184039350505086868260050284035b80851115610c95577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb8501803560f01c9990990198947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd013560e81c428a1115610c8b57828a03428481038302908c03860201049b5050610c95565b9250889150610c0f565b5089610ca75780870342880383020499505b505050505050505050919050565b60006040518481528360048201528260248201526020600060448360008a5af19150508015610d01573d8015610cf757600160005114601f3d11169150610cff565b6000863b1191505b505b949350505050565b60008083601f840112610d1b57600080fd5b50813567ffffffffffffffff811115610d3357600080fd5b602083019150836020828501011115610d4b57600080fd5b9250929050565b60008060208385031215610d6557600080fd5b823567ffffffffffffffff811115610d7c57600080fd5b610d8885828601610d09565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610db857600080fd5b919050565b60008060408385031215610dd057600080fd5b610dd983610d94565b946020939093013593505050565b600060208284031215610df957600080fd5b610e0282610d94565b9392505050565b600080600080600060808688031215610e2157600080fd5b610e2a86610d94565b94506020860135935060408601359250606086013567ffffffffffffffff811115610e5457600080fd5b610e6088828901610d09565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610ee257610ee2610ea0565b92915050565b81810381811115610ee257610ee2610ea0565b8082028115828204841417610ee257610ee2610ea0565b600082610f48577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008135818116916014851015610fbc5780818660140360031b1b83161692505b505092915050565b60008085851115610fd457600080fd5b83861115610fe157600080fd5b5050820193919092039150565b73ffffffffffffffffffffffffffffffffffffffff8516815260006020606081840152855180606085015260005b818110156110385787810183015185820160800152820161101c565b506000608082860101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0915081601f820116840190506080848203016040850152846080820152848660a0830137600060a0868301015260a082601f8701168201019250505095945050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110dd57600080fd5b83018035915067ffffffffffffffff8211156110f857600080fd5b602001915036819003821315610d4b57600080fdfea26469706673582212209c7fa27ec20c16ed309e2009a17458ca2682f2e05f31b135d716c14e5c5730f464736f6c6343000811003360c06040523480156200001157600080fd5b5060405162001120380380620011208339810160408190526200003491620001ad565b6200003f3362000066565b6001600160a01b0380841660a05282166080526200005d81620000b6565b50505062000201565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000c062000139565b6001600160a01b0381166200012b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001368162000066565b50565b6000546001600160a01b03163314620001955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000122565b565b6001600160a01b03811681146200013657600080fd5b600080600060608486031215620001c357600080fd5b8351620001d08162000197565b6020850151909350620001e38162000197565b6040850151909250620001f68162000197565b809150509250925092565b60805160a051610ecf620002516000396000818161028b015281816103a0015281816105c101526107780152600081816102070152818161047c0152818161068701526106ca0152610ecf6000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063715018a611610081578063b6b55f251161005b578063b6b55f2514610185578063bfe9173414610198578063f2fde38b146101ab57600080fd5b8063715018a6146101405780638da5cb5b1461014a57806397a2cb641461017257600080fd5b80632f4f21e2116100b25780632f4f21e21461010757806332d323a51461011a5780635886216f1461012d57600080fd5b8063205c2878146100ce5780632e1a7d4d146100f4575b600080fd5b6100e16100dc366004610b65565b6101be565b6040519081526020015b60405180910390f35b6100e1610102366004610b8f565b6101d3565b6100e1610115366004610b65565b6101df565b6100e1610128366004610bf1565b6101eb565b6100e161013b366004610c4b565b610243565b6101486102f8565b005b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100eb565b6100e1610180366004610c95565b61030c565b6100e1610193366004610b8f565b6104a9565b6100e16101a6366004610d78565b6104b5565b6101486101b9366004610c4b565b6104cd565b60006101ca8383610589565b90505b92915050565b60006101cd3383610589565b60006101ca83836106ae565b600061022e73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001684846107e5565b61023885856106ae565b90505b949350505050565b6040517f5886216f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690635886216f90602401602060405180830381865afa1580156102d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101cd9190610dc4565b610300610801565b61030a6000610882565b565b6000610316610801565b815160005b8181101561046157600084828151811061033757610337610ddd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff8082166000818152600190945260408085205490517f5886216f00000000000000000000000000000000000000000000000000000000815260048101929092529294509192917f000000000000000000000000000000000000000000000000000000000000000090911690635886216f90602401602060405180830381865afa1580156103e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040d9190610dc4565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020526040902081905590506104418183610e3b565b61044b9087610e4e565b95505050508061045a90610e61565b905061031b565b506104a373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633846108f7565b50919050565b60006101cd33836106ae565b60006104c3338585856101eb565b90505b9392505050565b6104d5610801565b73ffffffffffffffffffffffffffffffffffffffff811661057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61058681610882565b50565b6040517f85eda2de000000000000000000000000000000000000000000000000000000008152336004820152602481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906385eda2de906044016020604051808303816000875af115801561061f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106439190610dc4565b33600090815260016020526040812080549293508492909190610667908490610e3b565b909155506101cd905073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001684846108f7565b60006106f273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333085610959565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604081208054849290610727908490610e4e565b90915550506040517f3ee5ef1f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490527f00000000000000000000000000000000000000000000000000000000000000001690633ee5ef1f906044016020604051808303816000875af11580156107c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101ca9190610dc4565b6107f08383836109f6565b6107fc576107fc610a9c565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461030a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610574565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610923837fa9059cbb000000000000000000000000000000000000000000000000000000008484610aa8565b6107fc576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006323b872dd60e01b905060006040518281528560048201528460248201528360448201526020600060648360008b5af191505080156109b7573d80156109ad57600160005114601f3d111691506109b5565b6000873b1191505b505b806109ee576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b600060e0829003610a3457610a2d847fd505accf000000000000000000000000000000000000000000000000000000008585610afb565b90506104c6565b610100829003610a6a57610a2d847f8fcbaf0c000000000000000000000000000000000000000000000000000000008585610afb565b6040517f6827585700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040513d6000823e3d81fd5b60006040518481528360048201528260248201526020600060448360008a5af1915050801561023b573d8015610aea57600160005114601f3d11169150610af2565b6000863b1191505b50949350505050565b6000816004016040518581528385600483013760206000838360008b5af192505050801561023b573d8015610aea57600160005114601f3d11169150610af2565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b6057600080fd5b919050565b60008060408385031215610b7857600080fd5b610b8183610b3c565b946020939093013593505050565b600060208284031215610ba157600080fd5b5035919050565b60008083601f840112610bba57600080fd5b50813567ffffffffffffffff811115610bd257600080fd5b602083019150836020828501011115610bea57600080fd5b9250929050565b60008060008060608587031215610c0757600080fd5b610c1085610b3c565b935060208501359250604085013567ffffffffffffffff811115610c3357600080fd5b610c3f87828801610ba8565b95989497509550505050565b600060208284031215610c5d57600080fd5b6101ca82610b3c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020808385031215610ca857600080fd5b823567ffffffffffffffff80821115610cc057600080fd5b818501915085601f830112610cd457600080fd5b813581811115610ce657610ce6610c66565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610d2957610d29610c66565b604052918252848201925083810185019188831115610d4757600080fd5b938501935b82851015610d6c57610d5d85610b3c565b84529385019392850192610d4c565b98975050505050505050565b600080600060408486031215610d8d57600080fd5b83359250602084013567ffffffffffffffff811115610dab57600080fd5b610db786828701610ba8565b9497909650939450505050565b600060208284031215610dd657600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156101cd576101cd610e0c565b808201808211156101cd576101cd610e0c565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610e9257610e92610e0c565b506001019056fea26469706673582212203c4030d8e4fd032251f47f19b257241211e815812cd7d45d8d965652ddf2470e64736f6c634300081100330000000000000000000000001111111254eeb25477b68fb85ed929f73a960582000000000000000000000000111111111117dc0aa78b770fa6a738034120c302Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100725760003560e01c806385eda2de1161005057806385eda2de146100e8578063af15d786146100fb578063ccee33d71461014757600080fd5b80630965d04b146100775780633ee5ef1f1461008c5780635886216f146100b2575b600080fd5b61008a610085366004610d52565b61015a565b005b61009f61009a366004610dbd565b61017d565b6040519081526020015b60405180910390f35b61009f6100c0366004610de7565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61009f6100f6366004610dbd565b61024f565b6101227f000000000000000000000000a0844e046a5b7db55bb8dcdffbf0bbf9c6dc654681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a9565b61009f610155366004610e09565b6102f1565b60408051600080825260208201909252610179918491849133916106db565b5050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0844e046a5b7db55bb8dcdffbf0bbf9c6dc654616146101ee576040517fa454419900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205461021f8282610ecf565b73ffffffffffffffffffffffffffffffffffffffff90931660009081526020819052604090208390555090919050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0844e046a5b7db55bb8dcdffbf0bbf9c6dc654616146102c0576040517fa454419900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205461021f8282610ee8565b60008573ffffffffffffffffffffffffffffffffffffffff81163014610343576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000001111111254eeb25477b68fb85ed929f73a96058216146103b2576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8284017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081810135918290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff40810192918101919060018801908881037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f01907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80810135906298968090610489907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0013582610ecf565b610493908d610efb565b61049d9190610f12565b97506000633b9aca006104bd63ffffffff60808a013560a01c168b610efb565b6104c79190610f12565b905060006104d6866040610ecf565b67ffffffffffffffff8111156104ee576104ee610e71565b6040519080825280601f01601f191660200182016040528015610518576020820181803683370190505b509050602081018688823786018381528a83016020909101527f01000000000000000000000000000000000000000000000000000000000000008c8c60008161056357610563610f4d565b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361064b576105a3602089013589356108a3565b60006105af8587610f7c565b60601c90503660006105c4876014818b610fc4565b915091508273ffffffffffffffffffffffffffffffffffffffff16631944799f6105ef8d6020013590565b8685856040518563ffffffff1660e01b81526004016106119493929190610fee565b600060405180830381600087803b15801561062b57600080fd5b505af115801561063f573d6000803e3d6000fd5b5050505050505061065d565b61065d858560208b01358b35856106db565b81156106885761068873ffffffffffffffffffffffffffffffffffffffff841660808a013584610936565b6106c973ffffffffffffffffffffffffffffffffffffffff84167f0000000000000000000000001111111254eeb25477b68fb85ed929f73a9605828c61099d565b50505050505050505095945050505050565b843585016106e98185610a66565b61071f576040517f4b57606900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061072a82610b37565b905061074766038d7ea4c6800063ffffffff843560901c16610efb565b6107519085610ecf565b9350600061075e83610b70565b90506000845160a06107709190610ecf565b61077b906020610ecf565b90507f0000000000000000000000001111111254eeb25477b68fb85ed929f73a9605826107b1565b8281848460045afa50505050565b60408a013560208101818c0135818d013560601c308114156014831017156107fd577f5b34bf890000000000000000000000000000000000000000000000000000000060005260046000fd5b506040517fe5d7bde60000000000000000000000000000000000000000000000000000000081528c8e600483013785820160048583010152818382010193508a60048501528b60248501526040890135604485015286606485015287608485015289516108718160208d0160a488016107a3565b84810160a40152600081878f016004018183895af1610893573d6000823e3d81fd5b5050505050505050505050505050565b80156101795773ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610909576040517fa7fd379200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff92909216600090815260208190526040902091039055565b610962837fa9059cbb000000000000000000000000000000000000000000000000000000008484610cb5565b610998576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6109c9837f095ea7b3000000000000000000000000000000000000000000000000000000008484610cb5565b610998576109fa837f095ea7b300000000000000000000000000000000000000000000000000000000846000610cb5565b1580610a2f5750610a2d837f095ea7b3000000000000000000000000000000000000000000000000000000008484610cb5565b155b15610998576040517f19be9a9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003681610a786101208601866110a8565b91509150600181830103803560001a6004820391506080811615610a9d576020820391505b813560e01c4211945060031c600f16841915610b2d578060180282035b80831115610b2b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe88301927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec013560601c833560e01c888203610b24574210159650610b2b9050565b5050610aba565b505b5050505092915050565b60003681610b496101208501856110a8565b91509150600181830103803560001a60801615610b6857602081033593505b505050919050565b600062ffffff823560b081901c82169160e082901c918491610b969160c81c1683610ecf565b9050814211610ba85750909392505050565b804210610bba57506000949350505050565b366000610bcb6101208801886110a8565b915091506001818301036000813560001a6078811660031c6007821692506080821615610bf9576020840393505b6004816018020184039350505086868260050284035b80851115610c95577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb8501803560f01c9990990198947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd013560e81c428a1115610c8b57828a03428481038302908c03860201049b5050610c95565b9250889150610c0f565b5089610ca75780870342880383020499505b505050505050505050919050565b60006040518481528360048201528260248201526020600060448360008a5af19150508015610d01573d8015610cf757600160005114601f3d11169150610cff565b6000863b1191505b505b949350505050565b60008083601f840112610d1b57600080fd5b50813567ffffffffffffffff811115610d3357600080fd5b602083019150836020828501011115610d4b57600080fd5b9250929050565b60008060208385031215610d6557600080fd5b823567ffffffffffffffff811115610d7c57600080fd5b610d8885828601610d09565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610db857600080fd5b919050565b60008060408385031215610dd057600080fd5b610dd983610d94565b946020939093013593505050565b600060208284031215610df957600080fd5b610e0282610d94565b9392505050565b600080600080600060808688031215610e2157600080fd5b610e2a86610d94565b94506020860135935060408601359250606086013567ffffffffffffffff811115610e5457600080fd5b610e6088828901610d09565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610ee257610ee2610ea0565b92915050565b81810381811115610ee257610ee2610ea0565b8082028115828204841417610ee257610ee2610ea0565b600082610f48577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008135818116916014851015610fbc5780818660140360031b1b83161692505b505092915050565b60008085851115610fd457600080fd5b83861115610fe157600080fd5b5050820193919092039150565b73ffffffffffffffffffffffffffffffffffffffff8516815260006020606081840152855180606085015260005b818110156110385787810183015185820160800152820161101c565b506000608082860101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0915081601f820116840190506080848203016040850152846080820152848660a0830137600060a0868301015260a082601f8701168201019250505095945050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110dd57600080fd5b83018035915067ffffffffffffffff8211156110f857600080fd5b602001915036819003821315610d4b57600080fdfea26469706673582212209c7fa27ec20c16ed309e2009a17458ca2682f2e05f31b135d716c14e5c5730f464736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001111111254eeb25477b68fb85ed929f73a960582000000000000000000000000111111111117dc0aa78b770fa6a738034120c302
-----Decoded View---------------
Arg [0] : limitOrderProtocol (address): 0x1111111254EEB25477B68fb85Ed929f73A960582
Arg [1] : token (address): 0x111111111117dC0aa78b770fA6A738034120C302
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000001111111254eeb25477b68fb85ed929f73a960582
Arg [1] : 000000000000000000000000111111111117dc0aa78b770fa6a738034120c302Loading...LoadingLoading...Loading
Loading...Loading
Loading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingMultichain Portfolio | 30 Chains
Chain Token Portfolio % Price Amount Value ETH 11.23% $0.000001 36,527,895.8978 $24.97 ETH 6.79% $3,548.23 0.00425174 $15.09 ETH 6.77% $3.98 3.7844 $15.05 ETH 5.51% $3,440.92 0.00355934 $12.25 ETH 4.51% $526.76 0.019 $10.03 ETH 3.94% $3,476.01 0.00251805 $8.75 ETH 3.93% $98,333 0.00008881 $8.73 ETH 3.74% $0.639592 12.9942 $8.31 ETH 3.70% $0.840277 9.7974 $8.23 ETH 3.03% $0.061015 110.3115 $6.73 ETH 2.86% $0.000235 27,008.5807 $6.36 ETH 2.58% $5.63 1.0173 $5.73 ETH 2.56% $163.43 0.0348 $5.69 ETH 2.47% $0.000909 6,029.7524 $5.48 ETH 2.42% $0.01845 291.4162 $5.38 ETH 2.32% $0.030921 166.4424 $5.15 ETH 2.27% $0.600247 8.4016 $5.04 ETH 2.02% $0.996626 4.498 $4.48 ETH 1.85% $0.999859 4.112 $4.11 ETH 1.80% $3,365.5 0.00118541 $3.99 ETH 1.63% <$0.000001 186,738,158.7996 $3.63 ETH 1.63% $0.997415 3.6244 $3.62 ETH 1.32% $156.54 0.0188 $2.94 ETH 1.23% $1 2.7365 $2.74 ETH 1.19% <$0.000001 1,436,533,059.6542 $2.64 ETH 1.01% $0.250221 8.9572 $2.24 ETH 0.99% $0.000028 78,679.7888 $2.19 ETH 0.97% $3,730.58 0.00057513 $2.15 ETH 0.94% $0.068113 30.6776 $2.09 ETH 0.90% $0.210115 9.4754 $1.99 ETH 0.75% $0.183599 9.1109 $1.67 ETH 0.70% $0.00105 1,479.428 $1.55 ETH 0.70% $0.144824 10.711 $1.55 ETH 0.60% $0.204335 6.5293 $1.33 ETH 0.53% $0.000021 55,051.983 $1.18 ETH 0.48% $0.000296 3,609.526 $1.07 ETH 0.43% $6.29 0.1512 $0.9509 ETH 0.38% <$0.000001 184,848,164.7694 $0.8551 ETH 0.36% $3,361.45 0.00023824 $0.8008 ETH 0.36% $0.033229 24.0563 $0.7993 ETH 0.32% $0.150226 4.7932 $0.72 ETH 0.30% $0.804642 0.8388 $0.6749 ETH 0.30% <$0.000001 5,717,176.0041 $0.6725 ETH 0.26% $3,370.94 0.00017415 $0.587 ETH 0.24% $1.15 0.4672 $0.5372 ETH 0.23% $0.014023 36.4747 $0.5114 ETH 0.23% $64.81 0.00785654 $0.5091 ETH 0.20% $8.29 0.0536 $0.4445 ETH 0.20% $0.320332 1.3656 $0.4374 ETH 0.20% $0.013712 31.7236 $0.4349 ETH 0.18% $0.006845 59.7655 $0.409 ETH 0.18% $32.22 0.0125 $0.4011 ETH 0.18% $258.02 0.00154688 $0.3991 ETH 0.18% $0.082394 4.8043 $0.3958 ETH 0.17% $3,617.31 0.00010248 $0.3707 ETH 0.17% $0.810889 0.457 $0.3705 ETH 0.16% $0.612357 0.5968 $0.3654 ETH 0.16% <$0.000001 7,546,638.2637 $0.3478 ETH 0.15% $11.54 0.0289 $0.3331 ETH 0.14% $0.000001 564,567.8395 $0.3214 ETH 0.14% $0.0021 147.1384 $0.3089 ETH 0.13% $0.000002 179,937.0653 $0.2896 ETH 0.12% <$0.000001 767,961.7474 $0.2681 ETH 0.12% $0.000006 46,438.6627 $0.2656 ETH 0.10% $3.03 0.0748 $0.2266 ETH 0.10% $0.000007 30,052.9831 $0.2145 ETH 0.09% $0.02276 9.2658 $0.2108 ETH 0.09% $0.135184 1.4601 $0.1973 ETH 0.08% $0.002345 74.1274 $0.1738 ETH 0.07% $0.000027 6,199.6854 $0.1662 ETH 0.07% <$0.000001 1,454,294.1807 $0.1641 ETH 0.07% $0.078824 1.9809 $0.1561 ETH 0.07% <$0.000001 257,039,698.9939 $0.1523 ETH 0.07% $0.050192 3 $0.1505 ETH 0.06% $0.039982 3.5895 $0.1435 ETH 0.06% $0.389096 0.3677 $0.143 ETH 0.06% $0.028276 4.8116 $0.136 ETH 0.06% $0.014729 9.0829 $0.1337 ETH 0.06% $0.014856 8.5894 $0.1276 ETH 0.05% $0.001938 56.2956 $0.1091 ARB 0.52% $0.000582 2,000 $1.16 BASE 0.26% <$0.000001 11,111,111 $0.5677 POL <0.01% $0.543152 0.0043 $0.002336 Loading...Loading[ Download: CSV Export ][ Download: CSV Export ]A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.
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.SignIn
Address Cards
To use this feature, please login to your Etherscan account and return to this page.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.