More Info
Private Name Tags
ContractCreator
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
8605868 | 5 hrs ago | 10 GLMR | ||||
8605847 | 5 hrs ago | 10 GLMR | ||||
8602298 | 11 hrs ago | 60 GLMR | ||||
8602284 | 11 hrs ago | 60 GLMR | ||||
8597678 | 18 hrs ago | 10,000 GLMR | ||||
8595941 | 21 hrs ago | 378.735 GLMR | ||||
8595760 | 22 hrs ago | 118.515 GLMR | ||||
8594058 | 25 hrs ago | 11 GLMR | ||||
8593788 | 25 hrs ago | 11 GLMR | ||||
8593763 | 25 hrs ago | 11 GLMR | ||||
8585565 | 39 hrs ago | 300.32430758 GLMR | ||||
8581014 | 47 hrs ago | 247 GLMR | ||||
8580834 | 47 hrs ago | 500 GLMR | ||||
8580057 | 2 days ago | 220 GLMR | ||||
8579151 | 2 days ago | 5,230 GLMR | ||||
8577296 | 2 days ago | 85 GLMR | ||||
8575750 | 2 days ago | 540 GLMR | ||||
8571940 | 2 days ago | 1,000 GLMR | ||||
8571845 | 2 days ago | 0.5 GLMR | ||||
8570852 | 2 days ago | 10,000 GLMR | ||||
8568858 | 2 days ago | 7 GLMR | ||||
8568811 | 2 days ago | 7.3 GLMR | ||||
8568082 | 2 days ago | 10 GLMR | ||||
8566122 | 3 days ago | 270 GLMR | ||||
8559583 | 3 days ago | 120 GLMR |
Loading...
Loading
Contract Name:
AggregatorV3
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 500 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.9; import "./base/AggregatorBase.sol"; import "./helpers/TransferHelper.sol"; import "./interfaces/IAlgebraSwapRouter.sol"; import "./helpers/Path.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; contract AggregatorV3 is AggregatorBase { using Path for bytes; function initialize(RouterParameters memory params) public initializer { AggregatorBase.initializerr(params); } function execute( Command[] calldata commands, bytes[] calldata inputs // with abi.encode it gives InvalidSignatureLength(), so we pass here ) public payable { require(commands.length <= 15, "Too many commands for executor."); require( commands.length == inputs.length, "Amount of commands must match inputs." ); for (uint256 i = 0; i < commands.length; ++i) { if (commands[i].instruction == InstructionType.V3_EXACT_IN) { ( bytes memory path, address recipient, uint256 deadline, uint256 amountIn, uint256 amountOutMinimum ) = abi.decode( inputs[i], (bytes, address, uint256, uint256, uint256) ); require(recipient != address(0), "Zero Address"); //fetch the first token (address tokenA,) = path.decodeFirstPool(); IStellaSwapV2ERC20(tokenA).approve(address(v3Router),amountIn); IAlgebraSwapRouter(v3Router).exactInput( IAlgebraSwapRouter.ExactInputParams({ path: path, recipient: recipient, deadline: deadline, amountIn: amountIn, amountOutMinimum: amountOutMinimum }) ); } if (commands[i].instruction == InstructionType.V3_EXACT_OUT) { ( bytes memory path, address recipient, uint256 deadline, uint256 amountOut, uint256 amountInMaximum ) = abi.decode( inputs[i], (bytes, address, uint256, uint256, uint256) ); require(recipient != address(0), "Zero Address"); //approve last token in the reversed path in v3_exact_out address lastToken = path.getLastPoolToken(); IStellaSwapV2ERC20(lastToken).approve(address(v3Router), amountInMaximum); //need to encode path IAlgebraSwapRouter(v3Router).exactOutput( IAlgebraSwapRouter.ExactOutputParams({ path: path, recipient: recipient, deadline: deadline, amountOut: amountOut, amountInMaximum: amountInMaximum }) ); } if (commands[i].instruction == InstructionType.V2_EXACT_IN) { ( uint256 amountIn, uint256 amountOutMin, address[] memory path, address to, uint256 deadline ) = abi.decode( inputs[i], (uint256, uint256, address[], address, uint256) ); require(to != address(0), "Zero Address"); IStellaSwapV2ERC20(path[0]).approve(address(v2router), amountIn); v2router.swapExactTokensForTokens(amountIn, amountOutMin, path, to, deadline); } if (commands[i].instruction == InstructionType.V2_EXACT_OUT) { ( uint256 amountOut, uint256 amountInMax, address[] memory path, address to, uint256 deadline ) = abi.decode( inputs[i], (uint256, uint256, address[], address, uint256) ); require(to != address(0), "Zero Address"); IStellaSwapV2ERC20(path[0]).approve(address(v2router), amountInMax); v2router.swapTokensForExactTokens(amountOut, amountInMax, path, to, deadline); } if (commands[i].instruction == InstructionType.STABLE_SIMPLE) { ( address basepool, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline ) = abi.decode( inputs[i], (address, uint8, uint8, uint256, uint256, uint256) ); _stableApproval(basepool, tokenIndexFrom, dx); IStableSwap(basepool).swap(tokenIndexFrom, tokenIndexTo, dx, minDy, deadline); } if (commands[i].instruction == InstructionType.STABLE_FROM_BASE) { ( address pool, address basePool, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline ) = abi.decode( inputs[i], ( address, address, uint8, uint8, uint256, uint256, uint256 ) ); _stableApproval(basePool, tokenIndexFrom, dx); stableRouter.swapFromBase(IStableSwap(pool), IStableSwap(basePool), tokenIndexFrom, tokenIndexTo, dx, minDy, deadline); } if (commands[i].instruction == InstructionType.STABLE_TO_BASE) { ( address pool, address basePool, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline ) = abi.decode( inputs[i], ( address, address, uint8, uint8, uint256, uint256, uint256 ) ); address poolToken = IStableSwap(pool).getToken(tokenIndexFrom); IStellaSwapV2ERC20(poolToken).approve(address(stableRouter), dx); stableRouter.swapToBase(IStableSwap(pool), IStableSwap(basePool), tokenIndexFrom, tokenIndexTo, dx, minDy, deadline); } if (commands[i].instruction == InstructionType.PERMIT2_TRANSFER) { ( uint256 _amount, address _owner, address _user, address _token, uint256 _nonce, uint256 _deadline, bytes memory _signature ) = abi.decode( inputs[i], ( uint256, address, address, address, uint256, uint256, bytes ) ); address permit2addr = address(permit2); ISignatureTransfer.TokenPermissions memory permitted = ISignatureTransfer.TokenPermissions({ amount: _amount, token: _token }); ISignatureTransfer(permit2addr).permitWitnessTransferFrom( ISignatureTransfer.PermitTransferFrom({ permitted: permitted, nonce: _nonce, deadline: _deadline }), ISignatureTransfer.SignatureTransferDetails({ to: address(this), requestedAmount: _amount }), msg.sender, // witness keccak256(abi.encode(WITNESS_TYPEHASH, Witness(_user))), // witnessTypeString, WITNESS_TYPE_STRING, _signature ); } if (commands[i].instruction == InstructionType.WRAP_ETH) { uint256 amount = abi.decode(inputs[i], (uint256)); require( address(this).balance >= amount, "Insufficient ETH balance" ); weth.deposit{value: amount}(); } if (commands[i].instruction == InstructionType.UNWRAP_ETH) { //wglmr.withdraw (with users permit signature) uint256 amount = abi.decode(inputs[i], (uint256)); weth.withdraw(amount); } if (commands[i].instruction == InstructionType.TRANSFER) { ( address token, address recipient, uint256 value, bool isEth ) = abi.decode(inputs[i], (address, address, uint256, bool)); require(recipient != address(0), "Zero Address"); if (isEth) { TransferHelper.safeTransferETH(recipient, value); } else { TransferHelper.safeTransfer(token, recipient, value); } } if (commands[i].instruction == InstructionType.SWEEP) { ( address token, address recipient, bool isEth ) = abi.decode(inputs[i], (address, address, bool)); require(recipient != address(0), "Zero Address"); if (isEth) { uint256 balance = address(this).balance; TransferHelper.safeTransferETH(recipient, balance); } else { uint256 balance = IStellaSwapV2ERC20(token).balanceOf(address(this)); TransferHelper.safeTransfer(token, recipient, balance); } } } } function _stableApproval(address pool, uint8 tokenIndex, uint256 amount) internal { address poolToken = IStableSwap(pool).getToken(tokenIndex); IStellaSwapV2ERC20(poolToken).approve(address(pool), amount); IStellaSwapV2ERC20(poolToken).approve(address(stableRouter), amount); } receive() external payable {} }
pragma solidity ^0.8.17; import "../interfaces/IWETH.sol"; import "../interfaces/IAlgebraSwapRouter.sol"; import "../interfaces/IStellaSwapV2Router02.sol"; import "../interfaces/ISignatureTransfer.sol"; import "../interfaces/IStableSwapRouter.sol"; import "../interfaces/IStellaSwapV2ERC20.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; struct RouterParameters { IAlgebraSwapRouter v3router; IStellaSwapV2Router02 v2router; IStableSwapRouter stableRouter; ISignatureTransfer permit2; IWETH weth; } contract AggregatorBase is Initializable { //Aggregator is a contract that takes commands, data, and a signature from the user //to transfer their tokens to operate on them. ISignatureTransfer public permit2; IAlgebraSwapRouter public v3Router; IStellaSwapV2Router02 public v2router; IStableSwapRouter public stableRouter; IWETH public weth; string public constant WITNESS_TYPE_STRING = "Witness witness)TokenPermissions(address token,uint256 amount)Witness(address user)"; bytes32 public constant WITNESS_TYPEHASH = keccak256("Witness(address user)"); enum AMM { V2, V3, STABLE } //will the tokens stay in the router for the next command to use or go to user? enum Destination { ROUTER, MSG_SENDER } //v2 v3 stable etc all use the same commands for simplifying the API enum InstructionType { V3_EXACT_IN, V3_EXACT_OUT, V2_EXACT_IN, V2_EXACT_OUT, PERMIT2_TRANSFER, //giving tokens for aggregator to trade with WRAP_ETH, //turn users GLMR to WGLMR UNWRAP_ETH, //reverse SWEEP, //say user had negative slippage, send the remaining funds back TRANSFER, // simple transfer helper STABLE_SIMPLE, // simple transfer helper STABLE_TO_BASE,// simple transfer helper STABLE_FROM_BASE // simple transfer helper } struct SwapArguments { uint256 inputAmount; uint256 outputAmount; uint256 desiredInput; uint256 desiredOutput; } struct Command { InstructionType instruction; } struct Witness { // Address of the user that signer is giving the tokens to address user; } function initializerr(RouterParameters memory params) public onlyInitializing { permit2 = params.permit2; v3Router = params.v3router; v2router = params.v2router; stableRouter = params.stableRouter; weth = params.weth; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; import './IAlgebraSwapCallback.sol'; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Algebra /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery interface IAlgebraSwapRouter is IAlgebraSwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 limitSqrtPrice; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 limitSqrtPrice; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @dev Unlike standard swaps, handles transferring from user before the actual swap. /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInputSingleSupportingFeeOnTransferTokens(ExactInputSingleParams calldata params) external returns (uint256 amountOut); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.0; import './BytesLib.sol'; /// @title Functions for manipulating path data for multihop swaps /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery library Path { using BytesLib for bytes; /// @dev The length of the bytes encoded address uint256 private constant ADDR_SIZE = 20; /// @dev The length of the bytes encoded fee uint256 private constant FEE_SIZE = 3; /// @dev The offset of a single token address and pool fee uint256 private constant NEXT_OFFSET = ADDR_SIZE; /// @dev The offset of an encoded pool key uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE; /// @dev The minimum length of an encoding that contains 2 or more pools uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET; /// @notice Returns true iff the path contains two or more pools /// @param path The encoded swap path /// @return True if path contains two or more pools, otherwise false function hasMultiplePools(bytes memory path) internal pure returns (bool) { return path.length >= MULTIPLE_POOLS_MIN_LENGTH; } /// @notice Returns the number of pools in the path /// @param path The encoded swap path /// @return The number of pools in the path function numPools(bytes memory path) internal pure returns (uint256) { // Ignore the first token address. From then on every fee and token offset indicates a pool. return ((path.length - ADDR_SIZE) / NEXT_OFFSET); } /// @notice Decodes the first pool in path /// @param path The bytes encoded swap path /// @return tokenA The first token of the given pool /// @return tokenB The second token of the given pool function decodeFirstPool(bytes memory path) internal pure returns (address tokenA, address tokenB) { tokenA = path.toAddress(0); tokenB = path.toAddress(NEXT_OFFSET); } /// @notice Gets the segment corresponding to the first pool in the path /// @param path The bytes encoded swap path /// @return The segment containing all data necessary to target the first pool in the path function getFirstPool(bytes memory path) internal pure returns (bytes memory) { return path.slice(0, POP_OFFSET); } function getLastPoolToken(bytes memory path) internal pure returns (address lastPool) { lastPool = path.toAddress(path.length - 20); } /// @notice Skips a token + fee element from the buffer and returns the remainder /// @param path The swap path /// @return The remaining token + fee elements in the path function skipToken(bytes memory path) internal pure returns (bytes memory) { return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.0; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove(address token, address to, uint value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); } function safeTransfer(address token, address to, uint value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); } function safeTransferFrom(address token, address from, address to, uint value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); } function safeTransferETH(address to, uint value) internal { (bool success,) = to.call{value:value}(new bytes(0)); require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0; interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /// @title SignatureTransfer /// @notice Handles ERC20 token transfers through signature based actions /// @dev Requires user's token approval on the Permit2 contract interface ISignatureTransfer { /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount /// @param maxAmount The maximum amount a spender can request to transfer error InvalidAmount(uint256 maxAmount); /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred error LengthMismatch(); /// @notice Emits an event when the owner successfully invalidates an unordered nonce. event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask); /// @notice The token and amount details for a transfer signed in the permit transfer signature struct TokenPermissions { // ERC20 token address address token; // the maximum amount that can be spent uint256 amount; } /// @notice The signed permit message for a single token transfer struct PermitTransferFrom { TokenPermissions permitted; // a unique value for every token owner's signature to prevent signature replays uint256 nonce; // deadline on the permit signature uint256 deadline; } /// @notice Specifies the recipient address and amount for batched transfers. /// @dev Recipients and amounts correspond to the index of the signed token permissions array. /// @dev Reverts if the requested amount is greater than the permitted signed amount. struct SignatureTransferDetails { // recipient address address to; // spender requested amount uint256 requestedAmount; } /// @notice Used to reconstruct the signed permit message for multiple token transfers /// @dev Do not need to pass in spender address as it is required that it is msg.sender /// @dev Note that a user still signs over a spender address struct PermitBatchTransferFrom { // the tokens and corresponding amounts permitted for a transfer TokenPermissions[] permitted; // a unique value for every token owner's signature to prevent signature replays uint256 nonce; // deadline on the permit signature uint256 deadline; } /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce /// @dev It returns a uint256 bitmap /// @dev The index, or wordPosition is capped at type(uint248).max function nonceBitmap(address, uint256) external view returns (uint256); /// @notice Transfers a token using a signed permit message /// @dev Reverts if the requested amount is greater than the permitted signed amount /// @param permit The permit data signed over by the owner /// @param owner The owner of the tokens to transfer /// @param transferDetails The spender's requested transfer details for the permitted token /// @param signature The signature to verify function permitTransferFrom( PermitTransferFrom memory permit, SignatureTransferDetails calldata transferDetails, address owner, bytes calldata signature ) external; /// @notice Transfers a token using a signed permit message /// @notice Includes extra data provided by the caller to verify signature over /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition /// @dev Reverts if the requested amount is greater than the permitted signed amount /// @param permit The permit data signed over by the owner /// @param owner The owner of the tokens to transfer /// @param transferDetails The spender's requested transfer details for the permitted token /// @param witness Extra data to include when checking the user signature /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash /// @param signature The signature to verify function permitWitnessTransferFrom( PermitTransferFrom memory permit, SignatureTransferDetails calldata transferDetails, address owner, bytes32 witness, string calldata witnessTypeString, bytes calldata signature ) external; /// @notice Transfers multiple tokens using a signed permit message /// @param permit The permit data signed over by the owner /// @param owner The owner of the tokens to transfer /// @param transferDetails Specifies the recipient and requested amount for the token transfer /// @param signature The signature to verify function permitTransferFrom( PermitBatchTransferFrom memory permit, SignatureTransferDetails[] calldata transferDetails, address owner, bytes calldata signature ) external; /// @notice Transfers multiple tokens using a signed permit message /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition /// @notice Includes extra data provided by the caller to verify signature over /// @param permit The permit data signed over by the owner /// @param owner The owner of the tokens to transfer /// @param transferDetails Specifies the recipient and requested amount for the token transfer /// @param witness Extra data to include when checking the user signature /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash /// @param signature The signature to verify function permitWitnessTransferFrom( PermitBatchTransferFrom memory permit, SignatureTransferDetails[] calldata transferDetails, address owner, bytes32 witness, string calldata witnessTypeString, bytes calldata signature ) external; /// @notice Invalidates the bits specified in mask for the bitmap at the word position /// @dev The wordPos is maxed at type(uint248).max /// @param wordPos A number to index the nonceBitmap at /// @param mask A bitmap masked against msg.sender's current bitmap at the word position function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.2; import './IStellaSwapV2Router01.sol'; interface IStellaSwapV2Router02 is IStellaSwapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; import "./IStableSwap.sol"; interface IStableSwapRouter { function swapFromBase( IStableSwap pool, IStableSwap basePool, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline ) external returns (uint256); function swapToBase( IStableSwap pool, IStableSwap basePool, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline ) external returns (uint256); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0; interface IStellaSwapV2ERC20 { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.2; interface IStellaSwapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Callback for IAlgebraPoolActions#swap /// @notice Any contract that calls IAlgebraPoolActions#swap must implement this interface /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces interface IAlgebraSwapCallback { /// @notice Called to `msg.sender` after executing a swap via IAlgebraPool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a AlgebraPool deployed by the canonical AlgebraFactory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IAlgebraPoolActions#swap call function algebraSwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; interface IStableSwap { function swap( uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline ) external returns (uint256); function getLpToken() external returns (address); function getToken(uint8 index) external returns (address); }
// 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 AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return 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 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: Unlicense /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function concat( bytes memory _preBytes, bytes memory _postBytes ) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
{ "viaIR": true, "optimizer": { "enabled": true, "runs": 500 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"inputs":[],"name":"WITNESS_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITNESS_TYPE_STRING","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"enum AggregatorBase.InstructionType","name":"instruction","type":"uint8"}],"internalType":"struct AggregatorBase.Command[]","name":"commands","type":"tuple[]"},{"internalType":"bytes[]","name":"inputs","type":"bytes[]"}],"name":"execute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IAlgebraSwapRouter","name":"v3router","type":"address"},{"internalType":"contract IStellaSwapV2Router02","name":"v2router","type":"address"},{"internalType":"contract IStableSwapRouter","name":"stableRouter","type":"address"},{"internalType":"contract ISignatureTransfer","name":"permit2","type":"address"},{"internalType":"contract IWETH","name":"weth","type":"address"}],"internalType":"struct RouterParameters","name":"params","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IAlgebraSwapRouter","name":"v3router","type":"address"},{"internalType":"contract IStellaSwapV2Router02","name":"v2router","type":"address"},{"internalType":"contract IStableSwapRouter","name":"stableRouter","type":"address"},{"internalType":"contract ISignatureTransfer","name":"permit2","type":"address"},{"internalType":"contract IWETH","name":"weth","type":"address"}],"internalType":"struct RouterParameters","name":"params","type":"tuple"}],"name":"initializerr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"permit2","outputs":[{"internalType":"contract ISignatureTransfer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stableRouter","outputs":[{"internalType":"contract IStableSwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"v2router","outputs":[{"internalType":"contract IStellaSwapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"v3Router","outputs":[{"internalType":"contract IAlgebraSwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60808060405234610016576120e5908161001c8239f35b600080fdfe6080604052600436101561001b575b361561001957600080fd5b005b60003560e01c80630dc91306146100e357806312261ee7146100da578063156e2152146100d15780632c03ae6a146100c85780633fc8cef3146100bf5780634c3677c8146100b65780638f656d22146100ad5780638f8dc10a146100a4578063d7f478ee1461009b5763ff08da6e0361000e57610096610775565b61000e565b506100966105f2565b506100966105ca565b50610096610482565b506100966103dc565b506100966103b4565b50610096610378565b50610096610343565b50610096610124565b506100966100fc565b60009103126100f757565b600080fd5b50346100f75760003660031901126100f75760206001600160a01b0360015416604051908152f35b50346100f75760003660031901126100f75760206001600160a01b0360005460101c16604051908152f35b50634e487b7160e01b600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761018257604052565b61018a61014f565b604052565b67ffffffffffffffff811161018257604052565b90601f8019910116810190811067ffffffffffffffff82111761018257604052565b604051906101d282610166565b565b604051906040820182811067ffffffffffffffff82111761018257604052565b604051906060820182811067ffffffffffffffff82111761018257604052565b604051906020820182811067ffffffffffffffff82111761018257604052565b60209067ffffffffffffffff8111610252575b601f01601f19160190565b61025a61014f565b610247565b604051906080820182811067ffffffffffffffff8211176102f6575b604052605382527f746e6573732861646472657373207573657229000000000000000000000000006060837f5769746e657373207769746e65737329546f6b656e5065726d697373696f6e7360208201527f286164647265737320746f6b656e2c75696e7432353620616d6f756e7429576960408201520152565b6102fe61014f565b61027b565b919082519283825260005b84811061032f575050826000602080949584010152601f8019910116010190565b60208183018101518483018201520161030e565b50346100f75760003660031901126100f75761037461036061025f565b604051918291602083526020830190610303565b0390f35b50346100f75760003660031901126100f75760206040517ffeed45b61d43f452c933000e813412318e408c352e137cba26cfbe202b355c3a8152f35b50346100f75760003660031901126100f75760206001600160a01b0360045416604051908152f35b50346100f75760003660031901126100f75760206001600160a01b0360035416604051908152f35b6001600160a01b038116036100f757565b60a09060031901126100f75760405161042d81610166565b60043561043981610404565b815260243561044781610404565b602082015260443561045881610404565b604082015260643561046981610404565b606082015260843561047a81610404565b608082015290565b50346100f75761049136610415565b6000549060ff8260081c1615809281936105bc575b811561059c575b5015610531576104d390826104ca600160ff196000541617600055565b61051857611e11565b6104d957005b6104e961ff001960005416600055565b604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602090a1005b61052c61010061ff00196000541617600055565b611e11565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608490fd5b303b159150816105ae575b50386104ad565b6001915060ff1614386105a7565b600160ff82161091506104a6565b50346100f75760003660031901126100f75760206001600160a01b0360025416604051908152f35b50346100f75761060136610415565b6000549060ff8260081c16156106eb576080816100199362010000600160b01b0360606106cf95015160101b169062010000600160b01b031916176000556001600160a01b038151166001600160a01b0319600154161760015561068e61067260208301516001600160a01b031690565b6001600160a01b03166001600160a01b03196002541617600255565b6106c16106a560408301516001600160a01b031690565b6001600160a01b03166001600160a01b03196003541617600355565b01516001600160a01b031690565b6001600160a01b03166001600160a01b03196004541617600455565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b9181601f840112156100f75782359167ffffffffffffffff83116100f7576020808501948460051b0101116100f757565b5060403660031901126100f75767ffffffffffffffff6004358181116100f7576107a3903690600401610744565b916024359081116100f7576107bc903690600401610744565b906107ca600f851115611598565b6107d58285146115e4565b60005b8481106107e157005b6107f46107ef828787611688565b6116c6565b6107fd816116a6565b15611474575b6108116107ef828787611688565b61081a816116a6565b600180911461131c575b506108336107ef828787611688565b61083c816116a6565b60028091146111e8575b60036108566107ef848989611688565b61085f816116a6565b1461109b575b5060096108766107ef838888611688565b61087f816116a6565b14610fdb575b600b6108956107ef838888611688565b61089e816116a6565b14610eec575b600a6108b46107ef838888611688565b6108bd816116a6565b14610cf7575b60046108d36107ef838888611688565b6108dc816116a6565b14610b93575b60056108f26107ef838888611688565b6108fb816116a6565b14610b13575b60066109116107ef838888611688565b61091a816116a6565b14610a72575b8060086109346107ef610967948989611688565b61093d816116a6565b14610a24575b60076109536107ef838989611688565b61095c816116a6565b1461096c575b611655565b6107d8565b61098261097a8286866116d3565b810190611c88565b916001600160a01b0380911691169161099c8315156117c0565b156109ad5750610962904790612018565b6040516370a0823160e01b81523060048201526109629260209290918381602481855afa938415610a17575b6000946109e8575b5050611f4b565b610a08929450803d10610a10575b610a0081836101a3565b81019061182a565b9138806109e1565b503d6109f6565b610a1f61181d565b6109d9565b610a3a610a328286866116d3565b810190611c4e565b90916001600160a01b0380911691610a538315156117c0565b15610a685750610a639250612018565b610943565b610a639316611f4b565b610a88610a808285856116d3565b810190611bf3565b90610aaa610a9e6004546001600160a01b031690565b6001600160a01b031690565b91823b156100f757604051632e1a7d4d60e01b81526004810191909152610967926000908290602490829084905af18015610b06575b610aed575b509050610920565b80610afa610b009261018f565b806100ec565b38610ae5565b610b0e61181d565b610ae0565b610b21610a808285856116d3565b610b2d81471015611c02565b610b42610a9e6004546001600160a01b031690565b803b156100f757600090600460405180948193630d0e30db60e41b83525af18015610b86575b610b73575b50610901565b80610afa610b809261018f565b38610b6d565b610b8e61181d565b610b68565b610c78610c86610baf610ba78487876116d3565b810190611aff565b9792909596919450610c32610bd3610a9e6000546001600160a01b039060101c1690565b91610bdc6101d4565b6001600160a01b03918216815297816020948b868c01521697610bfd6101f4565b998a52848a01526040890152610c116101d4565b30815298838a0152610c21610214565b951685906001600160a01b03169052565b6040519283918201948591909160206001600160a01b0360408301947ffeed45b61d43f452c933000e813412318e408c352e137cba26cfbe202b355c3a84525116910152565b03601f1981018352826101a3565b51902091610c9261025f565b94823b156100f757600094610cc18692604051988997889687956309be14ff60e11b8752339160048801611b64565b03925af18015610cea575b610cd7575b506108e2565b80610afa610ce49261018f565b38610cd1565b610cf261181d565b610ccc565b610d028184846116d3565b8101610d0d91611a97565b60405162415c3360e91b815260ff861660048201529295939493869390916001600160a01b038916826024815a602094600091f1938415986001600160a01b0398610db460208b99600099610e3698839f610edf575b8b91610eb2575b50610d80610a9e6003546001600160a01b031690565b8b8d60405180978196829563095ea7b360e01b845260048401602090939291936001600160a01b0360408201951681520152565b0393165af18015610ea5575b610e78575b50610ddb610a9e6003546001600160a01b031690565b986040519c8d9b8c9a8b99637fcb499160e11b8b52169116600489019360ff60c0969399989794819360e088019b6001600160a01b038092168952166020880152166040860152166060840152608083015260a08201520152565b03925af18015610e6b575b610e4c575b506108c3565b610e649060203d602011610a1057610a0081836101a3565b5038610e46565b610e7361181d565b610e41565b610e97908c3d8e11610e9e575b610e8f81836101a3565b810190611805565b5038610dc5565b503d610e85565b610ead61181d565b610dc0565b610ed29150833d8511610ed8575b610eca81836101a3565b810190611aea565b38610d6a565b503d610ec0565b610ee761181d565b610d63565b6000610f04610efc8386866116d3565b810190611a97565b610f996001600160a01b03989294959397969880991691610f26898685611cbb565b610f3b610a9e6003546001600160a01b031690565b95604051998a98899788966338c7897360e01b885260209e8f9d16600489019360ff60c0969399989794819360e088019b6001600160a01b038092168952166020880152166040860152166060840152608083015260a08201520152565b03925af18015610fce575b610fb0575b50506108a4565b81610fc692903d10610a1057610a0081836101a3565b503880610fa9565b610fd661181d565b610fa4565b60006110596001600160a01b03610ffe610ff68588886116d3565b810190611a52565b94979193959092971692611013818786611cbb565b604051968795869485936348b4aac360e11b855260209b8c9a60048701919260ff60809497969592978160a0860199168552166020840152604083015260608201520152565b03925af1801561108e575b611070575b5050610885565b8161108692903d10610a1057610a0081836101a3565b503880611069565b61109661181d565b611064565b60006001600160a01b0361117d610a9e8361115f6110c56110bd898c8c6116d3565b8101906118a6565b9793949296919816996110d98b15156117c0565b866110f9610a9e610a9e6110ec8d611949565b516001600160a01b031690565b61110d610a9e84546001600160a01b031690565b60405163095ea7b360e01b81526001600160a01b039190911660048201526024810192909252602091908290829060449082908c905af180156111db575b6111bd575b5050546001600160a01b031690565b9460405198899788968795634401edf760e11b8752600487016119d9565b03925af180156111b0575b15610865576111a9903d806000833e6111a181836101a3565b81019061195f565b5038610865565b6111b861181d565b611188565b816111d392903d10610e9e57610e8f81836101a3565b503880611150565b6111e361181d565b61114b565b6000806001600160a01b036112016110bd8689896116d3565b9396919416956112128715156117c0565b80611225610a9e610a9e6110ec89611949565b611239610a9e8b546001600160a01b031690565b60405163095ea7b360e01b81526001600160a01b0391909116600482015260248101929092526020919082908290604490829088905af1801561130f575b6112f1575b50506112b3611295610a9e8a546001600160a01b031690565b94604051988997889687956338ed173960e01b8752600487016119d9565b03925af180156112e4575b6112c9575b50610846565b6112dd903d806000833e6111a181836101a3565b50386112c3565b6112ec61181d565b6112be565b8161130792903d10610e9e57610e8f81836101a3565b50388061127c565b61131761181d565b611277565b6113278285856116d3565b810161133291611775565b91949390926001600160a01b03169061134c8215156117c0565b61135581611eed565b855460405163095ea7b360e01b81526001600160a01b03918216600482015260248101869052602098899791969391929091889188916044918391165a90600091f18015610a9e60009a611409996113de946113c394611467575b61144a575b50546001600160a01b031690565b956113cc6101c5565b9586526001600160a01b031688860152565b604084015260608301526080820152604051948580948193631e51809360e31b835260048301611839565b03925af1801561143d575b61141f575b50610824565b8161143592903d10610a1057610a0081836101a3565b503880611419565b61144561181d565b611414565b611460908c8d3d10610e9e57610e8f81836101a3565b50386113b5565b61146f61181d565b6113b0565b61147f8184846116d3565b810161148a91611775565b9092936001600160a01b03809516908115156114a5906117c0565b6114ae81611e82565b509260019586546114c5906001600160a01b031690565b60405163095ea7b360e01b81526001600160a01b039190911660048201526024810182905260209889979196889188916044918391165a90600091f18015610a9e60009a6115569961152b946113c3946114675761144a5750546001600160a01b031690565b60408401526060830152608082015260405194858094819363c04b8d5960e01b835260048301611839565b03925af1801561158b575b61156d575b5050610803565b8161158392903d10610a1057610a0081836101a3565b503880611566565b61159361181d565b611561565b1561159f57565b60405162461bcd60e51b815260206004820152601f60248201527f546f6f206d616e7920636f6d6d616e647320666f72206578656375746f722e006044820152606490fd5b156115eb57565b60405162461bcd60e51b815260206004820152602560248201527f416d6f756e74206f6620636f6d6d616e6473206d757374206d6174636820696e604482015264383aba399760d91b6064820152608490fd5b50634e487b7160e01b600052601160045260246000fd5b6001906000198114611665570190565b61166d61163e565b0190565b50634e487b7160e01b600052603260045260246000fd5b9190811015611699575b60051b0190565b6116a1611671565b611692565b600c11156116b057565b634e487b7160e01b600052602160045260246000fd5b35600c8110156100f75790565b9190811015611716575b60051b81013590601e19813603018212156100f757019081359167ffffffffffffffff83116100f75760200182360381136100f7579190565b61171e611671565b6116dd565b81601f820112156100f75780359061173a82610234565b9261174860405194856101a3565b828452602083830101116100f757816000926020809301838601378301015290565b35906101d282610404565b9060a0828203126100f75781359067ffffffffffffffff82116100f75761179d918301611723565b9160208201356117ac81610404565b916040810135916080606083013592013590565b156117c757565b60405162461bcd60e51b815260206004820152600c60248201526b5a65726f204164647265737360a01b6044820152606490fd5b801515036100f757565b908160209103126100f7575161181a816117fb565b90565b506040513d6000823e3d90fd5b908160209103126100f7575190565b6020815260a06080611856845183602086015260c0850190610303565b936001600160a01b03602082015116604085015260408101516060850152606081015182850152015191015290565b60209067ffffffffffffffff811161189e5760051b0190565b6116a161014f565b9160a0838303126100f7578235926020928382013593604083013567ffffffffffffffff81116100f75783019180601f840112156100f75782356118e981611885565b936118f760405195866101a3565b818552838086019260051b8201019283116100f7578301905b828210611930575050505091608061192a6060840161176a565b92013590565b838091833561193e81610404565b815201910190611910565b602090805115611957570190565b61166d611671565b60209081818403126100f75780519067ffffffffffffffff82116100f757019180601f840112156100f757825161199581611885565b936119a360405195866101a3565b818552838086019260051b8201019283116100f7578301905b8282106119ca575050505090565b815181529083019083016119bc565b9291909594939560a084019084526020918285015260a0604085015282518091528160c0850193019160005b828110611a275750505050906001600160a01b03608092951660608201520152565b83516001600160a01b031685529381019392810192600101611a05565b359060ff821682036100f757565b91908260c09103126100f7578135611a6981610404565b91611a7660208201611a44565b91611a8360408301611a44565b9160608101359160a0608083013592013590565b908160e09103126100f7578035611aad81610404565b916020820135611abc81610404565b91611ac960408201611a44565b91611ad660608301611a44565b9160808101359160c060a083013592013590565b908160209103126100f7575161181a81610404565b9060e0828203126100f7578135926020830135611b1b81610404565b926040810135611b2a81610404565b926060820135611b3981610404565b9260808301359260a08101359260c082013567ffffffffffffffff81116100f75761181a9201611723565b9491611be493611bc76001600160a01b0392604061181a9a9895611b9c8b8251602080916001600160a01b0381511684520151910152565b6020818101518c84015291015160608b015281516001600160a01b031660808b0152015160a0890152565b1660c086015260e085015261014080610100860152840190610303565b91610120818403910152610303565b908160209103126100f7573590565b15611c0957565b60405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e74204554482062616c616e636500000000000000006044820152606490fd5b91908260809103126100f7578135611c6581610404565b916020810135611c7481610404565b916060604083013592013561181a816117fb565b908160609103126100f7578035611c9e81610404565b9160406020830135611caf81610404565b92013561181a816117fb565b60405162415c3360e91b815260ff929092166004830152602092611d84928492906001600160a01b0390848160248160008688165af1908115611e04575b600091611de7575b5060405163095ea7b360e01b8082526001600160a01b03949094166004820152602481018590529116919084816044816000875af18015611dda575b611dbd575b506000611d5a610a9e6003546001600160a01b031690565b6040519283526001600160a01b031660048301526024820193909352938492839182906044820190565b03925af18015611db0575b611d97575050565b81611dad92903d10610e9e57610e8f81836101a3565b50565b611db861181d565b611d8f565b611dd390853d8711610e9e57610e8f81836101a3565b5038611d42565b611de261181d565b611d3d565b611dfe9150853d8711610ed857610eca81836101a3565b38611d01565b611e0c61181d565b611cf9565b6000549060ff8260081c16156106eb576080816101d29362010000600160b01b0360606106cf95015160101b169062010000600160b01b031916176000556001600160a01b038151166001600160a01b0319600154161760015561068e61067260208301516001600160a01b031690565b906014825110611ea857602082015160601c916028815110611ea8576034015160601c90565b60405162461bcd60e51b815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e647300000000000000000000006044820152606490fd5b805180601319810111611f0e575b80825110611ea85701600c015160601c90565b611f1661163e565b611efb565b3d15611f46573d90611f2c82610234565b91611f3a60405193846101a3565b82523d6000602084013e565b606090565b60405163a9059cbb60e01b602082019081526001600160a01b03909316602482015260448101939093526000928392908390611f8a8160648101610c78565b51925af1611f96611f1b565b81611fe9575b5015611fa457565b60405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606490fd5b8051801592508215611ffe575b505038611f9c565b6120119250602080918301019101611805565b3880611ff6565b60008080938193826040516020810181811067ffffffffffffffff8211176120a2575b604052525af1612049611f1b565b501561205157565b60405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b6064820152608490fd5b6120aa61014f565b61203b56fea264697066735822122004734597ce29d7951fd64fee6ce3eb7642123fea86567eaf9370c4ec254fb08f64736f6c63430008110033
Deployed Bytecode
0x6080604052600436101561001b575b361561001957600080fd5b005b60003560e01c80630dc91306146100e357806312261ee7146100da578063156e2152146100d15780632c03ae6a146100c85780633fc8cef3146100bf5780634c3677c8146100b65780638f656d22146100ad5780638f8dc10a146100a4578063d7f478ee1461009b5763ff08da6e0361000e57610096610775565b61000e565b506100966105f2565b506100966105ca565b50610096610482565b506100966103dc565b506100966103b4565b50610096610378565b50610096610343565b50610096610124565b506100966100fc565b60009103126100f757565b600080fd5b50346100f75760003660031901126100f75760206001600160a01b0360015416604051908152f35b50346100f75760003660031901126100f75760206001600160a01b0360005460101c16604051908152f35b50634e487b7160e01b600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761018257604052565b61018a61014f565b604052565b67ffffffffffffffff811161018257604052565b90601f8019910116810190811067ffffffffffffffff82111761018257604052565b604051906101d282610166565b565b604051906040820182811067ffffffffffffffff82111761018257604052565b604051906060820182811067ffffffffffffffff82111761018257604052565b604051906020820182811067ffffffffffffffff82111761018257604052565b60209067ffffffffffffffff8111610252575b601f01601f19160190565b61025a61014f565b610247565b604051906080820182811067ffffffffffffffff8211176102f6575b604052605382527f746e6573732861646472657373207573657229000000000000000000000000006060837f5769746e657373207769746e65737329546f6b656e5065726d697373696f6e7360208201527f286164647265737320746f6b656e2c75696e7432353620616d6f756e7429576960408201520152565b6102fe61014f565b61027b565b919082519283825260005b84811061032f575050826000602080949584010152601f8019910116010190565b60208183018101518483018201520161030e565b50346100f75760003660031901126100f75761037461036061025f565b604051918291602083526020830190610303565b0390f35b50346100f75760003660031901126100f75760206040517ffeed45b61d43f452c933000e813412318e408c352e137cba26cfbe202b355c3a8152f35b50346100f75760003660031901126100f75760206001600160a01b0360045416604051908152f35b50346100f75760003660031901126100f75760206001600160a01b0360035416604051908152f35b6001600160a01b038116036100f757565b60a09060031901126100f75760405161042d81610166565b60043561043981610404565b815260243561044781610404565b602082015260443561045881610404565b604082015260643561046981610404565b606082015260843561047a81610404565b608082015290565b50346100f75761049136610415565b6000549060ff8260081c1615809281936105bc575b811561059c575b5015610531576104d390826104ca600160ff196000541617600055565b61051857611e11565b6104d957005b6104e961ff001960005416600055565b604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602090a1005b61052c61010061ff00196000541617600055565b611e11565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608490fd5b303b159150816105ae575b50386104ad565b6001915060ff1614386105a7565b600160ff82161091506104a6565b50346100f75760003660031901126100f75760206001600160a01b0360025416604051908152f35b50346100f75761060136610415565b6000549060ff8260081c16156106eb576080816100199362010000600160b01b0360606106cf95015160101b169062010000600160b01b031916176000556001600160a01b038151166001600160a01b0319600154161760015561068e61067260208301516001600160a01b031690565b6001600160a01b03166001600160a01b03196002541617600255565b6106c16106a560408301516001600160a01b031690565b6001600160a01b03166001600160a01b03196003541617600355565b01516001600160a01b031690565b6001600160a01b03166001600160a01b03196004541617600455565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b9181601f840112156100f75782359167ffffffffffffffff83116100f7576020808501948460051b0101116100f757565b5060403660031901126100f75767ffffffffffffffff6004358181116100f7576107a3903690600401610744565b916024359081116100f7576107bc903690600401610744565b906107ca600f851115611598565b6107d58285146115e4565b60005b8481106107e157005b6107f46107ef828787611688565b6116c6565b6107fd816116a6565b15611474575b6108116107ef828787611688565b61081a816116a6565b600180911461131c575b506108336107ef828787611688565b61083c816116a6565b60028091146111e8575b60036108566107ef848989611688565b61085f816116a6565b1461109b575b5060096108766107ef838888611688565b61087f816116a6565b14610fdb575b600b6108956107ef838888611688565b61089e816116a6565b14610eec575b600a6108b46107ef838888611688565b6108bd816116a6565b14610cf7575b60046108d36107ef838888611688565b6108dc816116a6565b14610b93575b60056108f26107ef838888611688565b6108fb816116a6565b14610b13575b60066109116107ef838888611688565b61091a816116a6565b14610a72575b8060086109346107ef610967948989611688565b61093d816116a6565b14610a24575b60076109536107ef838989611688565b61095c816116a6565b1461096c575b611655565b6107d8565b61098261097a8286866116d3565b810190611c88565b916001600160a01b0380911691169161099c8315156117c0565b156109ad5750610962904790612018565b6040516370a0823160e01b81523060048201526109629260209290918381602481855afa938415610a17575b6000946109e8575b5050611f4b565b610a08929450803d10610a10575b610a0081836101a3565b81019061182a565b9138806109e1565b503d6109f6565b610a1f61181d565b6109d9565b610a3a610a328286866116d3565b810190611c4e565b90916001600160a01b0380911691610a538315156117c0565b15610a685750610a639250612018565b610943565b610a639316611f4b565b610a88610a808285856116d3565b810190611bf3565b90610aaa610a9e6004546001600160a01b031690565b6001600160a01b031690565b91823b156100f757604051632e1a7d4d60e01b81526004810191909152610967926000908290602490829084905af18015610b06575b610aed575b509050610920565b80610afa610b009261018f565b806100ec565b38610ae5565b610b0e61181d565b610ae0565b610b21610a808285856116d3565b610b2d81471015611c02565b610b42610a9e6004546001600160a01b031690565b803b156100f757600090600460405180948193630d0e30db60e41b83525af18015610b86575b610b73575b50610901565b80610afa610b809261018f565b38610b6d565b610b8e61181d565b610b68565b610c78610c86610baf610ba78487876116d3565b810190611aff565b9792909596919450610c32610bd3610a9e6000546001600160a01b039060101c1690565b91610bdc6101d4565b6001600160a01b03918216815297816020948b868c01521697610bfd6101f4565b998a52848a01526040890152610c116101d4565b30815298838a0152610c21610214565b951685906001600160a01b03169052565b6040519283918201948591909160206001600160a01b0360408301947ffeed45b61d43f452c933000e813412318e408c352e137cba26cfbe202b355c3a84525116910152565b03601f1981018352826101a3565b51902091610c9261025f565b94823b156100f757600094610cc18692604051988997889687956309be14ff60e11b8752339160048801611b64565b03925af18015610cea575b610cd7575b506108e2565b80610afa610ce49261018f565b38610cd1565b610cf261181d565b610ccc565b610d028184846116d3565b8101610d0d91611a97565b60405162415c3360e91b815260ff861660048201529295939493869390916001600160a01b038916826024815a602094600091f1938415986001600160a01b0398610db460208b99600099610e3698839f610edf575b8b91610eb2575b50610d80610a9e6003546001600160a01b031690565b8b8d60405180978196829563095ea7b360e01b845260048401602090939291936001600160a01b0360408201951681520152565b0393165af18015610ea5575b610e78575b50610ddb610a9e6003546001600160a01b031690565b986040519c8d9b8c9a8b99637fcb499160e11b8b52169116600489019360ff60c0969399989794819360e088019b6001600160a01b038092168952166020880152166040860152166060840152608083015260a08201520152565b03925af18015610e6b575b610e4c575b506108c3565b610e649060203d602011610a1057610a0081836101a3565b5038610e46565b610e7361181d565b610e41565b610e97908c3d8e11610e9e575b610e8f81836101a3565b810190611805565b5038610dc5565b503d610e85565b610ead61181d565b610dc0565b610ed29150833d8511610ed8575b610eca81836101a3565b810190611aea565b38610d6a565b503d610ec0565b610ee761181d565b610d63565b6000610f04610efc8386866116d3565b810190611a97565b610f996001600160a01b03989294959397969880991691610f26898685611cbb565b610f3b610a9e6003546001600160a01b031690565b95604051998a98899788966338c7897360e01b885260209e8f9d16600489019360ff60c0969399989794819360e088019b6001600160a01b038092168952166020880152166040860152166060840152608083015260a08201520152565b03925af18015610fce575b610fb0575b50506108a4565b81610fc692903d10610a1057610a0081836101a3565b503880610fa9565b610fd661181d565b610fa4565b60006110596001600160a01b03610ffe610ff68588886116d3565b810190611a52565b94979193959092971692611013818786611cbb565b604051968795869485936348b4aac360e11b855260209b8c9a60048701919260ff60809497969592978160a0860199168552166020840152604083015260608201520152565b03925af1801561108e575b611070575b5050610885565b8161108692903d10610a1057610a0081836101a3565b503880611069565b61109661181d565b611064565b60006001600160a01b0361117d610a9e8361115f6110c56110bd898c8c6116d3565b8101906118a6565b9793949296919816996110d98b15156117c0565b866110f9610a9e610a9e6110ec8d611949565b516001600160a01b031690565b61110d610a9e84546001600160a01b031690565b60405163095ea7b360e01b81526001600160a01b039190911660048201526024810192909252602091908290829060449082908c905af180156111db575b6111bd575b5050546001600160a01b031690565b9460405198899788968795634401edf760e11b8752600487016119d9565b03925af180156111b0575b15610865576111a9903d806000833e6111a181836101a3565b81019061195f565b5038610865565b6111b861181d565b611188565b816111d392903d10610e9e57610e8f81836101a3565b503880611150565b6111e361181d565b61114b565b6000806001600160a01b036112016110bd8689896116d3565b9396919416956112128715156117c0565b80611225610a9e610a9e6110ec89611949565b611239610a9e8b546001600160a01b031690565b60405163095ea7b360e01b81526001600160a01b0391909116600482015260248101929092526020919082908290604490829088905af1801561130f575b6112f1575b50506112b3611295610a9e8a546001600160a01b031690565b94604051988997889687956338ed173960e01b8752600487016119d9565b03925af180156112e4575b6112c9575b50610846565b6112dd903d806000833e6111a181836101a3565b50386112c3565b6112ec61181d565b6112be565b8161130792903d10610e9e57610e8f81836101a3565b50388061127c565b61131761181d565b611277565b6113278285856116d3565b810161133291611775565b91949390926001600160a01b03169061134c8215156117c0565b61135581611eed565b855460405163095ea7b360e01b81526001600160a01b03918216600482015260248101869052602098899791969391929091889188916044918391165a90600091f18015610a9e60009a611409996113de946113c394611467575b61144a575b50546001600160a01b031690565b956113cc6101c5565b9586526001600160a01b031688860152565b604084015260608301526080820152604051948580948193631e51809360e31b835260048301611839565b03925af1801561143d575b61141f575b50610824565b8161143592903d10610a1057610a0081836101a3565b503880611419565b61144561181d565b611414565b611460908c8d3d10610e9e57610e8f81836101a3565b50386113b5565b61146f61181d565b6113b0565b61147f8184846116d3565b810161148a91611775565b9092936001600160a01b03809516908115156114a5906117c0565b6114ae81611e82565b509260019586546114c5906001600160a01b031690565b60405163095ea7b360e01b81526001600160a01b039190911660048201526024810182905260209889979196889188916044918391165a90600091f18015610a9e60009a6115569961152b946113c3946114675761144a5750546001600160a01b031690565b60408401526060830152608082015260405194858094819363c04b8d5960e01b835260048301611839565b03925af1801561158b575b61156d575b5050610803565b8161158392903d10610a1057610a0081836101a3565b503880611566565b61159361181d565b611561565b1561159f57565b60405162461bcd60e51b815260206004820152601f60248201527f546f6f206d616e7920636f6d6d616e647320666f72206578656375746f722e006044820152606490fd5b156115eb57565b60405162461bcd60e51b815260206004820152602560248201527f416d6f756e74206f6620636f6d6d616e6473206d757374206d6174636820696e604482015264383aba399760d91b6064820152608490fd5b50634e487b7160e01b600052601160045260246000fd5b6001906000198114611665570190565b61166d61163e565b0190565b50634e487b7160e01b600052603260045260246000fd5b9190811015611699575b60051b0190565b6116a1611671565b611692565b600c11156116b057565b634e487b7160e01b600052602160045260246000fd5b35600c8110156100f75790565b9190811015611716575b60051b81013590601e19813603018212156100f757019081359167ffffffffffffffff83116100f75760200182360381136100f7579190565b61171e611671565b6116dd565b81601f820112156100f75780359061173a82610234565b9261174860405194856101a3565b828452602083830101116100f757816000926020809301838601378301015290565b35906101d282610404565b9060a0828203126100f75781359067ffffffffffffffff82116100f75761179d918301611723565b9160208201356117ac81610404565b916040810135916080606083013592013590565b156117c757565b60405162461bcd60e51b815260206004820152600c60248201526b5a65726f204164647265737360a01b6044820152606490fd5b801515036100f757565b908160209103126100f7575161181a816117fb565b90565b506040513d6000823e3d90fd5b908160209103126100f7575190565b6020815260a06080611856845183602086015260c0850190610303565b936001600160a01b03602082015116604085015260408101516060850152606081015182850152015191015290565b60209067ffffffffffffffff811161189e5760051b0190565b6116a161014f565b9160a0838303126100f7578235926020928382013593604083013567ffffffffffffffff81116100f75783019180601f840112156100f75782356118e981611885565b936118f760405195866101a3565b818552838086019260051b8201019283116100f7578301905b828210611930575050505091608061192a6060840161176a565b92013590565b838091833561193e81610404565b815201910190611910565b602090805115611957570190565b61166d611671565b60209081818403126100f75780519067ffffffffffffffff82116100f757019180601f840112156100f757825161199581611885565b936119a360405195866101a3565b818552838086019260051b8201019283116100f7578301905b8282106119ca575050505090565b815181529083019083016119bc565b9291909594939560a084019084526020918285015260a0604085015282518091528160c0850193019160005b828110611a275750505050906001600160a01b03608092951660608201520152565b83516001600160a01b031685529381019392810192600101611a05565b359060ff821682036100f757565b91908260c09103126100f7578135611a6981610404565b91611a7660208201611a44565b91611a8360408301611a44565b9160608101359160a0608083013592013590565b908160e09103126100f7578035611aad81610404565b916020820135611abc81610404565b91611ac960408201611a44565b91611ad660608301611a44565b9160808101359160c060a083013592013590565b908160209103126100f7575161181a81610404565b9060e0828203126100f7578135926020830135611b1b81610404565b926040810135611b2a81610404565b926060820135611b3981610404565b9260808301359260a08101359260c082013567ffffffffffffffff81116100f75761181a9201611723565b9491611be493611bc76001600160a01b0392604061181a9a9895611b9c8b8251602080916001600160a01b0381511684520151910152565b6020818101518c84015291015160608b015281516001600160a01b031660808b0152015160a0890152565b1660c086015260e085015261014080610100860152840190610303565b91610120818403910152610303565b908160209103126100f7573590565b15611c0957565b60405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e74204554482062616c616e636500000000000000006044820152606490fd5b91908260809103126100f7578135611c6581610404565b916020810135611c7481610404565b916060604083013592013561181a816117fb565b908160609103126100f7578035611c9e81610404565b9160406020830135611caf81610404565b92013561181a816117fb565b60405162415c3360e91b815260ff929092166004830152602092611d84928492906001600160a01b0390848160248160008688165af1908115611e04575b600091611de7575b5060405163095ea7b360e01b8082526001600160a01b03949094166004820152602481018590529116919084816044816000875af18015611dda575b611dbd575b506000611d5a610a9e6003546001600160a01b031690565b6040519283526001600160a01b031660048301526024820193909352938492839182906044820190565b03925af18015611db0575b611d97575050565b81611dad92903d10610e9e57610e8f81836101a3565b50565b611db861181d565b611d8f565b611dd390853d8711610e9e57610e8f81836101a3565b5038611d42565b611de261181d565b611d3d565b611dfe9150853d8711610ed857610eca81836101a3565b38611d01565b611e0c61181d565b611cf9565b6000549060ff8260081c16156106eb576080816101d29362010000600160b01b0360606106cf95015160101b169062010000600160b01b031916176000556001600160a01b038151166001600160a01b0319600154161760015561068e61067260208301516001600160a01b031690565b906014825110611ea857602082015160601c916028815110611ea8576034015160601c90565b60405162461bcd60e51b815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e647300000000000000000000006044820152606490fd5b805180601319810111611f0e575b80825110611ea85701600c015160601c90565b611f1661163e565b611efb565b3d15611f46573d90611f2c82610234565b91611f3a60405193846101a3565b82523d6000602084013e565b606090565b60405163a9059cbb60e01b602082019081526001600160a01b03909316602482015260448101939093526000928392908390611f8a8160648101610c78565b51925af1611f96611f1b565b81611fe9575b5015611fa457565b60405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606490fd5b8051801592508215611ffe575b505038611f9c565b6120119250602080918301019101611805565b3880611ff6565b60008080938193826040516020810181811067ffffffffffffffff8211176120a2575b604052525af1612049611f1b565b501561205157565b60405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b6064820152608490fd5b6120aa61014f565b61203b56fea264697066735822122004734597ce29d7951fd64fee6ce3eb7642123fea86567eaf9370c4ec254fb08f64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 29 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
GLMR | 100.00% | $0.999111 | 1 | $0.9991 |
[ 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.