Source Code
Latest 25 from a total of 7,879 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap With Magpie... | 137725562 | 5 mins ago | IN | 0 ETH | 0.000000191165 | ||||
Swap With Magpie... | 137725463 | 8 mins ago | IN | 0 ETH | 0.000000136437 | ||||
Swap With Magpie... | 137725368 | 11 mins ago | IN | 0 ETH | 0.000000535216 | ||||
Swap With Magpie... | 137725178 | 17 mins ago | IN | 0 ETH | 0.000001844467 | ||||
Swap With Magpie... | 137724844 | 29 mins ago | IN | 0 ETH | 0.000000215835 | ||||
Swap With Magpie... | 137724826 | 29 mins ago | IN | 0 ETH | 0.000000209473 | ||||
Swap With Magpie... | 137724809 | 30 mins ago | IN | 0 ETH | 0.00000027399 | ||||
Swap With Magpie... | 137724775 | 31 mins ago | IN | 0 ETH | 0.000000817333 | ||||
Swap With Magpie... | 137724549 | 38 mins ago | IN | 0 ETH | 0.000000423903 | ||||
Swap With Magpie... | 137724535 | 39 mins ago | IN | 0 ETH | 0.000000459053 | ||||
Swap With Magpie... | 137724491 | 40 mins ago | IN | 0 ETH | 0.000000467296 | ||||
Swap With Magpie... | 137724387 | 44 mins ago | IN | 0 ETH | 0.000000573207 | ||||
Swap With Magpie... | 137724206 | 50 mins ago | IN | 0.00225 ETH | 0.000000515911 | ||||
Swap With Magpie... | 137723643 | 1 hr ago | IN | 0 ETH | 0.000000715734 | ||||
Swap With Magpie... | 137723632 | 1 hr ago | IN | 0 ETH | 0.000000870702 | ||||
Swap With Magpie... | 137723288 | 1 hr ago | IN | 0 ETH | 0.000002671817 | ||||
Swap With Magpie... | 137723272 | 1 hr ago | IN | 0 ETH | 0.000000409523 | ||||
Swap With Magpie... | 137722787 | 1 hr ago | IN | 0 ETH | 0.000000514739 | ||||
Swap With Magpie... | 137722701 | 1 hr ago | IN | 0 ETH | 0.000000756126 | ||||
Swap With Magpie... | 137722692 | 1 hr ago | IN | 0 ETH | 0.000000079095 | ||||
Swap With Magpie... | 137722651 | 1 hr ago | IN | 0 ETH | 0.000000534473 | ||||
Swap With Magpie... | 137722642 | 1 hr ago | IN | 0 ETH | 0.000000105661 | ||||
Swap With Magpie... | 137722590 | 1 hr ago | IN | 0 ETH | 0.000000555457 | ||||
Swap With Magpie... | 137721228 | 2 hrs ago | IN | 0 ETH | 0.000000571623 | ||||
Swap With Magpie... | 137720971 | 2 hrs ago | IN | 0 ETH | 0.000000315793 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
137724206 | 50 mins ago | 0.002244375 ETH | ||||
137724206 | 50 mins ago | 0.000005625 ETH | ||||
137721272 | 2 hrs ago | 0.0003 ETH | ||||
137721272 | 2 hrs ago | 0.0003 ETH | ||||
137719714 | 3 hrs ago | 0.001665825 ETH | ||||
137719714 | 3 hrs ago | 0.000004175 ETH | ||||
137719702 | 3 hrs ago | 0.00161595 ETH | ||||
137719702 | 3 hrs ago | 0.00000405 ETH | ||||
137718330 | 4 hrs ago | 0.00009975 ETH | ||||
137718330 | 4 hrs ago | 0.00000025 ETH | ||||
137718279 | 4 hrs ago | 0.00009975 ETH | ||||
137718279 | 4 hrs ago | 0.00000025 ETH | ||||
137718214 | 4 hrs ago | 0.00009975 ETH | ||||
137718214 | 4 hrs ago | 0.00000025 ETH | ||||
137715715 | 5 hrs ago | 0.001995 ETH | ||||
137715715 | 5 hrs ago | 0.000005 ETH | ||||
137712206 | 7 hrs ago | 0.0057855 ETH | ||||
137712206 | 7 hrs ago | 0.0000145 ETH | ||||
137699734 | 14 hrs ago | 0.000895201185595 ETH | ||||
137699734 | 14 hrs ago | 0.000002243611993 ETH | ||||
137698681 | 15 hrs ago | 0.00788025 ETH | ||||
137698681 | 15 hrs ago | 0.00001975 ETH | ||||
137696802 | 16 hrs ago | 0.00608475 ETH | ||||
137696802 | 16 hrs ago | 0.00001525 ETH | ||||
137688048 | 20 hrs ago | 0.0129675 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
MagpieRouterV3_1
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {Ownable2Step} from "openzeppelin-solidity/contracts/access/Ownable2Step.sol"; import {Pausable} from "openzeppelin-solidity/contracts/security/Pausable.sol"; import {Address} from "openzeppelin-solidity/contracts/utils/Address.sol"; import {IMagpieRouterV3_1} from "./interfaces/IMagpieRouterV3_1.sol"; import {LibAsset} from "./libraries/LibAsset.sol"; import {LibRouter, SwapData} from "./libraries/LibRouter.sol"; error InvalidCall(); error InvalidCaller(); error InvalidAmountIn(); error InvalidNativeAmount(); contract MagpieRouterV3_1 is IMagpieRouterV3_1, Ownable2Step, Pausable { using LibAsset for address; mapping(address => bool) public internalCaller; address public coreAddress; address public swapFeeAddress; /// @dev Restricts swap functions with signatures to only be called by whitelisted internal caller. modifier onlyInternalCaller() { if (!internalCaller[msg.sender]) { revert InvalidCaller(); } _; } /// @dev See {IMagpieRouterV3-updateRouterAddress} function updateCoreAddress(address value) external onlyOwner { coreAddress = value; } /// @dev See {IMagpieRouterV3-updateSwapFeeAddress} function updateSwapFeeAddress(address value) external onlyOwner { swapFeeAddress = value; } /// @dev See {IMagpieRouterV3-updateInternalCaller} function updateInternalCaller(address caller, bool value) external onlyOwner { internalCaller[caller] = value; emit UpdateInternalCaller(msg.sender, caller, value); } /// @dev See {IMagpieRouterV3-pause} function pause() public onlyOwner whenNotPaused { _pause(); } /// @dev See {IMagpieRouterV3-unpause} function unpause() public onlyOwner whenPaused { _unpause(); } /// @dev See {IMagpieRouterV3-multicall} function multicall(bytes[] calldata data) external onlyOwner returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { results[i] = Address.functionDelegateCall(address(this), data[i]); } return results; } /// @dev Verifies the signature for a swap operation. /// @param swapData The data structure containing information about the swap. /// @param useCaller Boolean indicating whether to use the caller's address. /// @return fromAddress The address to be used for the swap operation. function verifySignature(SwapData memory swapData, bool useCaller) private view returns (address fromAddress) { bool hasAffiliate = swapData.hasAffiliate; uint256 messagePtr; uint256 messageLength = hasAffiliate ? 384 : 320; assembly { messagePtr := mload(0x40) mstore(0x40, add(messagePtr, messageLength)) switch hasAffiliate case 1 { // keccak256("Swap(address router,address sender,address recipient,address fromAsset,address toAsset,uint256 deadline,uint256 amountOutMin,uint256 swapFee,uint256 amountIn,address affiliate,uint256 affiliateFee)") mstore(messagePtr, 0x64d67eff2ff010acba1b1df82fb327ba0dc6d2965ba6b0b472bc14c494c8b4f6) } default { // keccak256("Swap(address router,address sender,address recipient,address fromAsset,address toAsset,uint256 deadline,uint256 amountOutMin,uint256 swapFee,uint256 amountIn)") mstore(messagePtr, 0x783528850c43ab6adcc3a843186a6558aa806707dd0abb3d2909a2a70b7f22a3) } } fromAddress = LibRouter.verifySignature( // keccak256(bytes("Magpie Router")), 0x86af987965544521ef5b52deabbeb812d3353977e11a2dbe7e0f4905d1e60721, // keccak256(bytes("3")), 0x2a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de, swapData, messagePtr, messageLength, useCaller, 2 ); } /// @dev Swaps tokens based on the provided swap data. /// @param swapData The data structure containing information about the swap operation. /// @param fromAddress The address initiating the swap. This address is responsible for the input assets. /// @return amountOut The amount of tokens or assets received after the swap. /// @return gasUsed The amount of gas consumed by the recorded operation. function swap( SwapData memory swapData, address fromAddress, uint256 fullAmountIn ) private returns (uint256 amountOut, uint256 gasUsed) { if (swapData.fromAssetAddress.isNative()) { if (msg.value < (swapData.amountIn + swapData.swapFee + swapData.affiliateFee)) { revert InvalidAmountIn(); } } uint256 nativeAmount = 0; if (swapData.fromAssetAddress.isNative()) { nativeAmount = swapData.amountIn; } else { swapData.fromAssetAddress.transferFrom(fromAddress, address(this), swapData.amountIn); swapData.fromAssetAddress.approve(coreAddress, swapData.amountIn); } address currentCoreAddress = coreAddress; assembly { let success := 0 let inputPtr := mload(0x40) let inputLength := add(calldataload(36), 68) let payloadLength := sub(inputLength, 68) mstore(0x40, add(inputPtr, inputLength)) mstore(inputPtr, 0x158f689400000000000000000000000000000000000000000000000000000000) // swapWithoutSignature mstore(add(inputPtr, 4), 32) mstore(add(inputPtr, 36), payloadLength) let outputPtr := mload(0x40) mstore(0x40, add(outputPtr, 64)) calldatacopy(add(inputPtr, 68), 68, payloadLength) success := call(gas(), currentCoreAddress, nativeAmount, inputPtr, inputLength, outputPtr, 64) if eq(success, 1) { amountOut := mload(outputPtr) gasUsed := mload(add(outputPtr, 32)) } if eq(success, 0) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } emit Swap( fromAddress, swapData.toAddress, swapData.fromAssetAddress, swapData.toAssetAddress, fullAmountIn, amountOut ); } /// @dev See {IMagpieRouterV3-estimateSwapGas} function estimateSwapGas( bytes calldata ) external payable whenNotPaused returns (uint256 amountOut, uint256 gasUsed) { SwapData memory swapData = LibRouter.getData(); address fromAddress = verifySignature(swapData, true); if (swapData.hasPermit) { LibRouter.permit(swapData, fromAddress); } LibRouter.transferFees(swapData, fromAddress, swapData.swapFee == 0 ? address(0) : swapFeeAddress); (amountOut, gasUsed) = swap( swapData, fromAddress, swapData.amountIn + swapData.swapFee + swapData.affiliateFee ); } /// @dev See {IMagpieRouterV3-swapWithMagpieSignature} function swapWithMagpieSignature(bytes calldata) external payable whenNotPaused returns (uint256 amountOut) { SwapData memory swapData = LibRouter.getData(); address fromAddress = verifySignature(swapData, true); if (swapData.hasPermit) { LibRouter.permit(swapData, fromAddress); } LibRouter.transferFees(swapData, fromAddress, swapData.swapFee == 0 ? address(0) : swapFeeAddress); (amountOut, ) = swap(swapData, fromAddress, swapData.amountIn + swapData.swapFee + swapData.affiliateFee); } /// @dev See {IMagpieRouterV3-swapWithUserSignature} function swapWithUserSignature(bytes calldata) external payable onlyInternalCaller returns (uint256 amountOut) { SwapData memory swapData = LibRouter.getData(); if (msg.value > 0) { revert InvalidNativeAmount(); } address fromAddress = verifySignature(swapData, false); if (swapData.hasPermit) { LibRouter.permit(swapData, fromAddress); } LibRouter.transferFees(swapData, fromAddress, swapData.swapFee == 0 ? address(0) : swapFeeAddress); (amountOut, ) = swap(swapData, fromAddress, swapData.amountIn + swapData.swapFee + swapData.affiliateFee); } /// @dev Used to receive ethers receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; interface IMagpieRouterV3_1 { event UpdateInternalCaller(address indexed sender, address caller, bool value); /// @dev Allows the owner to update the whitelisted internal callers. /// @param caller Caller address. /// @param value Disable or enable the related caller. function updateInternalCaller(address caller, bool value) external; /// @dev Allows the owner to update the swap fee receiver. /// @param value Swap fee receiver address. function updateSwapFeeAddress(address value) external; /// @dev Allows the owner to update the magpire router core address. /// @param value Magpie core address. function updateCoreAddress(address value) external; /// @dev Called by the owner to pause, triggers stopped state. function pause() external; /// @dev Called by the owner to unpause, returns to normal state. function unpause() external; event Swap( address indexed fromAddress, address indexed toAddress, address fromAssetAddress, address toAssetAddress, uint256 amountIn, uint256 amountOut ); /// @dev Makes it possible to execute multiple functions in the same transaction. function multicall(bytes[] calldata data) external returns (bytes[] memory results); /// @dev Provides an external interface to estimate the gas cost of the last hop in a route. /// @return amountOut The amount received after swapping. /// @return gasUsed The cost of gas while performing the swap. function estimateSwapGas(bytes calldata swapArgs) external payable returns (uint256 amountOut, uint256 gasUsed); /// @dev Performs token swap with magpie signature. /// @return amountOut The amount received after swapping. function swapWithMagpieSignature(bytes calldata swapArgs) external payable returns (uint256 amountOut); /// @dev Performs token swap with a user signature. /// @return amountOut The amount received after swapping. function swapWithUserSignature(bytes calldata swapArgs) external payable returns (uint256 amountOut); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; interface IWETH { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import "../interfaces/IWETH.sol"; error AssetNotReceived(); error ApprovalFailed(); error TransferFromFailed(); error TransferFailed(); error FailedWrap(); error FailedUnwrap(); library LibAsset { using LibAsset for address; address constant NATIVE_ASSETID = address(0); /// @dev Checks if the given address (self) represents a native asset (Ether). /// @param self The asset that will be checked for a native token. /// @return Flag to identify if the asset is native or not. function isNative(address self) internal pure returns (bool) { return self == NATIVE_ASSETID; } /// @dev Wraps the specified asset. /// @param self The asset that will be wrapped. function wrap(address self, uint256 amount) internal { uint256 ptr; assembly { ptr := mload(0x40) mstore(0x40, add(ptr, 4)) mstore(ptr, 0xd0e30db000000000000000000000000000000000000000000000000000000000) } if (!execute(self, amount, ptr, 4, 0, 0)) { revert FailedWrap(); } } /// @dev Unwraps the specified asset. /// @param self The asset that will be unwrapped. function unwrap(address self, uint256 amount) internal { uint256 ptr; assembly { ptr := mload(0x40) mstore(0x40, add(ptr, 36)) mstore(ptr, 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000) mstore(add(ptr, 4), amount) } if (!execute(self, 0, ptr, 36, 0, 0)) { revert FailedUnwrap(); } } /// @dev Retrieves the balance of the current contract for a given asset (self). /// @param self Asset whose balance needs to be found. /// @return Balance of the specific asset. function getBalance(address self) internal view returns (uint256) { return getBalanceOf(self, address(this)); } /// @dev Retrieves the balance of the target address for a given asset (self). /// @param self Asset whose balance needs to be found. /// @param targetAddress The address where the balance is checked from. /// @return amount Balance of the specific asset. function getBalanceOf(address self, address targetAddress) internal view returns (uint256 amount) { assembly { switch self case 0 { amount := balance(targetAddress) } default { let currentInputPtr := mload(0x40) mstore(0x40, add(currentInputPtr, 68)) mstore(currentInputPtr, 0x70a0823100000000000000000000000000000000000000000000000000000000) mstore(add(currentInputPtr, 4), targetAddress) let currentOutputPtr := add(currentInputPtr, 36) if iszero(staticcall(gas(), self, currentInputPtr, 36, currentOutputPtr, 32)) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } amount := mload(currentOutputPtr) } } } /// @dev Performs a safe transferFrom operation for a given asset (self) from one address (from) to another address (to). /// @param self Asset that will be transferred. /// @param from Address that will send the asset. /// @param to Address that will receive the asset. /// @param amount Transferred amount. function transferFrom(address self, address from, address to, uint256 amount) internal { uint256 ptr; assembly { ptr := mload(0x40) mstore(0x40, add(ptr, 100)) mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(ptr, 4), from) mstore(add(ptr, 36), to) mstore(add(ptr, 68), amount) } if (!execute(self, 0, ptr, 100, 0, 0)) { revert TransferFromFailed(); } } /// @dev Transfers a given amount of an asset (self) to a recipient address (recipient). /// @param self Asset that will be transferred. /// @param recipient Address that will receive the transferred asset. /// @param amount Transferred amount. function transfer(address self, address recipient, uint256 amount) internal { if (self.isNative()) { (bool success, ) = payable(recipient).call{value: amount}(""); if (!success) { revert TransferFailed(); } } else { uint256 ptr; assembly { ptr := mload(0x40) mstore(0x40, add(ptr, 68)) mstore(ptr, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(ptr, 4), recipient) mstore(add(ptr, 36), amount) } if (!execute(self, 0, ptr, 68, 0, 0)) { revert TransferFailed(); } } } /// @dev Approves a spender address (spender) to spend a specified amount of an asset (self). /// @param self The asset that will be approved. /// @param spender Address of a contract that will spend the owners asset. /// @param amount Asset amount that can be spent. function approve(address self, address spender, uint256 amount) internal { uint256 ptr; assembly { ptr := mload(0x40) mstore(0x40, add(ptr, 68)) mstore(ptr, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(ptr, 4), spender) mstore(add(ptr, 36), amount) } if (!execute(self, 0, ptr, 68, 0, 0)) { assembly { mstore(add(ptr, 36), 0) } if (!execute(self, 0, ptr, 68, 0, 0)) { revert ApprovalFailed(); } assembly { mstore(add(ptr, 36), amount) } if (!execute(self, 0, ptr, 68, 0, 0)) { revert ApprovalFailed(); } } } function permit( address self, address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { assembly { let ptr := mload(0x40) mstore(0x40, add(ptr, 228)) mstore(ptr, 0xd505accf00000000000000000000000000000000000000000000000000000000) mstore(add(ptr, 4), owner) mstore(add(ptr, 36), spender) mstore(add(ptr, 68), amount) mstore(add(ptr, 100), deadline) mstore(add(ptr, 132), v) mstore(add(ptr, 164), r) mstore(add(ptr, 196), s) let success := call(gas(), self, 0, ptr, 228, 0, 0) } } /// @dev Determines if a call was successful. /// @param target Address of the target contract. /// @param success To check if the call to the contract was successful or not. /// @param data The data was sent while calling the target contract. /// @return result The success of the call. function isSuccessful(address target, bool success, bytes memory data) private view returns (bool result) { if (success) { if (data.length == 0) { // isContract if (target.code.length > 0) { result = true; } } else { assembly { result := mload(add(data, 32)) } } } } /// @dev Executes a low level call. function execute( address self, uint256 currentNativeAmount, uint256 currentInputPtr, uint256 currentInputLength, uint256 currentOutputPtr, uint256 outputLength ) internal returns (bool result) { assembly { function isSuccessfulCall(targetAddress) -> isSuccessful { switch iszero(returndatasize()) case 1 { if gt(extcodesize(targetAddress), 0) { isSuccessful := 1 } } case 0 { returndatacopy(0, 0, 32) isSuccessful := gt(mload(0), 0) } } if iszero( call( gas(), self, currentNativeAmount, currentInputPtr, currentInputLength, currentOutputPtr, outputLength ) ) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } result := isSuccessfulCall(self) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {LibAsset} from "../libraries/LibAsset.sol"; struct SwapData { address toAddress; address fromAssetAddress; address toAssetAddress; uint256 deadline; uint256 amountOutMin; uint256 swapFee; uint256 amountIn; bool hasPermit; bool hasAffiliate; address affiliateAddress; uint256 affiliateFee; } error InvalidSignature(); error ExpiredTransaction(); library LibRouter { using LibAsset for address; /// @dev Prepares SwapData from calldata function getData() internal view returns (SwapData memory swapData) { // dataOffset: 68 + 2 assembly { let deadline := shr( shr(248, calldataload(132)), // dataOffset + 62 calldataload(shr(240, calldataload(133))) // dataOffset + 62 + 1 ) if lt(deadline, timestamp()) { // ExpiredTransaction mstore(0, 0x931997cf00000000000000000000000000000000000000000000000000000000) revert(0, 4) } mstore(swapData, shr(96, calldataload(72))) // toAddress / dataOffset + 2 mstore(add(swapData, 32), shr(96, calldataload(92))) // fromAssetAddress / dataOffset + 22 mstore(add(swapData, 64), shr(96, calldataload(112))) // toAssetAddress / dataOffset + 42 mstore(add(swapData, 96), deadline) mstore( add(swapData, 128), shr( shr(248, calldataload(135)), // dataOffset + 62 + 3 calldataload(shr(240, calldataload(136))) // dataOffset + 62 + 4 ) ) // amountOutMin mstore( add(swapData, 160), shr( shr(248, calldataload(138)), // dataOffset + 62 + 6 calldataload(shr(240, calldataload(139))) // dataOffset + 62 + 7 ) ) // swapFee mstore( add(swapData, 192), shr( shr(248, calldataload(141)), // dataOffset + 62 + 9 calldataload(shr(240, calldataload(142))) // dataOffset + 62 + 10 ) ) // amountIn // calldataload(144) // r // calldataload(176) // s // shr(248, calldataload(208)) // v let hasPermit := gt(shr(248, calldataload(209)), 0) // permit v mstore(add(swapData, 224), hasPermit) // hasPermit // calldataload(210) // permit r // calldataload(242) // permit s // calldataload(274) // permit deadline switch hasPermit case 1 { let hasAffiliate := shr(248, calldataload(277)) mstore(add(swapData, 256), hasAffiliate) // hasAffiliate if eq(hasAffiliate, 1) { mstore(add(swapData, 288), shr(96, calldataload(278))) // affiliateAddress mstore( add(swapData, 320), shr(shr(248, calldataload(298)), calldataload(shr(240, calldataload(299)))) ) // affiliateFee } } default { let hasAffiliate := shr(248, calldataload(210)) mstore(add(swapData, 256), hasAffiliate) // hasAffiliate if eq(hasAffiliate, 1) { mstore(add(swapData, 288), shr(96, calldataload(211))) // affiliateAddress mstore( add(swapData, 320), shr(shr(248, calldataload(231)), calldataload(shr(240, calldataload(232)))) ) // affiliateFee } } } } /// @dev Transfers the required fees for the swap operation from the user's account. /// @param swapData The data structure containing the details of the swap operation, including fee information. /// @param fromAddress The address of the user from whom the fees will be deducted. /// @param swapFeeAddress The address of the swap fee receiver. function transferFees(SwapData memory swapData, address fromAddress, address swapFeeAddress) internal { if (swapData.swapFee > 0) { if (swapData.fromAssetAddress.isNative()) { swapData.fromAssetAddress.transfer(swapFeeAddress, swapData.swapFee); } else { swapData.fromAssetAddress.transferFrom(fromAddress, swapFeeAddress, swapData.swapFee); } } if (swapData.affiliateFee > 0) { if (swapData.fromAssetAddress.isNative()) { swapData.fromAssetAddress.transfer(swapData.affiliateAddress, swapData.affiliateFee); } else { swapData.fromAssetAddress.transferFrom(fromAddress, swapData.affiliateAddress, swapData.affiliateFee); } } } /// @dev Grants permission for the user's asset to be used in a swap operation. /// @param swapData The data structure containing the details of the swap operation. /// @param fromAddress The address of the user who is granting permission for their asset to be used. function permit(SwapData memory swapData, address fromAddress) internal { uint8 v; bytes32 r; bytes32 s; uint256 deadline; assembly { v := shr(248, calldataload(209)) r := calldataload(210) s := calldataload(242) deadline := shr(shr(248, calldataload(274)), calldataload(shr(240, calldataload(275)))) } swapData.fromAssetAddress.permit( fromAddress, address(this), swapData.amountIn + swapData.swapFee + swapData.affiliateFee, deadline, v, r, s ); } /// @dev Recovers the signer's address from a hashed message and signature components. /// @param hash The hash of the message that was signed. /// @param r The `r` component of the signature. /// @param s The `s` component of the signature. /// @param v The `v` component of the signature. /// @return signer The address of the signer recovered from the signature. function recoverSigner(bytes32 hash, bytes32 r, bytes32 s, uint8 v) private pure returns (address signer) { // 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. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { revert InvalidSignature(); } if (v != 27 && v != 28) { revert InvalidSignature(); } signer = ecrecover(hash, v, r, s); if (signer == address(0)) { revert InvalidSignature(); } } function getDomainSeparator(bytes32 name, bytes32 version) private view returns (bytes32) { uint256 chainId; assembly { chainId := chainid() } return keccak256( abi.encode( // keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)") 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f, name, version, chainId, address(this) ) ); } /// @dev Verifies the signature for a swap operation. /// @param swapData The SwapData struct containing swap details. /// @param messagePtr Pointer to the message data in memory. /// @param messageLength Length of the message data. /// @param useCaller Flag indicating whether to use the caller's address for verification. /// @param internalCallersSlot Slot in the internal callers storage for verification. /// @return fromAddress The address of the signer / or caller if the signature is valid. function verifySignature( bytes32 name, bytes32 version, SwapData memory swapData, uint256 messagePtr, uint256 messageLength, bool useCaller, uint8 internalCallersSlot ) internal view returns (address fromAddress) { bytes32 domainSeparator = getDomainSeparator(name, version); bytes32 digest; bytes32 r; bytes32 s; uint8 v; assembly { mstore(add(messagePtr, 32), address()) mstore(add(messagePtr, 64), caller()) mstore(add(messagePtr, 96), mload(swapData)) mstore(add(messagePtr, 128), mload(add(swapData, 32))) mstore(add(messagePtr, 160), mload(add(swapData, 64))) mstore(add(messagePtr, 192), mload(add(swapData, 96))) mstore(add(messagePtr, 224), mload(add(swapData, 128))) mstore(add(messagePtr, 256), mload(add(swapData, 160))) mstore(add(messagePtr, 288), mload(add(swapData, 192))) // hasAffiliate if eq(mload(add(swapData, 256)), 1) { mstore(add(messagePtr, 320), mload(add(swapData, 288))) mstore(add(messagePtr, 352), mload(add(swapData, 320))) } let hash := keccak256(messagePtr, messageLength) messagePtr := mload(0x40) mstore(0x40, add(messagePtr, 66)) mstore(messagePtr, "\x19\x01") mstore(add(messagePtr, 2), domainSeparator) mstore(add(messagePtr, 34), hash) digest := keccak256(messagePtr, 66) r := calldataload(144) s := calldataload(176) v := shr(248, calldataload(208)) } if (useCaller) { address internalCaller = recoverSigner(digest, r, s, v); assembly { fromAddress := caller() mstore(0, internalCaller) mstore(0x20, internalCallersSlot) if iszero(eq(sload(keccak256(0, 0x40)), 1)) { // InvalidSignature mstore(0, 0x8baa579f00000000000000000000000000000000000000000000000000000000) revert(0, 4) } } } else { fromAddress = recoverSigner(digest, r, s, v); if (fromAddress == address(this)) { revert InvalidSignature(); } } } }
// 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. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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 (last updated v4.8.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; import "./Ownable.sol"; /** * @dev Contract module which provides 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} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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; } }
{ "evmVersion": "paris", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"ApprovalFailed","type":"error"},{"inputs":[],"name":"InvalidAmountIn","type":"error"},{"inputs":[],"name":"InvalidCaller","type":"error"},{"inputs":[],"name":"InvalidNativeAmount","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"TransferFromFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"address","name":"fromAssetAddress","type":"address"},{"indexed":false,"internalType":"address","name":"toAssetAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"UpdateInternalCaller","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"coreAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"estimateSwapGas","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"internalCaller","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapFeeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"swapWithMagpieSignature","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"swapWithUserSignature","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"value","type":"address"}],"name":"updateCoreAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"updateInternalCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"value","type":"address"}],"name":"updateSwapFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001a3361002c565b6001805460ff60a01b19169055610098565b600180546001600160a01b031916905561004581610048565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6118f8806100a76000396000f3fe60806040526004361061010d5760003560e01c806373fc4457116100955780638da5cb5b116100645780638da5cb5b146102c7578063ac9650d8146102e5578063b8f38c7414610312578063e30c397814610332578063f2fde38b1461035057600080fd5b806373fc44571461026257806379ba50971461027557806383bf23211461028a5780638456cb59146102b257600080fd5b80633f4ba83a116100dc5780633f4ba83a146101b9578063519a98e0146101ce57806357f46a1a146101ee5780635c975abb1461022e578063715018a61461024d57600080fd5b80631c0ad646146101195780631ec4aec81461015657806325e651ed14610176578063364f9cf81461019757600080fd5b3661011457005b600080fd5b34801561012557600080fd5b50600354610139906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561016257600080fd5b50600454610139906001600160a01b031681565b6101896101843660046115d5565b610370565b60405190815260200161014d565b3480156101a357600080fd5b506101b76101b2366004611663565b61044f565b005b3480156101c557600080fd5b506101b7610479565b3480156101da57600080fd5b506101b76101e936600461167e565b610493565b3480156101fa57600080fd5b5061021e610209366004611663565b60026020526000908152604090205460ff1681565b604051901515815260200161014d565b34801561023a57600080fd5b50600154600160a01b900460ff1661021e565b34801561025957600080fd5b506101b7610500565b6101896102703660046115d5565b610512565b34801561028157600080fd5b506101b7610535565b61029d6102983660046115d5565b6105b4565b6040805192835260208301919091520161014d565b3480156102be57600080fd5b506101b761063c565b3480156102d357600080fd5b506000546001600160a01b0316610139565b3480156102f157600080fd5b506103056103003660046116ba565b610654565b60405161014d919061176d565b34801561031e57600080fd5b506101b761032d366004611663565b610747565b34801561033e57600080fd5b506001546001600160a01b0316610139565b34801561035c57600080fd5b506101b761036b366004611663565b610771565b3360009081526002602052604081205460ff166103a0576040516348f5c3ed60e01b815260040160405180910390fd5b60006103aa6107e2565b905034156103cb5760405163113a2f4b60e21b815260040160405180910390fd5b60006103d8826000610953565b90508160e00151156103ee576103ee8282610a30565b61041782828460a00151600014610410576004546001600160a01b0316610aa5565b6000610aa5565b61044582828461014001518560a001518660c0015161043691906117d1565b61044091906117d1565b610b90565b5095945050505050565b610457610d56565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b610481610d56565b610489610db0565b610491610e00565b565b61049b610d56565b6001600160a01b038216600081815260026020908152604091829020805460ff191685151590811790915582519384529083015233917fa71618a9ed4e81ce27edc2700d38db549c32abb5e4f32ec57f791151030fbc45910160405180910390a25050565b610508610d56565b6104916000610e55565b600061051c610e6e565b60006105266107e2565b905060006103d8826001610953565b60015433906001600160a01b031681146105a85760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b6105b181610e55565b50565b6000806105bf610e6e565b60006105c96107e2565b905060006105d8826001610953565b90508160e00151156105ee576105ee8282610a30565b61061082828460a00151600014610410576004546001600160a01b0316610aa5565b61062f82828461014001518560a001518660c0015161043691906117d1565b9097909650945050505050565b610644610d56565b61064c610e6e565b610491610ebb565b606061065e610d56565b8167ffffffffffffffff811115610677576106776117f2565b6040519080825280602002602001820160405280156106aa57816020015b60608152602001906001900390816106955790505b50905060005b8281101561073f5761071a308585848181106106ce576106ce611808565b90506020028101906106e0919061181e565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610efe92505050565b82828151811061072c5761072c611808565b60209081029190910101526001016106b0565b505b92915050565b61074f610d56565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b610779610d56565b600180546001600160a01b0383166001600160a01b031990911681179091556107aa6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260853560f01c3560843560f81c1c428110156108625763931997cf60e01b60005260046000fd5b60483560601c8252605c3560601c602083015260703560601c60408301528060608301525060883560f01c3560873560f81c1c6080820152608b3560f01c35608a3560f81c1c60a0820152608e3560f01c35608d3560f81c1c60c0820152600060d13560f81c118060e083015280600181146109145760d23560f81c806101008501526001810361090e5760d33560601c61012085015260e83560f01c3560e73560f81c1c6101408501525b50505090565b6101153560f81c806101008501526001810361090e576101163560601c61012085015261012b3560f01c3561012a3560f81c1c61014085015250505090565b61010082015160009081808261096b5761014061096f565b6101805b61ffff169050604051915080820160405282600181146109b1577f783528850c43ab6adcc3a843186a6558aa806707dd0abb3d2909a2a70b7f22a383526109d5565b7f64d67eff2ff010acba1b1df82fb327ba0dc6d2965ba6b0b472bc14c494c8b4f683525b50610a267f86af987965544521ef5b52deabbeb812d3353977e11a2dbe7e0f4905d1e607217f2a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de8885858a6002610f2a565b9695505050505050565b60008060008060d13560f81c935060d235925060f23591506101133560f01c356101123560f81c1c9050610a9d85308861014001518960a001518a60c00151610a7991906117d1565b610a8391906117d1565b60208a01516001600160a01b0316929190858989896110d4565b505050505050565b60a083015115610b145760208301516001600160a01b0316610aec57610ae7818460a0015185602001516001600160a01b03166111299092919063ffffffff16565b610b14565b610b1482828560a0015186602001516001600160a01b0316611203909392919063ffffffff16565b61014083015115610b5d5760208301516001600160a01b0316610b6257610b5d83610120015184610140015185602001516001600160a01b03166111299092919063ffffffff16565b505050565b610b5d8284610120015185610140015186602001516001600160a01b0316611203909392919063ffffffff16565b602083015160009081906001600160a01b0316610beb578461014001518560a001518660c00151610bc191906117d1565b610bcb91906117d1565b341015610beb576040516365719fe160e11b815260040160405180910390fd5b60208501516000906001600160a01b0316610c0b575060c0850151610c58565b610c3385308860c0015189602001516001600160a01b0316611203909392919063ffffffff16565b60035460c08701516020880151610c58926001600160a01b0391821692911690611262565b6000600360009054906101000a90046001600160a01b03169050600060405160446024350160448103818301604052630563da2560e21b835260206004840152806024840152604051604081016040528160448086013760408184868a8a5af1945060018503610cce5780519850602081015197505b5050505060008103610ce4573d6000803e3d6000fd5b5086516020808901516040808b015181516001600160a01b03938416815290831693810193909352820188905260608201879052918216918816907f20efd6d5195b7b50273f01cd79a27989255356f9f13293edc53ee142accfdb759060800160405180910390a35050935093915050565b6000546001600160a01b031633146104915760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161059f565b600154600160a01b900460ff166104915760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161059f565b610e08610db0565b6001805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600180546001600160a01b03191690556105b181611304565b600154600160a01b900460ff16156104915760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059f565b610ec3610e6e565b6001805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610e383390565b6060610f23838360405180606001604052806027815260200161189c60279139611354565b9392505050565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091528183018a9052606082018990524660808301523060a0808401919091528351808403909101815260c090920190925280519101206000906000806000803060208b01523360408b01528a5160608b015260208b015160808b015260408b015160a08b015260608b015160c08b015260808b015160e08b015260a08b01516101008b015260c08b01516101208b015260016101008c01510361100c576101208b01516101408b01526101408b01516101608b01525b888a206040519a5060428b0160405261190160f01b8b528560028c01528060228c01525060428a209350609035925060b035915060d03560f81c9050871561108d57600061105c858585856113c2565b9050339650806000528760205260016040600020541461108757638baa579f60e01b60005260046000fd5b506110c4565b611099848484846113c2565b9550306001600160a01b038716036110c457604051638baa579f60e01b815260040160405180910390fd5b5050505050979650505050505050565b60405160e4810160405263d505accf60e01b81528760048201528660248201528560448201528460648201528360848201528260a48201528160c482015260008060e48360008d5af150505050505050505050565b6001600160a01b0383166111b1576000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611184576040519150601f19603f3d011682016040523d82523d6000602084013e611189565b606091505b50509050806111ab576040516312171d8360e31b815260040160405180910390fd5b50505050565b600060405190506044810160405263a9059cbb60e01b81528260048201528160248201526111e68460008360446000806114ca565b6111ab576040516312171d8360e31b815260040160405180910390fd5b60006040519050606481016040526323b872dd60e01b815283600482015282602482015281604482015261123e8560008360646000806114ca565b61125b57604051631e4e7d0960e21b815260040160405180910390fd5b5050505050565b600060405190506044810160405263095ea7b360e01b81528260048201528160248201526112978460008360446000806114ca565b6111ab57600060248201526112b38460008360446000806114ca565b6112d0576040516340b27c2160e11b815260040160405180910390fd5b8160248201526112e78460008360446000806114ca565b6111ab576040516340b27c2160e11b815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080856001600160a01b031685604051611371919061186c565b600060405180830381855af49150503d80600081146113ac576040519150601f19603f3d011682016040523d82523d6000602084013e6113b1565b606091505b5091509150610a2686838387611537565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561140557604051638baa579f60e01b815260040160405180910390fd5b8160ff16601b1415801561141d57508160ff16601c14155b1561143b57604051638baa579f60e01b815260040160405180910390fd5b60408051600081526020810180835287905260ff841691810191909152606081018590526080810184905260019060a0016020604051602081039080840390855afa15801561148e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166114c257604051638baa579f60e01b815260040160405180910390fd5b949350505050565b600061150d565b60003d15600181146114e85780156114f957611507565b823b156114f457600191505b611507565b60206000803e600080511191505b50919050565b81838587898b5af1611523573d6000803e3d6000fd5b61152c876114d1565b979650505050505050565b606083156115a657825160000361159f576001600160a01b0385163b61159f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161059f565b50816114c2565b6114c283838151156115bb5781518083602001fd5b8060405162461bcd60e51b815260040161059f9190611888565b600080602083850312156115e857600080fd5b823567ffffffffffffffff8082111561160057600080fd5b818501915085601f83011261161457600080fd5b81358181111561162357600080fd5b86602082850101111561163557600080fd5b60209290920196919550909350505050565b80356001600160a01b038116811461165e57600080fd5b919050565b60006020828403121561167557600080fd5b610f2382611647565b6000806040838503121561169157600080fd5b61169a83611647565b9150602083013580151581146116af57600080fd5b809150509250929050565b600080602083850312156116cd57600080fd5b823567ffffffffffffffff808211156116e557600080fd5b818501915085601f8301126116f957600080fd5b81358181111561170857600080fd5b8660208260051b850101111561163557600080fd5b60005b83811015611738578181015183820152602001611720565b50506000910152565b6000815180845261175981602086016020860161171d565b601f01601f19169290920160200192915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156117c457603f198886030184526117b2858351611741565b94509285019290850190600101611796565b5092979650505050505050565b8082018082111561074157634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261183557600080fd5b83018035915067ffffffffffffffff82111561185057600080fd5b60200191503681900382131561186557600080fd5b9250929050565b6000825161187e81846020870161171d565b9190910192915050565b602081526000610f23602083018461174156fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212206c01e7a70960db48fa1e0a8f1a90050a760b85f697057e4b88fbdcf1ffc1983b64736f6c63430008180033
Deployed Bytecode
0x60806040526004361061010d5760003560e01c806373fc4457116100955780638da5cb5b116100645780638da5cb5b146102c7578063ac9650d8146102e5578063b8f38c7414610312578063e30c397814610332578063f2fde38b1461035057600080fd5b806373fc44571461026257806379ba50971461027557806383bf23211461028a5780638456cb59146102b257600080fd5b80633f4ba83a116100dc5780633f4ba83a146101b9578063519a98e0146101ce57806357f46a1a146101ee5780635c975abb1461022e578063715018a61461024d57600080fd5b80631c0ad646146101195780631ec4aec81461015657806325e651ed14610176578063364f9cf81461019757600080fd5b3661011457005b600080fd5b34801561012557600080fd5b50600354610139906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561016257600080fd5b50600454610139906001600160a01b031681565b6101896101843660046115d5565b610370565b60405190815260200161014d565b3480156101a357600080fd5b506101b76101b2366004611663565b61044f565b005b3480156101c557600080fd5b506101b7610479565b3480156101da57600080fd5b506101b76101e936600461167e565b610493565b3480156101fa57600080fd5b5061021e610209366004611663565b60026020526000908152604090205460ff1681565b604051901515815260200161014d565b34801561023a57600080fd5b50600154600160a01b900460ff1661021e565b34801561025957600080fd5b506101b7610500565b6101896102703660046115d5565b610512565b34801561028157600080fd5b506101b7610535565b61029d6102983660046115d5565b6105b4565b6040805192835260208301919091520161014d565b3480156102be57600080fd5b506101b761063c565b3480156102d357600080fd5b506000546001600160a01b0316610139565b3480156102f157600080fd5b506103056103003660046116ba565b610654565b60405161014d919061176d565b34801561031e57600080fd5b506101b761032d366004611663565b610747565b34801561033e57600080fd5b506001546001600160a01b0316610139565b34801561035c57600080fd5b506101b761036b366004611663565b610771565b3360009081526002602052604081205460ff166103a0576040516348f5c3ed60e01b815260040160405180910390fd5b60006103aa6107e2565b905034156103cb5760405163113a2f4b60e21b815260040160405180910390fd5b60006103d8826000610953565b90508160e00151156103ee576103ee8282610a30565b61041782828460a00151600014610410576004546001600160a01b0316610aa5565b6000610aa5565b61044582828461014001518560a001518660c0015161043691906117d1565b61044091906117d1565b610b90565b5095945050505050565b610457610d56565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b610481610d56565b610489610db0565b610491610e00565b565b61049b610d56565b6001600160a01b038216600081815260026020908152604091829020805460ff191685151590811790915582519384529083015233917fa71618a9ed4e81ce27edc2700d38db549c32abb5e4f32ec57f791151030fbc45910160405180910390a25050565b610508610d56565b6104916000610e55565b600061051c610e6e565b60006105266107e2565b905060006103d8826001610953565b60015433906001600160a01b031681146105a85760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b6105b181610e55565b50565b6000806105bf610e6e565b60006105c96107e2565b905060006105d8826001610953565b90508160e00151156105ee576105ee8282610a30565b61061082828460a00151600014610410576004546001600160a01b0316610aa5565b61062f82828461014001518560a001518660c0015161043691906117d1565b9097909650945050505050565b610644610d56565b61064c610e6e565b610491610ebb565b606061065e610d56565b8167ffffffffffffffff811115610677576106776117f2565b6040519080825280602002602001820160405280156106aa57816020015b60608152602001906001900390816106955790505b50905060005b8281101561073f5761071a308585848181106106ce576106ce611808565b90506020028101906106e0919061181e565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610efe92505050565b82828151811061072c5761072c611808565b60209081029190910101526001016106b0565b505b92915050565b61074f610d56565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b610779610d56565b600180546001600160a01b0383166001600160a01b031990911681179091556107aa6000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260853560f01c3560843560f81c1c428110156108625763931997cf60e01b60005260046000fd5b60483560601c8252605c3560601c602083015260703560601c60408301528060608301525060883560f01c3560873560f81c1c6080820152608b3560f01c35608a3560f81c1c60a0820152608e3560f01c35608d3560f81c1c60c0820152600060d13560f81c118060e083015280600181146109145760d23560f81c806101008501526001810361090e5760d33560601c61012085015260e83560f01c3560e73560f81c1c6101408501525b50505090565b6101153560f81c806101008501526001810361090e576101163560601c61012085015261012b3560f01c3561012a3560f81c1c61014085015250505090565b61010082015160009081808261096b5761014061096f565b6101805b61ffff169050604051915080820160405282600181146109b1577f783528850c43ab6adcc3a843186a6558aa806707dd0abb3d2909a2a70b7f22a383526109d5565b7f64d67eff2ff010acba1b1df82fb327ba0dc6d2965ba6b0b472bc14c494c8b4f683525b50610a267f86af987965544521ef5b52deabbeb812d3353977e11a2dbe7e0f4905d1e607217f2a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de8885858a6002610f2a565b9695505050505050565b60008060008060d13560f81c935060d235925060f23591506101133560f01c356101123560f81c1c9050610a9d85308861014001518960a001518a60c00151610a7991906117d1565b610a8391906117d1565b60208a01516001600160a01b0316929190858989896110d4565b505050505050565b60a083015115610b145760208301516001600160a01b0316610aec57610ae7818460a0015185602001516001600160a01b03166111299092919063ffffffff16565b610b14565b610b1482828560a0015186602001516001600160a01b0316611203909392919063ffffffff16565b61014083015115610b5d5760208301516001600160a01b0316610b6257610b5d83610120015184610140015185602001516001600160a01b03166111299092919063ffffffff16565b505050565b610b5d8284610120015185610140015186602001516001600160a01b0316611203909392919063ffffffff16565b602083015160009081906001600160a01b0316610beb578461014001518560a001518660c00151610bc191906117d1565b610bcb91906117d1565b341015610beb576040516365719fe160e11b815260040160405180910390fd5b60208501516000906001600160a01b0316610c0b575060c0850151610c58565b610c3385308860c0015189602001516001600160a01b0316611203909392919063ffffffff16565b60035460c08701516020880151610c58926001600160a01b0391821692911690611262565b6000600360009054906101000a90046001600160a01b03169050600060405160446024350160448103818301604052630563da2560e21b835260206004840152806024840152604051604081016040528160448086013760408184868a8a5af1945060018503610cce5780519850602081015197505b5050505060008103610ce4573d6000803e3d6000fd5b5086516020808901516040808b015181516001600160a01b03938416815290831693810193909352820188905260608201879052918216918816907f20efd6d5195b7b50273f01cd79a27989255356f9f13293edc53ee142accfdb759060800160405180910390a35050935093915050565b6000546001600160a01b031633146104915760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161059f565b600154600160a01b900460ff166104915760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161059f565b610e08610db0565b6001805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600180546001600160a01b03191690556105b181611304565b600154600160a01b900460ff16156104915760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059f565b610ec3610e6e565b6001805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610e383390565b6060610f23838360405180606001604052806027815260200161189c60279139611354565b9392505050565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091528183018a9052606082018990524660808301523060a0808401919091528351808403909101815260c090920190925280519101206000906000806000803060208b01523360408b01528a5160608b015260208b015160808b015260408b015160a08b015260608b015160c08b015260808b015160e08b015260a08b01516101008b015260c08b01516101208b015260016101008c01510361100c576101208b01516101408b01526101408b01516101608b01525b888a206040519a5060428b0160405261190160f01b8b528560028c01528060228c01525060428a209350609035925060b035915060d03560f81c9050871561108d57600061105c858585856113c2565b9050339650806000528760205260016040600020541461108757638baa579f60e01b60005260046000fd5b506110c4565b611099848484846113c2565b9550306001600160a01b038716036110c457604051638baa579f60e01b815260040160405180910390fd5b5050505050979650505050505050565b60405160e4810160405263d505accf60e01b81528760048201528660248201528560448201528460648201528360848201528260a48201528160c482015260008060e48360008d5af150505050505050505050565b6001600160a01b0383166111b1576000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611184576040519150601f19603f3d011682016040523d82523d6000602084013e611189565b606091505b50509050806111ab576040516312171d8360e31b815260040160405180910390fd5b50505050565b600060405190506044810160405263a9059cbb60e01b81528260048201528160248201526111e68460008360446000806114ca565b6111ab576040516312171d8360e31b815260040160405180910390fd5b60006040519050606481016040526323b872dd60e01b815283600482015282602482015281604482015261123e8560008360646000806114ca565b61125b57604051631e4e7d0960e21b815260040160405180910390fd5b5050505050565b600060405190506044810160405263095ea7b360e01b81528260048201528160248201526112978460008360446000806114ca565b6111ab57600060248201526112b38460008360446000806114ca565b6112d0576040516340b27c2160e11b815260040160405180910390fd5b8160248201526112e78460008360446000806114ca565b6111ab576040516340b27c2160e11b815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080856001600160a01b031685604051611371919061186c565b600060405180830381855af49150503d80600081146113ac576040519150601f19603f3d011682016040523d82523d6000602084013e6113b1565b606091505b5091509150610a2686838387611537565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561140557604051638baa579f60e01b815260040160405180910390fd5b8160ff16601b1415801561141d57508160ff16601c14155b1561143b57604051638baa579f60e01b815260040160405180910390fd5b60408051600081526020810180835287905260ff841691810191909152606081018590526080810184905260019060a0016020604051602081039080840390855afa15801561148e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166114c257604051638baa579f60e01b815260040160405180910390fd5b949350505050565b600061150d565b60003d15600181146114e85780156114f957611507565b823b156114f457600191505b611507565b60206000803e600080511191505b50919050565b81838587898b5af1611523573d6000803e3d6000fd5b61152c876114d1565b979650505050505050565b606083156115a657825160000361159f576001600160a01b0385163b61159f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161059f565b50816114c2565b6114c283838151156115bb5781518083602001fd5b8060405162461bcd60e51b815260040161059f9190611888565b600080602083850312156115e857600080fd5b823567ffffffffffffffff8082111561160057600080fd5b818501915085601f83011261161457600080fd5b81358181111561162357600080fd5b86602082850101111561163557600080fd5b60209290920196919550909350505050565b80356001600160a01b038116811461165e57600080fd5b919050565b60006020828403121561167557600080fd5b610f2382611647565b6000806040838503121561169157600080fd5b61169a83611647565b9150602083013580151581146116af57600080fd5b809150509250929050565b600080602083850312156116cd57600080fd5b823567ffffffffffffffff808211156116e557600080fd5b818501915085601f8301126116f957600080fd5b81358181111561170857600080fd5b8660208260051b850101111561163557600080fd5b60005b83811015611738578181015183820152602001611720565b50506000910152565b6000815180845261175981602086016020860161171d565b601f01601f19169290920160200192915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156117c457603f198886030184526117b2858351611741565b94509285019290850190600101611796565b5092979650505050505050565b8082018082111561074157634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261183557600080fd5b83018035915067ffffffffffffffff82111561185057600080fd5b60200191503681900382131561186557600080fd5b9250929050565b6000825161187e81846020870161171d565b9190910192915050565b602081526000610f23602083018461174156fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212206c01e7a70960db48fa1e0a8f1a90050a760b85f697057e4b88fbdcf1ffc1983b64736f6c63430008180033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
POL | 100.00% | $0.172336 | 0.000000000000000054 | <$0.000001 |
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.