More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
19740424 | 268 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Minimal Proxy Contract for 0x167a871142494b86007761d12735017ceb227ed8
Contract Name:
Depositor
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@openzeppelin/contracts/utils/Address.sol'; import '@mimic-fi/v3-helpers/contracts/utils/ERC20Helpers.sol'; import '@mimic-fi/v3-helpers/contracts/utils/Denominations.sol'; import '../Task.sol'; import '../interfaces/primitives/IDepositor.sol'; /** * @title Depositor * @dev Task that can be used as the origin to start any workflow */ contract Depositor is IDepositor, Task { // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('DEPOSITOR'); /** * @dev Deposit config. Only used in the initializer. */ struct DepositConfig { TaskConfig taskConfig; } /** * @dev Initializes the depositor * @param config Deposit config */ function initialize(DepositConfig memory config) external virtual initializer { __Depositor_init(config); } /** * @dev Initializes the depositor. It does call upper contracts initializers. * @param config Deposit config */ function __Depositor_init(DepositConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __Depositor_init_unchained(config); } /** * @dev Initializes the depositor. It does not call upper contracts initializers. * @param config Deposit config */ function __Depositor_init_unchained(DepositConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Tells the address from where the token amounts to execute this task are fetched */ function getTokensSource() public view virtual override(IBaseTask, BaseTask) returns (address) { return address(this); } /** * @dev Tells the balance of the depositor for a given token * @param token Address of the token being queried */ function getTaskAmount(address token) public view virtual override(IBaseTask, BaseTask) returns (uint256) { return ERC20Helpers.balanceOf(token, getTokensSource()); } /** * @dev It allows receiving native token transfers */ receive() external payable { if (msg.value == 0) revert TaskValueZero(); } /** * @dev Execute Depositor */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeDepositor(token, amount); if (Denominations.isNativeToken(token)) { Address.sendValue(payable(smartVault), amount); } else { ERC20Helpers.approve(token, smartVault, amount); ISmartVault(smartVault).collect(token, getTokensSource(), amount); } _afterDepositor(token, amount); } /** * @dev Before depositor hook */ function _beforeDepositor(address token, uint256 amount) internal virtual { _beforeTask(token, amount); if (token == address(0)) revert TaskTokenZero(); if (amount == 0) revert TaskAmountZero(); } /** * @dev After depositor hook */ function _afterDepositor(address token, uint256 amount) internal virtual { _increaseBalanceConnector(token, amount); _afterTask(token, amount); } /** * @dev Sets the balance connectors. Previous balance connector must be unset. * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function _setBalanceConnectors(bytes32 previous, bytes32 next) internal virtual override { if (previous != bytes32(0)) revert TaskPreviousConnectorNotZero(previous); super._setBalanceConnectors(previous, next); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.17; import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol'; import './AuthorizedHelpers.sol'; import './interfaces/IAuthorized.sol'; import './interfaces/IAuthorizer.sol'; /** * @title Authorized * @dev Implementation using an authorizer as its access-control mechanism. It offers `auth` and `authP` modifiers to * tag its own functions in order to control who can access them against the authorizer referenced. */ contract Authorized is IAuthorized, Initializable, AuthorizedHelpers { // Authorizer reference address public override authorizer; /** * @dev Modifier that should be used to tag protected functions */ modifier auth() { _authenticate(msg.sender, msg.sig); _; } /** * @dev Modifier that should be used to tag protected functions with params */ modifier authP(uint256[] memory params) { _authenticate(msg.sender, msg.sig, params); _; } /** * @dev Creates a new authorized contract. Note that initializers are disabled at creation time. */ constructor() { _disableInitializers(); } /** * @dev Initializes the authorized contract. It does call upper contracts initializers. * @param _authorizer Address of the authorizer to be set */ function __Authorized_init(address _authorizer) internal onlyInitializing { __Authorized_init_unchained(_authorizer); } /** * @dev Initializes the authorized contract. It does not call upper contracts initializers. * @param _authorizer Address of the authorizer to be set */ function __Authorized_init_unchained(address _authorizer) internal onlyInitializing { authorizer = _authorizer; } /** * @dev Reverts if `who` is not allowed to call `what` * @param who Address to be authenticated * @param what Function selector to be authenticated */ function _authenticate(address who, bytes4 what) internal view { _authenticate(who, what, new uint256[](0)); } /** * @dev Reverts if `who` is not allowed to call `what` with `how` * @param who Address to be authenticated * @param what Function selector to be authenticated * @param how Params to be authenticated */ function _authenticate(address who, bytes4 what, uint256[] memory how) internal view { if (!_isAuthorized(who, what, how)) revert AuthSenderNotAllowed(who, what, how); } /** * @dev Tells whether `who` has any permission on this contract * @param who Address asking permissions for */ function _hasPermissions(address who) internal view returns (bool) { return IAuthorizer(authorizer).hasPermissions(who, address(this)); } /** * @dev Tells whether `who` is allowed to call `what` * @param who Address asking permission for * @param what Function selector asking permission for */ function _isAuthorized(address who, bytes4 what) internal view returns (bool) { return _isAuthorized(who, what, new uint256[](0)); } /** * @dev Tells whether `who` is allowed to call `what` with `how` * @param who Address asking permission for * @param what Function selector asking permission for * @param how Params asking permission for */ function _isAuthorized(address who, bytes4 what, uint256[] memory how) internal view returns (bool) { return IAuthorizer(authorizer).isAuthorized(who, address(this), what, how); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.17; /** * @title AuthorizedHelpers * @dev Syntax sugar methods to operate with authorizer params easily */ contract AuthorizedHelpers { function authParams(address p1) internal pure returns (uint256[] memory r) { return authParams(uint256(uint160(p1))); } function authParams(bytes32 p1) internal pure returns (uint256[] memory r) { return authParams(uint256(p1)); } function authParams(uint256 p1) internal pure returns (uint256[] memory r) { r = new uint256[](1); r[0] = p1; } function authParams(address p1, bool p2) internal pure returns (uint256[] memory r) { r = new uint256[](2); r[0] = uint256(uint160(p1)); r[1] = p2 ? 1 : 0; } function authParams(address p1, uint256 p2) internal pure returns (uint256[] memory r) { r = new uint256[](2); r[0] = uint256(uint160(p1)); r[1] = p2; } function authParams(address p1, address p2) internal pure returns (uint256[] memory r) { r = new uint256[](2); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); } function authParams(bytes32 p1, bytes32 p2) internal pure returns (uint256[] memory r) { r = new uint256[](2); r[0] = uint256(p1); r[1] = uint256(p2); } function authParams(address p1, address p2, uint256 p3) internal pure returns (uint256[] memory r) { r = new uint256[](3); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); r[2] = p3; } function authParams(address p1, address p2, address p3) internal pure returns (uint256[] memory r) { r = new uint256[](3); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); r[2] = uint256(uint160(p3)); } function authParams(address p1, address p2, bytes4 p3) internal pure returns (uint256[] memory r) { r = new uint256[](3); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); r[2] = uint256(uint32(p3)); } function authParams(address p1, uint256 p2, uint256 p3) internal pure returns (uint256[] memory r) { r = new uint256[](3); r[0] = uint256(uint160(p1)); r[1] = p2; r[2] = p3; } function authParams(uint256 p1, uint256 p2, uint256 p3, uint256 p4) internal pure returns (uint256[] memory r) { r = new uint256[](4); r[0] = p1; r[1] = p2; r[2] = p3; r[3] = p4; } function authParams(address p1, address p2, uint256 p3, uint256 p4) internal pure returns (uint256[] memory r) { r = new uint256[](4); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); r[2] = p3; r[3] = p4; } function authParams(address p1, uint256 p2, address p3, uint256 p4) internal pure returns (uint256[] memory r) { r = new uint256[](4); r[0] = uint256(uint160(p1)); r[1] = p2; r[2] = uint256(uint160(p3)); r[3] = p4; } function authParams(address p1, uint256 p2, uint256 p3, uint256 p4) internal pure returns (uint256[] memory r) { r = new uint256[](4); r[0] = uint256(uint160(p1)); r[1] = p2; r[2] = p3; r[3] = p4; } function authParams(bytes32 p1, address p2, uint256 p3, bool p4) internal pure returns (uint256[] memory r) { r = new uint256[](4); r[0] = uint256(p1); r[1] = uint256(uint160(p2)); r[2] = p3; r[3] = p4 ? 1 : 0; } function authParams(address p1, uint256 p2, uint256 p3, uint256 p4, uint256 p5) internal pure returns (uint256[] memory r) { r = new uint256[](5); r[0] = uint256(uint160(p1)); r[1] = p2; r[2] = p3; r[3] = p4; r[4] = p5; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @dev Authorized interface */ interface IAuthorized { /** * @dev Sender `who` is not allowed to call `what` with `how` */ error AuthSenderNotAllowed(address who, bytes4 what, uint256[] how); /** * @dev Tells the address of the authorizer reference */ function authorizer() external view returns (address); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @dev Authorizer interface */ interface IAuthorizer { /** * @dev Permission change * @param where Address of the contract to change a permission for * @param changes List of permission changes to be executed */ struct PermissionChange { address where; GrantPermission[] grants; RevokePermission[] revokes; } /** * @dev Grant permission data * @param who Address to be authorized * @param what Function selector to be authorized * @param params List of params to restrict the given permission */ struct GrantPermission { address who; bytes4 what; Param[] params; } /** * @dev Revoke permission data * @param who Address to be unauthorized * @param what Function selector to be unauthorized */ struct RevokePermission { address who; bytes4 what; } /** * @dev Params used to validate permissions params against * @param op ID of the operation to compute in order to validate a permission param * @param value Comparison value */ struct Param { uint8 op; uint248 value; } /** * @dev Sender is not authorized to call `what` on `where` with `how` */ error AuthorizerSenderNotAllowed(address who, address where, bytes4 what, uint256[] how); /** * @dev The operation param is invalid */ error AuthorizerInvalidParamOp(uint8 op); /** * @dev Emitted every time `who`'s permission to perform `what` on `where` is granted with `params` */ event Authorized(address indexed who, address indexed where, bytes4 indexed what, Param[] params); /** * @dev Emitted every time `who`'s permission to perform `what` on `where` is revoked */ event Unauthorized(address indexed who, address indexed where, bytes4 indexed what); /** * @dev Tells whether `who` has any permission on `where` * @param who Address asking permission for * @param where Target address asking permission for */ function hasPermissions(address who, address where) external view returns (bool); /** * @dev Tells the number of permissions `who` has on `where` * @param who Address asking permission for * @param where Target address asking permission for */ function getPermissionsLength(address who, address where) external view returns (uint256); /** * @dev Tells whether `who` has permission to call `what` on `where`. Note `how` is not evaluated here, * which means `who` might be authorized on or not depending on the call at the moment of the execution * @param who Address asking permission for * @param where Target address asking permission for * @param what Function selector asking permission for */ function hasPermission(address who, address where, bytes4 what) external view returns (bool); /** * @dev Tells whether `who` is allowed to call `what` on `where` with `how` * @param who Address asking permission for * @param where Target address asking permission for * @param what Function selector asking permission for * @param how Params asking permission for */ function isAuthorized(address who, address where, bytes4 what, uint256[] memory how) external view returns (bool); /** * @dev Tells the params set for a given permission * @param who Address asking permission params of * @param where Target address asking permission params of * @param what Function selector asking permission params of */ function getPermissionParams(address who, address where, bytes4 what) external view returns (Param[] memory); /** * @dev Executes a list of permission changes * @param changes List of permission changes to be executed */ function changePermissions(PermissionChange[] memory changes) external; /** * @dev Authorizes `who` to call `what` on `where` restricted by `params` * @param who Address to be authorized * @param where Target address to be granted for * @param what Function selector to be granted * @param params Optional params to restrict a permission attempt */ function authorize(address who, address where, bytes4 what, Param[] memory params) external; /** * @dev Unauthorizes `who` to call `what` on `where`. Sender must be authorized. * @param who Address to be authorized * @param where Target address to be revoked for * @param what Function selector to be revoked */ function unauthorize(address who, address where, bytes4 what) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title 1inch V5 connector interface */ interface IOneInchV5Connector { /** * @dev The token in is the same as the token out */ error OneInchV5SwapSameToken(address token); /** * @dev The amount out is lower than the minimum amount out */ error OneInchV5BadAmountOut(uint256 amountOut, uint256 minAmountOut); /** * @dev The post token in balance is lower than the previous token in balance minus the amount in */ error OneInchV5BadPostTokenInBalance(uint256 postBalanceIn, uint256 preBalanceIn, uint256 amountIn); /** * @dev Tells the reference to 1inch aggregation router v5 */ function oneInchV5Router() external view returns (address); /** * @dev Executes a token swap in 1Inch V5 * @param tokenIn Token to be sent * @param tokenOut Token to be received * @param amountIn Amount of token in to be swapped * @param minAmountOut Minimum amount of token out willing to receive * @param data Calldata to be sent to the 1inch aggregation router */ function execute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes memory data) external returns (uint256 amountOut); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Axelar connector interface */ interface IAxelarConnector { /** * @dev The recipient address is zero */ error AxelarBridgeRecipientZero(); /** * @dev The source and destination chains are the same */ error AxelarBridgeSameChain(uint256 chainId); /** * @dev The chain ID is not supported */ error AxelarBridgeUnknownChainId(uint256 chainId); /** * @dev The post token balance is lower than the previous token balance minus the amount bridged */ error AxelarBridgeBadPostTokenBalance(uint256 postBalance, uint256 preBalance, uint256 amount); /** * @dev Tells the reference to the Axelar gateway of the source chain */ function axelarGateway() external view returns (address); /** * @dev Executes a bridge of assets using Axelar * @param chainId ID of the destination chain * @param token Address of the token to be bridged * @param amount Amount of tokens to be bridged * @param recipient Address that will receive the tokens on the destination chain */ function execute(uint256 chainId, address token, uint256 amount, address recipient) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Balancer pool connector interface */ interface IBalancerV2PoolConnector { /** * @dev The given input length is invalid or do not match */ error BalancerV2InvalidInputLength(); /** * @dev The given tokens out length is not the expected one */ error BalancerV2InvalidTokensOutLength(); /** * @dev The given pool ID and bpt in do not match on Balancer vault */ error BalancerV2InvalidPoolId(bytes32 poolId, address bpt); /** * @dev The given token does not belong to the pool */ error BalancerV2InvalidToken(bytes32 poolId, address token); /** * @dev The post balance of the token in unexpected */ error BalancerV2BadTokenInBalance(uint256 postBalance, uint256 preBalance, uint256 amountIn); /** * @dev The post balance of the token out is unexpected */ error BalancerV2BadTokenOutBalance(uint256 postBalance, uint256 preBalance); /** * @dev The resulting amount out is lower than the expected min amount out */ error BalancerV2BadAmountOut(uint256 amountOut, uint256 minAmountOut); /** * @dev Tells the reference to Balancer v2 vault */ function balancerV2Vault() external view returns (address); /** * @dev Adds liquidity to a Balancer pool * @param poolId Balancer pool ID * @param tokenIn Address of the token to join the Balancer pool * @param amountIn Amount of tokens to join the Balancer pool * @param minAmountOut Minimum amount of pool tokens expected to receive after join */ function join(bytes32 poolId, address tokenIn, uint256 amountIn, uint256 minAmountOut) external returns (uint256 amountOut); /** * @dev Removes liquidity from a Balancer pool * @param tokenIn Address of the pool to exit * @param amountIn Amount of pool tokens to exit * @param tokensOut List of addresses of tokens in the pool * @param minAmountsOut List of min amounts out to be expected for each pool token */ function exit(address tokenIn, uint256 amountIn, address[] memory tokensOut, uint256[] memory minAmountsOut) external returns (uint256[] memory amountsOut); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Balancer v2 swap connector interface */ interface IBalancerV2SwapConnector { /** * @dev The input length mismatch */ error BalancerV2InputLengthMismatch(); /** * @dev The token in is the same as the token out */ error BalancerV2SwapSameToken(address token); /** * @dev The pool does not exist on the Balancer vault */ error BalancerV2InvalidPool(bytes32 poolId); /** * @dev The requested tokens do not belong to the pool */ error BalancerV2InvalidPoolTokens(bytes32 poolId, address tokenA, address tokenB); /** * @dev The returned amount in is not equal to the requested amount in */ error BalancerV2InvalidAmountIn(int256 amountIn); /** * @dev The returned amount out is greater than or equal to zero */ error BalancerV2InvalidAmountOut(int256 amountOut); /** * @dev The amount out is lower than the minimum amount out */ error BalancerV2BadAmountOut(uint256 amountOut, uint256 minAmountOut); /** * @dev The post token in balance is lower than the previous token in balance minus the amount in */ error BalancerV2BadPostTokenInBalance(uint256 postBalanceIn, uint256 preBalanceIn, uint256 amountIn); /** * @dev Tells the reference to Balancer v2 vault */ function balancerV2Vault() external view returns (address); /** * @dev Executes a token swap in Balancer V2 * @param tokenIn Token being sent * @param tokenOut Token being received * @param amountIn Amount of tokenIn being swapped * @param minAmountOut Minimum amount of tokenOut willing to receive * @param poolId Pool ID to be used * @param hopPoolsIds Optional list of hop-pools between tokenIn and tokenOut, only used for multi-hops * @param hopTokens Optional list of hop-tokens between tokenIn and tokenOut, only used for multi-hops */ function execute( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes32 poolId, bytes32[] memory hopPoolsIds, address[] memory hopTokens ) external returns (uint256 amountOut); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IBalancerV2Vault { function getPool(bytes32 poolId) external view returns (address, uint256); function getPoolTokens(bytes32 poolId) external view returns (IERC20[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock); struct JoinPoolRequest { IERC20[] assets; uint256[] maxAmountsIn; bytes userData; bool fromInternalBalance; } function joinPool(bytes32 poolId, address sender, address recipient, JoinPoolRequest memory request) external payable; struct ExitPoolRequest { IERC20[] assets; uint256[] minAmountsOut; bytes userData; bool toInternalBalance; } function exitPool(bytes32 poolId, address sender, address payable recipient, ExitPoolRequest memory request) external; enum SwapKind { GIVEN_IN, GIVEN_OUT } struct SingleSwap { bytes32 poolId; SwapKind kind; address assetIn; address assetOut; uint256 amount; bytes userData; } struct FundManagement { address sender; bool fromInternalBalance; address payable recipient; bool toInternalBalance; } function swap(SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline) external payable returns (uint256); struct BatchSwapStep { bytes32 poolId; uint256 assetInIndex; uint256 assetOutIndex; uint256 amount; bytes userData; } function batchSwap( SwapKind kind, BatchSwapStep[] memory swaps, address[] memory assets, FundManagement memory funds, int256[] memory limits, uint256 deadline ) external payable returns (int256[] memory); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Connext connector interface * @dev Interfaces with Connext to bridge tokens */ interface IConnextConnector { /** * @dev The recipient address is zero */ error ConnextBridgeRecipientZero(); /** * @dev The source and destination chains are the same */ error ConnextBridgeSameChain(uint256 chainId); /** * @dev The chain ID is not supported */ error ConnextBridgeUnknownChainId(uint256 chainId); /** * @dev The relayer fee is greater than the amount to be bridged */ error ConnextBridgeRelayerFeeGtAmount(uint256 relayerFee, uint256 amount); /** * @dev The minimum amount out is greater than the amount to be bridged minus the relayer fee */ error ConnextBridgeMinAmountOutTooBig(uint256 minAmountOut, uint256 amount, uint256 relayerFee); /** * @dev The post token balance is lower than the previous token balance minus the amount bridged */ error ConnextBridgeBadPostTokenBalance(uint256 postBalance, uint256 preBalance, uint256 amount); /** * @dev Tells the reference to the Connext contract of the source chain */ function connext() external view returns (address); /** * @dev Executes a bridge of assets using Connext * @param chainId ID of the destination chain * @param token Address of the token to be bridged * @param amount Amount of tokens to be bridged * @param minAmountOut Min amount of tokens to receive on the destination chain after relayer fees and slippage * @param recipient Address that will receive the tokens on the destination chain * @param relayerFee Fee to be paid to the relayer */ function execute( uint256 chainId, address token, uint256 amount, uint256 minAmountOut, address recipient, uint256 relayerFee ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Convex connector interface */ interface IConvexConnector { /** * @dev Missing Convex pool for the requested Curve pool */ error ConvexCvxPoolNotFound(address curvePool); /** * @dev Failed to deposit tokens into the Convex booster */ error ConvexBoosterDepositFailed(uint256 poolId, uint256 amount); /** * @dev Failed to withdraw tokens from Convex pool */ error ConvexCvxPoolWithdrawFailed(address cvxPool, uint256 amount); /** * @dev Tells the reference to the Convex booster */ function booster() external view returns (address); /** * @dev Finds the Curve pool address associated to a Convex pool */ function getCurvePool(address cvxPool) external view returns (address); /** * @dev Finds the Curve pool address associated to a Convex pool */ function getCvxPool(address curvePool) external view returns (address); /** * @dev Claims Convex pool rewards for a Curve pool */ function claim(address cvxPool) external returns (address[] memory tokens, uint256[] memory amounts); /** * @dev Deposits Curve pool tokens into Convex * @param curvePool Address of the Curve pool to join Convex * @param amount Amount of Curve pool tokens to be deposited into Convex */ function join(address curvePool, uint256 amount) external returns (uint256); /** * @dev Withdraws Curve pool tokens from Convex * @param cvxPool Address of the Convex pool to exit from Convex * @param amount Amount of Convex tokens to be withdrawn */ function exit(address cvxPool, uint256 amount) external returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Curve 2CRV connector interface */ interface ICurve2CrvConnector { /** * @dev Failed to find the token in the 2CRV pool */ error Curve2CrvTokenNotFound(address pool, address token); /** * @dev Token decimals exceed 18 */ error Curve2CrvTokenDecimalsAbove18(address token, uint256 decimals); /** * @dev The slippage is above one */ error Curve2CrvSlippageAboveOne(uint256 slippage); /** * @dev Adds liquidity to the 2CRV pool * @param pool Address of the 2CRV pool to join * @param tokenIn Address of the token to join the 2CRV pool * @param amountIn Amount of tokens to join the 2CRV pool * @param slippage Slippage value to be used to compute the desired min amount out of pool tokens */ function join(address pool, address tokenIn, uint256 amountIn, uint256 slippage) external returns (uint256); /** * @dev Removes liquidity from 2CRV pool * @param pool Address of the 2CRV pool to exit * @param amountIn Amount of pool tokens to exit from the 2CRV pool * @param tokenOut Address of the token to exit the pool * @param slippage Slippage value to be used to compute the desired min amount out of tokens */ function exit(address pool, uint256 amountIn, address tokenOut, uint256 slippage) external returns (uint256 amountOut); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title ERC4626 connector interface */ interface IERC4626Connector { /** * @dev The token is not the underlying token of the ERC4626 */ error ERC4626InvalidToken(address token, address underlying); /** * @dev The amount deposited is lower than the expected amount */ error ERC4626BadSharesOut(uint256 shares, uint256 minSharesOut); /** * @dev The amount redeemed is lower than the expected amount */ error ERC4626BadAssetsOut(uint256 assets, uint256 minAssetsOut); /** * @dev The post token in balance is lower than the previous token in balance minus the amount in */ error ERC4626BadPostTokenInBalance(uint256 postBalanceIn, uint256 preBalanceIn, uint256 amountIn); /** * @dev Tells the underlying token of an ERC4626 */ function getToken(address erc4626) external view returns (address); /** * @dev Deposits assets to the underlying ERC4626 * @param erc4626 Address of the ERC4626 to join * @param tokenIn Address of the token to join the ERC4626 * @param assets Amount of assets to be deposited * @param minSharesOut Minimum amount of shares willing to receive */ function join(address erc4626, address tokenIn, uint256 assets, uint256 minSharesOut) external returns (address tokenOut, uint256 shares); /** * @dev Withdraws assets from the underlying ERC4626 * @param erc4626 Address of the ERC4626 to exit * @param shares Amount of shares to be redeemed * @param minAssetsOut Minimum amount of assets willing to receive */ function exit(address erc4626, uint256 shares, uint256 minAssetsOut) external returns (address token, uint256 assets); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Hop connector interface */ interface IHopBridgeConnector { /** * @dev The source and destination chains are the same */ error HopBridgeSameChain(uint256 chainId); /** * @dev The bridge operation is not supported */ error HopBridgeOpNotSupported(); /** * @dev The recipient address is zero */ error HopBridgeRecipientZero(); /** * @dev The relayer was sent when not needed */ error HopBridgeRelayerNotNeeded(); /** * @dev The deadline was sent when not needed */ error HopBridgeDeadlineNotNeeded(); /** * @dev The deadline is in the past */ error HopBridgePastDeadline(uint256 deadline, uint256 currentTimestamp); /** * @dev The post token balance is lower than the previous token balance minus the amount bridged */ error HopBridgeBadPostTokenBalance(uint256 postBalance, uint256 preBalance, uint256 amount); /** * @dev Tells the reference to the wrapped native token address */ function wrappedNativeToken() external view returns (address); /** * @dev Executes a bridge of assets using Hop Exchange * @param chainId ID of the destination chain * @param token Address of the token to be bridged * @param amount Amount of tokens to be bridged * @param minAmountOut Minimum amount of tokens willing to receive on the destination chain * @param recipient Address that will receive the tokens on the destination chain * @param bridge Address of the bridge component (i.e. hopBridge or hopAMM) * @param deadline Deadline to be used when bridging to L2 in order to swap the corresponding hToken * @param relayer Only used when transferring from L1 to L2 if a 3rd party is relaying the transfer on the user's behalf * @param fee Fee to be sent to the bridge based on the source and destination chain (i.e. relayerFee or bonderFee) */ function execute( uint256 chainId, address token, uint256 amount, uint256 minAmountOut, address recipient, address bridge, uint256 deadline, address relayer, uint256 fee ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; interface IHopL2Amm { function hToken() external view returns (address); function exchangeAddress() external view returns (address); /** * @notice To send funds L2->L1 or L2->L2, call the swapAndSend method on the L2 AMM Wrapper contract * @dev Do not set destinationAmountOutMin and destinationDeadline when sending to L1 because there is no AMM on L1, * otherwise the calculated transferId will be invalid and the transfer will be unbondable. These parameters should * be set to 0 when sending to L1. * @param amount is the amount the user wants to send plus the Bonder fee */ function swapAndSend( uint256 chainId, address recipient, uint256 amount, uint256 bonderFee, uint256 amountOutMin, uint256 deadline, uint256 destinationAmountOutMin, uint256 destinationDeadline ) external payable; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Hop swap connector interface */ interface IHopSwapConnector { /** * @dev The dex address is zero */ error HopDexAddressZero(); /** * @dev The token in is the same as the token out */ error HopSwapSameToken(address token); /** * @dev The amount out is lower than the minimum amount out */ error HopBadAmountOut(uint256 amountOut, uint256 minAmountOut); /** * @dev The post token in balance is lower than the pre token in balance minus the amount in */ error HopBadPostTokenInBalance(uint256 postBalanceIn, uint256 preBalanceIn, uint256 amountIn); /** * @dev Executes a token swap in Hop * @param tokenIn Token being sent * @param tokenOut Token being received * @param amountIn Amount of tokenIn being swapped * @param minAmountOut Minimum amount of tokenOut willing to receive * @param hopDexAddress Address of the Hop dex to be used */ function execute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, address hopDexAddress) external returns (uint256 amountOut); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Paraswap V5 connector interface */ interface IParaswapV5Connector { /** * @dev The token in is the same as the token out */ error ParaswapV5SwapSameToken(address token); /** * @dev The amount out is lower than the minimum amount out */ error ParaswapV5BadAmountOut(uint256 amountOut, uint256 minAmountOut); /** * @dev The post token in balance is lower than the previous token in balance minus the amount in */ error ParaswapV5BadPostTokenInBalance(uint256 postBalanceIn, uint256 preBalanceIn, uint256 amountIn); /** * @dev Tells the reference to Paraswap V5 Augustus swapper */ function paraswapV5Augustus() external view returns (address); /** * @dev Executes a token swap in Paraswap V5 * @param tokenIn Token being sent * @param tokenOut Token being received * @param amountIn Amount of tokenIn being swapped * @param minAmountOut Minimum amount of tokenOut willing to receive * @param data Calldata to be sent to the Augusuts swapper */ function execute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes memory data) external returns (uint256 amountOut); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Uniswap V2 connector interface */ interface IUniswapV2Connector { /** * @dev The token in is the same as the token out */ error UniswapV2SwapSameToken(address token); /** * @dev The pool does not exist */ error UniswapV2InvalidPool(address tokenA, address tokenB); /** * @dev The amount out is lower than the minimum amount out */ error UniswapV2BadAmountOut(uint256 amountOut, uint256 minAmountOut); /** * @dev The post token in balance is lower than the previous token in balance minus the amount in */ error UniswapV2BadPostTokenInBalance(uint256 postBalanceIn, uint256 preBalanceIn, uint256 amountIn); /** * @dev Tells the reference to UniswapV2 router */ function uniswapV2Router() external view returns (address); /** * @dev Executes a token swap in Uniswap V2 * @param tokenIn Token being sent * @param tokenOut Token being received * @param amountIn Amount of tokenIn being swapped * @param minAmountOut Minimum amount of tokenOut willing to receive * @param hopTokens Optional list of hop-tokens between tokenIn and tokenOut, only used for multi-hops */ function execute( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, address[] memory hopTokens ) external returns (uint256 amountOut); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Uniswap V3 connector interface */ interface IUniswapV3Connector { /** * @dev The input length mismatch */ error UniswapV3InputLengthMismatch(); /** * @dev The token in is the same as the token out */ error UniswapV3SwapSameToken(address token); /** * @dev A pool with the given tokens and fee does not exist */ error UniswapV3InvalidPoolFee(address token0, address token1, uint24 fee); /** * @dev The amount out is lower than the minimum amount out */ error UniswapV3BadAmountOut(uint256 amountOut, uint256 minAmountOut); /** * @dev The post token in balance is lower than the previous token in balance minus the amount in */ error UniswapV3BadPostTokenInBalance(uint256 postBalanceIn, uint256 preBalanceIn, uint256 amountIn); /** * @dev Tells the reference to UniswapV3 router */ function uniswapV3Router() external view returns (address); /** * @dev Executes a token swap in Uniswap V3 * @param tokenIn Token being sent * @param tokenOut Token being received * @param amountIn Amount of tokenIn being swapped * @param minAmountOut Minimum amount of tokenOut willing to receive * @param fee Fee to be used * @param hopTokens Optional list of hop-tokens between tokenIn and tokenOut, only used for multi-hops * @param hopFees Optional list of hop-fees between tokenIn and tokenOut, only used for multi-hops */ function execute( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, uint24 fee, address[] memory hopTokens, uint24[] memory hopFees ) external returns (uint256 amountOut); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @title Wormhole connector interface */ interface IWormholeConnector { /** * @dev The recipient address is zero */ error WormholeBridgeRecipientZero(); /** * @dev The source and destination chains are the same */ error WormholeBridgeSameChain(uint256 chainId); /** * @dev The chain ID is not supported */ error WormholeBridgeUnknownChainId(uint256 chainId); /** * @dev The relayer fee is greater than the amount to be bridged */ error WormholeBridgeRelayerFeeGtAmount(uint256 relayerFee, uint256 amount); /** * @dev The minimum amount out is greater than the amount to be bridged minus the relayer fee */ error WormholeBridgeMinAmountOutTooBig(uint256 minAmountOut, uint256 amount, uint256 relayerFee); /** * @dev The post token balance is lower than the previous token balance minus the amount bridged */ error WormholeBridgeBadPostTokenBalance(uint256 postBalance, uint256 preBalance, uint256 amount); /** * @dev Tells the reference to the Wormhole's CircleRelayer contract of the source chain */ function wormholeCircleRelayer() external view returns (address); /** * @dev Executes a bridge of assets using Wormhole's CircleRelayer integration * @param chainId ID of the destination chain * @param token Address of the token to be bridged * @param amount Amount of tokens to be bridged * @param minAmountOut Minimum amount of tokens willing to receive on the destination chain after relayer fees * @param recipient Address that will receive the tokens on the destination chain */ function execute(uint256 chainId, address token, uint256 amount, uint256 minAmountOut, address recipient) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; /** * @title FixedPoint * @dev Math library to operate with fixed point values with 18 decimals */ library FixedPoint { // 1 in fixed point value: 18 decimal places uint256 internal constant ONE = 1e18; /** * @dev Multiplication overflow */ error FixedPointMulOverflow(uint256 a, uint256 b); /** * @dev Division by zero */ error FixedPointZeroDivision(); /** * @dev Division internal error */ error FixedPointDivInternal(uint256 a, uint256 aInflated); /** * @dev Multiplies two fixed point numbers rounding down */ function mulDown(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { uint256 product = a * b; if (a != 0 && product / a != b) revert FixedPointMulOverflow(a, b); return product / ONE; } } /** * @dev Multiplies two fixed point numbers rounding up */ function mulUp(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { uint256 product = a * b; if (a != 0 && product / a != b) revert FixedPointMulOverflow(a, b); return product == 0 ? 0 : (((product - 1) / ONE) + 1); } } /** * @dev Divides two fixed point numbers rounding down */ function divDown(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { if (b == 0) revert FixedPointZeroDivision(); if (a == 0) return 0; uint256 aInflated = a * ONE; if (aInflated / a != ONE) revert FixedPointDivInternal(a, aInflated); return aInflated / b; } } /** * @dev Divides two fixed point numbers rounding up */ function divUp(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { if (b == 0) revert FixedPointZeroDivision(); if (a == 0) return 0; uint256 aInflated = a * ONE; if (aInflated / a != ONE) revert FixedPointDivInternal(a, aInflated); return ((aInflated - 1) / b) + 1; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/ERC20.sol'; contract TokenMock is ERC20 { uint8 internal _decimals; constructor(string memory symbol, uint8 dec) ERC20(symbol, symbol) { _decimals = dec; } function mint(address account, uint256 amount) external { _mint(account, amount); } function decimals() public view override returns (uint8) { return _decimals; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; /** * @title BytesHelpers * @dev Provides a list of Bytes helper methods */ library BytesHelpers { /** * @dev The length is shorter than start plus 32 */ error BytesOutOfBounds(uint256 start, uint256 length); /** * @dev Concatenates an address to a bytes array */ function concat(bytes memory self, address value) internal pure returns (bytes memory) { return abi.encodePacked(self, value); } /** * @dev Concatenates an uint24 to a bytes array */ function concat(bytes memory self, uint24 value) internal pure returns (bytes memory) { return abi.encodePacked(self, value); } /** * @dev Decodes a bytes array into an uint256 */ function toUint256(bytes memory self) internal pure returns (uint256) { return toUint256(self, 0); } /** * @dev Reads an uint256 from a bytes array starting at a given position */ function toUint256(bytes memory self, uint256 start) internal pure returns (uint256 result) { if (self.length < start + 32) revert BytesOutOfBounds(start, self.length); assembly { result := mload(add(add(self, 0x20), start)) } } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; /** * @title Denominations * @dev Provides a list of ground denominations for those tokens that cannot be represented by an ERC20. * For now, the only needed is the native token that could be ETH, MATIC, or other depending on the layer being operated. */ library Denominations { address internal constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // Fiat currencies follow https://en.wikipedia.org/wiki/ISO_4217 address internal constant USD = address(840); function isNativeToken(address token) internal pure returns (bool) { return token == NATIVE_TOKEN; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import './Denominations.sol'; /** * @title ERC20Helpers * @dev Provides a list of ERC20 helper methods */ library ERC20Helpers { function approve(address token, address to, uint256 amount) internal { SafeERC20.forceApprove(IERC20(token), to, amount); } function transfer(address token, address to, uint256 amount) internal { if (Denominations.isNativeToken(token)) Address.sendValue(payable(to), amount); else SafeERC20.safeTransfer(IERC20(token), to, amount); } function balanceOf(address token, address account) internal view returns (uint256) { if (Denominations.isNativeToken(token)) return address(account).balance; else return IERC20(token).balanceOf(address(account)); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '@mimic-fi/v3-authorizer/contracts/interfaces/IAuthorized.sol'; /** * @title IPriceOracle * @dev Price oracle interface * * Tells the price of a token (base) in a given quote based the following rule: the response is expressed using the * corresponding number of decimals so that when performing a fixed point product of it by a `base` amount it results * in a value expressed in `quote` decimals. For example, if `base` is ETH and `quote` is USDC, then the returned * value is expected to be expressed using 6 decimals: * * FixedPoint.mul(X[ETH], price[USDC/ETH]) = FixedPoint.mul(X[18], price[6]) = X * price [6] */ interface IPriceOracle is IAuthorized { /** * @dev Price data * @param base Token to rate * @param quote Token used for the price rate * @param rate Price of a token (base) expressed in `quote` * @param deadline Expiration timestamp until when the given quote is considered valid */ struct PriceData { address base; address quote; uint256 rate; uint256 deadline; } /** * @dev The signer is not allowed */ error PriceOracleInvalidSigner(address signer); /** * @dev The feed for the given (base, quote) pair doesn't exist */ error PriceOracleMissingFeed(address base, address quote); /** * @dev The price deadline is in the past */ error PriceOracleOutdatedPrice(address base, address quote, uint256 deadline, uint256 currentTimestamp); /** * @dev The base decimals are bigger than the quote decimals plus the fixed point decimals */ error PriceOracleBaseDecimalsTooBig(address base, uint256 baseDecimals, address quote, uint256 quoteDecimals); /** * @dev The inverse feed decimals are bigger than the maximum inverse feed decimals */ error PriceOracleInverseFeedDecimalsTooBig(address inverseFeed, uint256 inverseFeedDecimals); /** * @dev The quote feed decimals are bigger than the base feed decimals plus the fixed point decimals */ error PriceOracleQuoteFeedDecimalsTooBig(uint256 quoteFeedDecimals, uint256 baseFeedDecimals); /** * @dev Emitted every time a signer is changed */ event SignerSet(address indexed signer, bool allowed); /** * @dev Emitted every time a feed is set for (base, quote) pair */ event FeedSet(address indexed base, address indexed quote, address feed); /** * @dev Tells whether an address is as an allowed signer or not * @param signer Address of the signer being queried */ function isSignerAllowed(address signer) external view returns (bool); /** * @dev Tells the list of allowed signers */ function getAllowedSigners() external view returns (address[] memory); /** * @dev Tells the digest expected to be signed by the off-chain oracle signers for a list of prices * @param prices List of prices to be signed */ function getPricesDigest(PriceData[] memory prices) external view returns (bytes32); /** * @dev Tells the price of a token `base` expressed in a token `quote` * @param base Token to rate * @param quote Token used for the price rate */ function getPrice(address base, address quote) external view returns (uint256); /** * @dev Tells the price of a token `base` expressed in a token `quote` * @param base Token to rate * @param quote Token used for the price rate * @param data Encoded data to validate in order to compute the requested rate */ function getPrice(address base, address quote, bytes memory data) external view returns (uint256); /** * @dev Tells the feed address for (base, quote) pair. It returns the zero address if there is no one set. * @param base Token to be rated * @param quote Token used for the price rate */ function getFeed(address base, address quote) external view returns (address); /** * @dev Sets a signer condition * @param signer Address of the signer to be set * @param allowed Whether the requested signer is allowed */ function setSigner(address signer, bool allowed) external; /** * @dev Sets a feed for a (base, quote) pair * @param base Token base to be set * @param quote Token quote to be set * @param feed Feed to be set */ function setFeed(address base, address quote, address feed) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @dev Relayer interface */ interface IRelayer { /** * @dev The token is zero */ error RelayerTokenZero(); /** * @dev The amount is zero */ error RelayerAmountZero(); /** * @dev The collector is zero */ error RelayerCollectorZero(); /** * @dev The recipient is zero */ error RelayerRecipientZero(); /** * @dev The executor is zero */ error RelayerExecutorZero(); /** * @dev Relayer no task given to execute */ error RelayerNoTaskGiven(); /** * @dev Relayer input length mismatch */ error RelayerInputLengthMismatch(); /** * @dev The sender is not allowed */ error RelayerExecutorNotAllowed(address sender); /** * @dev Trying to execute tasks from different smart vaults */ error RelayerMultipleTaskSmartVaults(address task, address taskSmartVault, address expectedSmartVault); /** * @dev The task to execute does not have permissions on the associated smart vault */ error RelayerTaskDoesNotHavePermissions(address task, address smartVault); /** * @dev The smart vault balance plus the available quota are lower than the amount to pay the relayer */ error RelayerPaymentInsufficientBalance(address smartVault, uint256 balance, uint256 quota, uint256 amount); /** * @dev It failed to send amount minus quota to the smart vault's collector */ error RelayerPaymentFailed(address smartVault, uint256 amount, uint256 quota); /** * @dev The smart vault balance is lower than the amount to withdraw */ error RelayerWithdrawInsufficientBalance(address sender, uint256 balance, uint256 amount); /** * @dev It failed to send the amount to the sender */ error RelayerWithdrawFailed(address sender, uint256 amount); /** * @dev The value sent and the amount differ */ error RelayerValueDoesNotMatchAmount(uint256 value, uint256 amount); /** * @dev The simulation executed properly */ error RelayerSimulationResult(TaskResult[] taskResults); /** * @dev Emitted every time an executor is configured */ event ExecutorSet(address indexed executor, bool allowed); /** * @dev Emitted every time the default collector is set */ event DefaultCollectorSet(address indexed collector); /** * @dev Emitted every time a collector is set for a smart vault */ event SmartVaultCollectorSet(address indexed smartVault, address indexed collector); /** * @dev Emitted every time a smart vault's maximum quota is set */ event SmartVaultMaxQuotaSet(address indexed smartVault, uint256 maxQuota); /** * @dev Emitted every time a smart vault's task is executed */ event TaskExecuted( address indexed smartVault, address indexed task, bytes data, bool success, bytes result, uint256 gas, uint256 index ); /** * @dev Emitted every time some native tokens are deposited for the smart vault's balance */ event Deposited(address indexed smartVault, uint256 amount); /** * @dev Emitted every time some native tokens are withdrawn from the smart vault's balance */ event Withdrawn(address indexed smartVault, uint256 amount); /** * @dev Emitted every time some ERC20 tokens are withdrawn from the relayer to an external account */ event FundsRescued(address indexed token, address indexed recipient, uint256 amount); /** * @dev Emitted every time a smart vault's quota is paid */ event QuotaPaid(address indexed smartVault, uint256 amount); /** * @dev Emitted every time a smart vault pays for transaction gas to the relayer */ event GasPaid(address indexed smartVault, uint256 amount, uint256 quota); /** * @dev Task result * @param success Whether the task execution succeeds or not * @param result Result of the task execution */ struct TaskResult { bool success; bytes result; } /** * @dev Tells the default collector address */ function defaultCollector() external view returns (address); /** * @dev Tells whether an executor is allowed * @param executor Address of the executor being queried */ function isExecutorAllowed(address executor) external view returns (bool); /** * @dev Tells the smart vault available balance to relay transactions * @param smartVault Address of the smart vault being queried */ function getSmartVaultBalance(address smartVault) external view returns (uint256); /** * @dev Tells the custom collector address set for a smart vault * @param smartVault Address of the smart vault being queried */ function getSmartVaultCollector(address smartVault) external view returns (address); /** * @dev Tells the smart vault maximum quota to be used * @param smartVault Address of the smart vault being queried */ function getSmartVaultMaxQuota(address smartVault) external view returns (uint256); /** * @dev Tells the smart vault used quota * @param smartVault Address of the smart vault being queried */ function getSmartVaultUsedQuota(address smartVault) external view returns (uint256); /** * @dev Tells the collector address applicable for a smart vault * @param smartVault Address of the smart vault being queried */ function getApplicableCollector(address smartVault) external view returns (address); /** * @dev Configures an external executor * @param executor Address of the executor to be set * @param allowed Whether the given executor should be allowed or not */ function setExecutor(address executor, bool allowed) external; /** * @dev Sets the default collector * @param collector Address of the new default collector to be set */ function setDefaultCollector(address collector) external; /** * @dev Sets a custom collector for a smart vault * @param smartVault Address of smart vault to set a collector for * @param collector Address of the collector to be set for the given smart vault */ function setSmartVaultCollector(address smartVault, address collector) external; /** * @dev Sets a maximum quota for a smart vault * @param smartVault Address of smart vault to set a maximum quota for * @param maxQuota Maximum quota to be set for the given smart vault */ function setSmartVaultMaxQuota(address smartVault, uint256 maxQuota) external; /** * @dev Deposits native tokens for a given smart vault * @param smartVault Address of smart vault to deposit balance for * @param amount Amount of native tokens to be deposited, must match msg.value */ function deposit(address smartVault, uint256 amount) external payable; /** * @dev Withdraws native tokens from a given smart vault * @param amount Amount of native tokens to be withdrawn */ function withdraw(uint256 amount) external; /** * @dev Executes a list of tasks * @param tasks Addresses of the tasks to execute * @param data List of calldata to execute each of the given tasks * @param continueIfFailed Whether the execution should fail in case one of the tasks fail */ function execute(address[] memory tasks, bytes[] memory data, bool continueIfFailed) external; /** * @dev Simulates an execution. * WARNING: THIS METHOD IS MEANT TO BE USED AS A VIEW FUNCTION * This method will always revert. Successful results or task execution errors are returned as * `RelayerSimulationResult` errors. Any other error should be treated as failure. * @param tasks Addresses of the tasks to simulate the execution of * @param data List of calldata to simulate each of the given tasks execution * @param continueIfFailed Whether the simulation should fail in case one of the tasks execution fails */ function simulate(address[] memory tasks, bytes[] memory data, bool continueIfFailed) external; /** * @dev Withdraw ERC20 tokens to an external account. To be used in case of accidental token transfers. * @param token Address of the token to be withdrawn * @param recipient Address where the tokens will be transferred to * @param amount Amount of tokens to withdraw */ function rescueFunds(address token, address recipient, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '@mimic-fi/v3-authorizer/contracts/interfaces/IAuthorized.sol'; /** * @dev Smart Vault interface */ interface ISmartVault is IAuthorized { /** * @dev The smart vault is paused */ error SmartVaultPaused(); /** * @dev The smart vault is unpaused */ error SmartVaultUnpaused(); /** * @dev The token is zero */ error SmartVaultTokenZero(); /** * @dev The amount is zero */ error SmartVaultAmountZero(); /** * @dev The recipient is zero */ error SmartVaultRecipientZero(); /** * @dev The connector is deprecated */ error SmartVaultConnectorDeprecated(address connector); /** * @dev The connector is not registered */ error SmartVaultConnectorNotRegistered(address connector); /** * @dev The connector is not stateless */ error SmartVaultConnectorNotStateless(address connector); /** * @dev The connector ID is zero */ error SmartVaultBalanceConnectorIdZero(); /** * @dev The balance connector's balance is lower than the requested amount to be deducted */ error SmartVaultBalanceConnectorInsufficientBalance(bytes32 id, address token, uint256 balance, uint256 amount); /** * @dev The smart vault's native token balance is lower than the requested amount to be deducted */ error SmartVaultInsufficientNativeTokenBalance(uint256 balance, uint256 amount); /** * @dev Emitted every time a smart vault is paused */ event Paused(); /** * @dev Emitted every time a smart vault is unpaused */ event Unpaused(); /** * @dev Emitted every time the price oracle is set */ event PriceOracleSet(address indexed priceOracle); /** * @dev Emitted every time a connector check is overridden */ event ConnectorCheckOverridden(address indexed connector, bool ignored); /** * @dev Emitted every time a balance connector is updated */ event BalanceConnectorUpdated(bytes32 indexed id, address indexed token, uint256 amount, bool added); /** * @dev Emitted every time `execute` is called */ event Executed(address indexed connector, bytes data, bytes result); /** * @dev Emitted every time `call` is called */ event Called(address indexed target, bytes data, uint256 value, bytes result); /** * @dev Emitted every time `wrap` is called */ event Wrapped(uint256 amount); /** * @dev Emitted every time `unwrap` is called */ event Unwrapped(uint256 amount); /** * @dev Emitted every time `collect` is called */ event Collected(address indexed token, address indexed from, uint256 amount); /** * @dev Emitted every time `withdraw` is called */ event Withdrawn(address indexed token, address indexed recipient, uint256 amount, uint256 fee); /** * @dev Tells if the smart vault is paused or not */ function isPaused() external view returns (bool); /** * @dev Tells the address of the price oracle */ function priceOracle() external view returns (address); /** * @dev Tells the address of the Mimic's registry */ function registry() external view returns (address); /** * @dev Tells the address of the Mimic's fee controller */ function feeController() external view returns (address); /** * @dev Tells the address of the wrapped native token */ function wrappedNativeToken() external view returns (address); /** * @dev Tells if a connector check is ignored * @param connector Address of the connector being queried */ function isConnectorCheckIgnored(address connector) external view returns (bool); /** * @dev Tells the balance to a balance connector for a token * @param id Balance connector identifier * @param token Address of the token querying the balance connector for */ function getBalanceConnector(bytes32 id, address token) external view returns (uint256); /** * @dev Tells whether someone has any permission over the smart vault */ function hasPermissions(address who) external view returns (bool); /** * @dev Pauses a smart vault */ function pause() external; /** * @dev Unpauses a smart vault */ function unpause() external; /** * @dev Sets the price oracle * @param newPriceOracle Address of the new price oracle to be set */ function setPriceOracle(address newPriceOracle) external; /** * @dev Overrides connector checks * @param connector Address of the connector to override its check * @param ignored Whether the connector check should be ignored */ function overrideConnectorCheck(address connector, bool ignored) external; /** * @dev Updates a balance connector * @param id Balance connector identifier to be updated * @param token Address of the token to update the balance connector for * @param amount Amount to be updated to the balance connector * @param add Whether the balance connector should be increased or decreased */ function updateBalanceConnector(bytes32 id, address token, uint256 amount, bool add) external; /** * @dev Executes a connector inside of the Smart Vault context * @param connector Address of the connector that will be executed * @param data Call data to be used for the delegate-call * @return result Call response if it was successful, otherwise it reverts */ function execute(address connector, bytes memory data) external returns (bytes memory result); /** * @dev Executes an arbitrary call from the Smart Vault * @param target Address where the call will be sent * @param data Call data to be used for the call * @param value Value in wei that will be attached to the call * @return result Call response if it was successful, otherwise it reverts */ function call(address target, bytes memory data, uint256 value) external returns (bytes memory result); /** * @dev Wrap an amount of native tokens to the wrapped ERC20 version of it * @param amount Amount of native tokens to be wrapped */ function wrap(uint256 amount) external; /** * @dev Unwrap an amount of wrapped native tokens * @param amount Amount of wrapped native tokens to unwrapped */ function unwrap(uint256 amount) external; /** * @dev Collect tokens from an external account to the Smart Vault * @param token Address of the token to be collected * @param from Address where the tokens will be transferred from * @param amount Amount of tokens to be transferred */ function collect(address token, address from, uint256 amount) external; /** * @dev Withdraw tokens to an external account * @param token Address of the token to be withdrawn * @param recipient Address where the tokens will be transferred to * @param amount Amount of tokens to withdraw */ function withdraw(address token, address recipient, uint256 amount) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (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] * ```solidity * 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: MIT // OpenZeppelin Contracts (last updated v4.9.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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // ---------------------------------------------------------------------------- // DateTime Library v2.0 // // A gas-efficient Solidity date and time library // // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary // // Tested date range 1970/01/01 to 2345/12/31 // // Conventions: // Unit | Range | Notes // :-------- |:-------------:|:----- // timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC // year | 1970 ... 2345 | // month | 1 ... 12 | // day | 1 ... 31 | // hour | 0 ... 23 | // minute | 0 ... 59 | // second | 0 ... 59 | // dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday // // // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence. // ---------------------------------------------------------------------------- library DateTime { uint256 constant SECONDS_PER_DAY = 24 * 60 * 60; uint256 constant SECONDS_PER_HOUR = 60 * 60; uint256 constant SECONDS_PER_MINUTE = 60; int256 constant OFFSET19700101 = 2440588; uint256 constant DOW_MON = 1; uint256 constant DOW_TUE = 2; uint256 constant DOW_WED = 3; uint256 constant DOW_THU = 4; uint256 constant DOW_FRI = 5; uint256 constant DOW_SAT = 6; uint256 constant DOW_SUN = 7; // ------------------------------------------------------------------------ // Calculate the number of days from 1970/01/01 to year/month/day using // the date conversion algorithm from // http://aa.usno.navy.mil/faq/docs/JD_Formula.php // and subtracting the offset 2440588 so that 1970/01/01 is day 0 // // days = day // - 32075 // + 1461 * (year + 4800 + (month - 14) / 12) / 4 // + 367 * (month - 2 - (month - 14) / 12 * 12) / 12 // - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4 // - offset // ------------------------------------------------------------------------ function _daysFromDate(uint256 year, uint256 month, uint256 day) internal pure returns (uint256 _days) { require(year >= 1970); int256 _year = int256(year); int256 _month = int256(month); int256 _day = int256(day); int256 __days = _day - 32075 + (1461 * (_year + 4800 + (_month - 14) / 12)) / 4 + (367 * (_month - 2 - ((_month - 14) / 12) * 12)) / 12 - (3 * ((_year + 4900 + (_month - 14) / 12) / 100)) / 4 - OFFSET19700101; _days = uint256(__days); } // ------------------------------------------------------------------------ // Calculate year/month/day from the number of days since 1970/01/01 using // the date conversion algorithm from // http://aa.usno.navy.mil/faq/docs/JD_Formula.php // and adding the offset 2440588 so that 1970/01/01 is day 0 // // int L = days + 68569 + offset // int N = 4 * L / 146097 // L = L - (146097 * N + 3) / 4 // year = 4000 * (L + 1) / 1461001 // L = L - 1461 * year / 4 + 31 // month = 80 * L / 2447 // dd = L - 2447 * month / 80 // L = month / 11 // month = month + 2 - 12 * L // year = 100 * (N - 49) + year + L // ------------------------------------------------------------------------ function _daysToDate(uint256 _days) internal pure returns (uint256 year, uint256 month, uint256 day) { unchecked { int256 __days = int256(_days); int256 L = __days + 68569 + OFFSET19700101; int256 N = (4 * L) / 146097; L = L - (146097 * N + 3) / 4; int256 _year = (4000 * (L + 1)) / 1461001; L = L - (1461 * _year) / 4 + 31; int256 _month = (80 * L) / 2447; int256 _day = L - (2447 * _month) / 80; L = _month / 11; _month = _month + 2 - 12 * L; _year = 100 * (N - 49) + _year + L; year = uint256(_year); month = uint256(_month); day = uint256(_day); } } function timestampFromDate(uint256 year, uint256 month, uint256 day) internal pure returns (uint256 timestamp) { timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY; } function timestampFromDateTime( uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second ) internal pure returns (uint256 timestamp) { timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second; } function timestampToDate(uint256 timestamp) internal pure returns (uint256 year, uint256 month, uint256 day) { unchecked { (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY); } } function timestampToDateTime(uint256 timestamp) internal pure returns (uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second) { unchecked { (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY); uint256 secs = timestamp % SECONDS_PER_DAY; hour = secs / SECONDS_PER_HOUR; secs = secs % SECONDS_PER_HOUR; minute = secs / SECONDS_PER_MINUTE; second = secs % SECONDS_PER_MINUTE; } } function isValidDate(uint256 year, uint256 month, uint256 day) internal pure returns (bool valid) { if (year >= 1970 && month > 0 && month <= 12) { uint256 daysInMonth = _getDaysInMonth(year, month); if (day > 0 && day <= daysInMonth) { valid = true; } } } function isValidDateTime(uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second) internal pure returns (bool valid) { if (isValidDate(year, month, day)) { if (hour < 24 && minute < 60 && second < 60) { valid = true; } } } function isLeapYear(uint256 timestamp) internal pure returns (bool leapYear) { (uint256 year,,) = _daysToDate(timestamp / SECONDS_PER_DAY); leapYear = _isLeapYear(year); } function _isLeapYear(uint256 year) internal pure returns (bool leapYear) { leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); } function isWeekDay(uint256 timestamp) internal pure returns (bool weekDay) { weekDay = getDayOfWeek(timestamp) <= DOW_FRI; } function isWeekEnd(uint256 timestamp) internal pure returns (bool weekEnd) { weekEnd = getDayOfWeek(timestamp) >= DOW_SAT; } function getDaysInMonth(uint256 timestamp) internal pure returns (uint256 daysInMonth) { (uint256 year, uint256 month,) = _daysToDate(timestamp / SECONDS_PER_DAY); daysInMonth = _getDaysInMonth(year, month); } function _getDaysInMonth(uint256 year, uint256 month) internal pure returns (uint256 daysInMonth) { if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { daysInMonth = 31; } else if (month != 2) { daysInMonth = 30; } else { daysInMonth = _isLeapYear(year) ? 29 : 28; } } // 1 = Monday, 7 = Sunday function getDayOfWeek(uint256 timestamp) internal pure returns (uint256 dayOfWeek) { uint256 _days = timestamp / SECONDS_PER_DAY; dayOfWeek = ((_days + 3) % 7) + 1; } function getYear(uint256 timestamp) internal pure returns (uint256 year) { (year,,) = _daysToDate(timestamp / SECONDS_PER_DAY); } function getMonth(uint256 timestamp) internal pure returns (uint256 month) { (, month,) = _daysToDate(timestamp / SECONDS_PER_DAY); } function getDay(uint256 timestamp) internal pure returns (uint256 day) { (,, day) = _daysToDate(timestamp / SECONDS_PER_DAY); } function getHour(uint256 timestamp) internal pure returns (uint256 hour) { uint256 secs = timestamp % SECONDS_PER_DAY; hour = secs / SECONDS_PER_HOUR; } function getMinute(uint256 timestamp) internal pure returns (uint256 minute) { uint256 secs = timestamp % SECONDS_PER_HOUR; minute = secs / SECONDS_PER_MINUTE; } function getSecond(uint256 timestamp) internal pure returns (uint256 second) { second = timestamp % SECONDS_PER_MINUTE; } function addYears(uint256 timestamp, uint256 _years) internal pure returns (uint256 newTimestamp) { (uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY); year += _years; uint256 daysInMonth = _getDaysInMonth(year, month); if (day > daysInMonth) { day = daysInMonth; } newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY); require(newTimestamp >= timestamp); } function addMonths(uint256 timestamp, uint256 _months) internal pure returns (uint256 newTimestamp) { (uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY); month += _months; year += (month - 1) / 12; month = ((month - 1) % 12) + 1; uint256 daysInMonth = _getDaysInMonth(year, month); if (day > daysInMonth) { day = daysInMonth; } newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY); require(newTimestamp >= timestamp); } function addDays(uint256 timestamp, uint256 _days) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp + _days * SECONDS_PER_DAY; require(newTimestamp >= timestamp); } function addHours(uint256 timestamp, uint256 _hours) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp + _hours * SECONDS_PER_HOUR; require(newTimestamp >= timestamp); } function addMinutes(uint256 timestamp, uint256 _minutes) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE; require(newTimestamp >= timestamp); } function addSeconds(uint256 timestamp, uint256 _seconds) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp + _seconds; require(newTimestamp >= timestamp); } function subYears(uint256 timestamp, uint256 _years) internal pure returns (uint256 newTimestamp) { (uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY); year -= _years; uint256 daysInMonth = _getDaysInMonth(year, month); if (day > daysInMonth) { day = daysInMonth; } newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY); require(newTimestamp <= timestamp); } function subMonths(uint256 timestamp, uint256 _months) internal pure returns (uint256 newTimestamp) { (uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY); uint256 yearMonth = year * 12 + (month - 1) - _months; year = yearMonth / 12; month = (yearMonth % 12) + 1; uint256 daysInMonth = _getDaysInMonth(year, month); if (day > daysInMonth) { day = daysInMonth; } newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + (timestamp % SECONDS_PER_DAY); require(newTimestamp <= timestamp); } function subDays(uint256 timestamp, uint256 _days) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp - _days * SECONDS_PER_DAY; require(newTimestamp <= timestamp); } function subHours(uint256 timestamp, uint256 _hours) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp - _hours * SECONDS_PER_HOUR; require(newTimestamp <= timestamp); } function subMinutes(uint256 timestamp, uint256 _minutes) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE; require(newTimestamp <= timestamp); } function subSeconds(uint256 timestamp, uint256 _seconds) internal pure returns (uint256 newTimestamp) { newTimestamp = timestamp - _seconds; require(newTimestamp <= timestamp); } function diffYears(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _years) { require(fromTimestamp <= toTimestamp); (uint256 fromYear,,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY); (uint256 toYear,,) = _daysToDate(toTimestamp / SECONDS_PER_DAY); _years = toYear - fromYear; } function diffMonths(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _months) { require(fromTimestamp <= toTimestamp); (uint256 fromYear, uint256 fromMonth,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY); (uint256 toYear, uint256 toMonth,) = _daysToDate(toTimestamp / SECONDS_PER_DAY); _months = toYear * 12 + toMonth - fromYear * 12 - fromMonth; } function diffDays(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _days) { require(fromTimestamp <= toTimestamp); _days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY; } function diffHours(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _hours) { require(fromTimestamp <= toTimestamp); _hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR; } function diffMinutes(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _minutes) { require(fromTimestamp <= toTimestamp); _minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE; } function diffSeconds(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _seconds) { require(fromTimestamp <= toTimestamp); _seconds = toTimestamp - fromTimestamp; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-authorizer/contracts/Authorized.sol'; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-helpers/contracts/utils/Denominations.sol'; import '@mimic-fi/v3-price-oracle/contracts/interfaces/IPriceOracle.sol'; import '@mimic-fi/v3-smart-vault/contracts/interfaces/ISmartVault.sol'; import '../interfaces/base/IBaseTask.sol'; /** * @title BaseTask * @dev Base task implementation with a Smart Vault reference and using the Authorizer */ abstract contract BaseTask is IBaseTask, Authorized { // Smart Vault reference address public override smartVault; // Optional balance connector id for the previous task in the workflow bytes32 internal previousBalanceConnectorId; // Optional balance connector id for the next task in the workflow bytes32 internal nextBalanceConnectorId; /** * @dev Base task config. Only used in the initializer. * @param smartVault Address of the smart vault this task will reference, it cannot be changed once set * @param previousBalanceConnectorId Balance connector id for the previous task in the workflow * @param nextBalanceConnectorId Balance connector id for the next task in the workflow */ struct BaseConfig { address smartVault; bytes32 previousBalanceConnectorId; bytes32 nextBalanceConnectorId; } /** * @dev Initializes the base task. It does call upper contracts initializers. * @param config Base task config */ function __BaseTask_init(BaseConfig memory config) internal onlyInitializing { __Authorized_init(ISmartVault(config.smartVault).authorizer()); __BaseTask_init_unchained(config); } /** * @dev Initializes the base task. It does not call upper contracts initializers. * @param config Base task config */ function __BaseTask_init_unchained(BaseConfig memory config) internal onlyInitializing { smartVault = config.smartVault; _setBalanceConnectors(config.previousBalanceConnectorId, config.nextBalanceConnectorId); } /** * @dev Tells the address from where the token amounts to execute this task are fetched. * Since by default tasks are supposed to use balance connectors, the tokens source has to be the smart vault. * In case a task does not need to rely on a previous balance connector, it must override this function to specify * where it is getting its tokens from. */ function getTokensSource() external view virtual override returns (address) { return smartVault; } /** * @dev Tells the amount a task should use for a token. By default tasks are expected to use balance connectors. * In case a task relies on an external tokens source, it must override how the task amount is calculated. * @param token Address of the token being queried */ function getTaskAmount(address token) public view virtual override returns (uint256) { return ISmartVault(smartVault).getBalanceConnector(previousBalanceConnectorId, token); } /** * @dev Tells the previous and next balance connectors id of the previous task in the workflow */ function getBalanceConnectors() external view returns (bytes32 previous, bytes32 next) { previous = previousBalanceConnectorId; next = nextBalanceConnectorId; } /** * @dev Sets the balance connectors * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function setBalanceConnectors(bytes32 previous, bytes32 next) external override authP(authParams(previous, next)) { _setBalanceConnectors(previous, next); } /** * @dev Tells the wrapped native token address if the given address is the native token * @param token Address of the token to be checked */ function _wrappedIfNative(address token) internal view returns (address) { return Denominations.isNativeToken(token) ? _wrappedNativeToken() : token; } /** * @dev Tells whether a token is the native or the wrapped native token * @param token Address of the token to be checked */ function _isWrappedOrNative(address token) internal view returns (bool) { return Denominations.isNativeToken(token) || token == _wrappedNativeToken(); } /** * @dev Tells the wrapped native token address */ function _wrappedNativeToken() internal view returns (address) { return ISmartVault(smartVault).wrappedNativeToken(); } /** * @dev Fetches a base/quote price from the smart vault's price oracle * @param base Token to rate * @param quote Token used for the price rate */ function _getPrice(address base, address quote) internal view virtual returns (uint256) { address priceOracle = ISmartVault(smartVault).priceOracle(); if (priceOracle == address(0)) revert TaskSmartVaultPriceOracleNotSet(smartVault); bytes memory extraCallData = _decodeExtraCallData(); return extraCallData.length == 0 ? IPriceOracle(priceOracle).getPrice(_wrappedIfNative(base), _wrappedIfNative(quote)) : IPriceOracle(priceOracle).getPrice(_wrappedIfNative(base), _wrappedIfNative(quote), extraCallData); } /** * @dev Before base task hook */ function _beforeBaseTask(address token, uint256 amount) internal virtual { _decreaseBalanceConnector(token, amount); } /** * @dev After base task hook */ function _afterBaseTask(address, uint256) internal virtual { emit Executed(); } /** * @dev Decreases the previous balance connector in the smart vault if defined * @param token Address of the token to update the previous balance connector of * @param amount Amount to be updated */ function _decreaseBalanceConnector(address token, uint256 amount) internal { if (previousBalanceConnectorId != bytes32(0)) { ISmartVault(smartVault).updateBalanceConnector(previousBalanceConnectorId, token, amount, false); } } /** * @dev Increases the next balance connector in the smart vault if defined * @param token Address of the token to update the next balance connector of * @param amount Amount to be updated */ function _increaseBalanceConnector(address token, uint256 amount) internal { if (nextBalanceConnectorId != bytes32(0)) { ISmartVault(smartVault).updateBalanceConnector(nextBalanceConnectorId, token, amount, true); } } /** * @dev Sets the balance connectors * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function _setBalanceConnectors(bytes32 previous, bytes32 next) internal virtual { if (previous == next && previous != bytes32(0)) revert TaskSameBalanceConnectors(previous); previousBalanceConnectorId = previous; nextBalanceConnectorId = next; emit BalanceConnectorsSet(previous, next); } /** * @dev Decodes any potential extra calldata stored in the calldata space. Tasks relying on the extra calldata * pattern, assume that the last word of the calldata stores the extra calldata length so it can be decoded. Note * that tasks relying on this pattern must contemplate this function may return bogus data if no extra calldata * was given. */ function _decodeExtraCallData() private pure returns (bytes memory data) { uint256 length = uint256(_decodeLastCallDataWord()); if (msg.data.length < length) return new bytes(0); data = new bytes(length); assembly { calldatacopy(add(data, 0x20), sub(sub(calldatasize(), length), 0x20), length) } } /** * @dev Returns the last calldata word. This function returns zero if the calldata is not long enough. */ function _decodeLastCallDataWord() private pure returns (bytes32 result) { if (msg.data.length < 36) return bytes32(0); assembly { result := calldataload(sub(calldatasize(), 0x20)) } } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.17; import '@mimic-fi/v3-authorizer/contracts/Authorized.sol'; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-smart-vault/contracts/interfaces/ISmartVault.sol'; import '../interfaces/base/IGasLimitedTask.sol'; /** * @dev Gas config for tasks. It allows setting different gas-related configs, specially useful to control relayed txs. */ abstract contract GasLimitedTask is IGasLimitedTask, Authorized { using FixedPoint for uint256; // Variable used to allow a better developer experience to reimburse tx gas cost // solhint-disable-next-line var-name-mixedcase uint256 private __initialGas__; // Gas limits config GasLimitConfig internal gasLimits; /** * @dev Gas limits config * @param gasPriceLimit Gas price limit expressed in the native token * @param priorityFeeLimit Priority fee limit expressed in the native token * @param txCostLimit Transaction cost limit to be set * @param txCostLimitPct Transaction cost limit percentage to be set */ struct GasLimitConfig { uint256 gasPriceLimit; uint256 priorityFeeLimit; uint256 txCostLimit; uint256 txCostLimitPct; } /** * @dev Initializes the gas limited task. It does call upper contracts initializers. * @param config Gas limited task config */ function __GasLimitedTask_init(GasLimitConfig memory config) internal onlyInitializing { __GasLimitedTask_init_unchained(config); } /** * @dev Initializes the gas limited task. It does not call upper contracts initializers. * @param config Gas limited task config */ function __GasLimitedTask_init_unchained(GasLimitConfig memory config) internal onlyInitializing { _setGasLimits(config.gasPriceLimit, config.priorityFeeLimit, config.txCostLimit, config.txCostLimitPct); } /** * @dev Tells the gas limits config */ function getGasLimits() external view returns (uint256 gasPriceLimit, uint256 priorityFeeLimit, uint256 txCostLimit, uint256 txCostLimitPct) { return (gasLimits.gasPriceLimit, gasLimits.priorityFeeLimit, gasLimits.txCostLimit, gasLimits.txCostLimitPct); } /** * @dev Sets the gas limits config * @param newGasPriceLimit New gas price limit to be set * @param newPriorityFeeLimit New priority fee limit to be set * @param newTxCostLimit New tx cost limit to be set * @param newTxCostLimitPct New tx cost percentage limit to be set */ function setGasLimits( uint256 newGasPriceLimit, uint256 newPriorityFeeLimit, uint256 newTxCostLimit, uint256 newTxCostLimitPct ) external override authP(authParams(newGasPriceLimit, newPriorityFeeLimit, newTxCostLimit, newTxCostLimitPct)) { _setGasLimits(newGasPriceLimit, newPriorityFeeLimit, newTxCostLimit, newTxCostLimitPct); } /** * @dev Fetches a base/quote price */ function _getPrice(address base, address quote) internal view virtual returns (uint256); /** * @dev Initializes gas limited tasks and validates gas price limit */ function _beforeGasLimitedTask(address, uint256) internal virtual { __initialGas__ = gasleft(); GasLimitConfig memory config = gasLimits; bool isGasPriceAllowed = config.gasPriceLimit == 0 || tx.gasprice <= config.gasPriceLimit; if (!isGasPriceAllowed) revert TaskGasPriceLimitExceeded(tx.gasprice, config.gasPriceLimit); uint256 priorityFee = tx.gasprice - block.basefee; bool isPriorityFeeAllowed = config.priorityFeeLimit == 0 || priorityFee <= config.priorityFeeLimit; if (!isPriorityFeeAllowed) revert TaskPriorityFeeLimitExceeded(priorityFee, config.priorityFeeLimit); } /** * @dev Validates transaction cost limit */ function _afterGasLimitedTask(address token, uint256 amount) internal virtual { if (__initialGas__ == 0) revert TaskGasNotInitialized(); GasLimitConfig memory config = gasLimits; uint256 totalGas = __initialGas__ - gasleft(); uint256 totalCost = totalGas * tx.gasprice; bool isTxCostAllowed = config.txCostLimit == 0 || totalCost <= config.txCostLimit; if (!isTxCostAllowed) revert TaskTxCostLimitExceeded(totalCost, config.txCostLimit); delete __initialGas__; if (config.txCostLimitPct > 0 && amount > 0) { uint256 price = _getPrice(ISmartVault(this.smartVault()).wrappedNativeToken(), token); uint256 totalCostInToken = totalCost.mulUp(price); uint256 txCostPct = totalCostInToken.divUp(amount); if (txCostPct > config.txCostLimitPct) revert TaskTxCostLimitPctExceeded(txCostPct, config.txCostLimitPct); } } /** * @dev Sets the gas limits config * @param newGasPriceLimit New gas price limit to be set * @param newPriorityFeeLimit New priority fee limit to be set * @param newTxCostLimit New tx cost limit to be set * @param newTxCostLimitPct New tx cost percentage limit to be set */ function _setGasLimits( uint256 newGasPriceLimit, uint256 newPriorityFeeLimit, uint256 newTxCostLimit, uint256 newTxCostLimitPct ) internal { if (newTxCostLimitPct > FixedPoint.ONE) revert TaskTxCostLimitPctAboveOne(); gasLimits.gasPriceLimit = newGasPriceLimit; gasLimits.priorityFeeLimit = newPriorityFeeLimit; gasLimits.txCostLimit = newTxCostLimit; gasLimits.txCostLimitPct = newTxCostLimitPct; emit GasLimitsSet(newGasPriceLimit, newPriorityFeeLimit, newTxCostLimit, newTxCostLimitPct); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.17; import '@mimic-fi/v3-authorizer/contracts/Authorized.sol'; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '../interfaces/base/IPausableTask.sol'; /** * @dev Pausable config for tasks */ abstract contract PausableTask is IPausableTask, Authorized { using FixedPoint for uint256; // Whether the task is paused or not bool public override isPaused; /** * @dev Initializes the pausable task. It does call upper contracts initializers. */ function __PausableTask_init() internal onlyInitializing { __PausableTask_init_unchained(); } /** * @dev Initializes the pausable task. It does not call upper contracts initializers. */ function __PausableTask_init_unchained() internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Pauses a task */ function pause() external override auth { if (isPaused) revert TaskPaused(); isPaused = true; emit Paused(); } /** * @dev Unpauses a task */ function unpause() external override auth { if (!isPaused) revert TaskUnpaused(); isPaused = false; emit Unpaused(); } /** * @dev Before pausable task hook */ function _beforePausableTask(address, uint256) internal virtual { if (isPaused) revert TaskPaused(); } /** * @dev After pausable task hook */ function _afterPausableTask(address, uint256) internal virtual { // solhint-disable-previous-line no-empty-blocks } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.3; import '@quant-finance/solidity-datetime/contracts/DateTime.sol'; import '@mimic-fi/v3-authorizer/contracts/Authorized.sol'; import '../interfaces/base/ITimeLockedTask.sol'; /** * @dev Time lock config for tasks. It allows limiting the frequency of a task. */ abstract contract TimeLockedTask is ITimeLockedTask, Authorized { using DateTime for uint256; uint256 private constant DAYS_28 = 60 * 60 * 24 * 28; /** * @dev Time-locks supports different frequency modes * @param Seconds To indicate the execution must occur every certain number of seconds * @param OnDay To indicate the execution must occur on day number from 1 to 28 every certain months * @param OnLastMonthDay To indicate the execution must occur on the last day of the month every certain months */ enum Mode { Seconds, OnDay, OnLastMonthDay } // Time lock mode Mode internal _mode; // Time lock frequency uint256 internal _frequency; // Future timestamp since when the task can be executed uint256 internal _allowedAt; // Next future timestamp since when the task can be executed to be set, only used internally uint256 internal _nextAllowedAt; // Period in seconds during when a time-locked task can be executed since the allowed timestamp uint256 internal _window; /** * @dev Time lock config params. Only used in the initializer. * @param mode Time lock mode * @param frequency Time lock frequency value * @param allowedAt Time lock allowed date * @param window Time lock execution window */ struct TimeLockConfig { uint8 mode; uint256 frequency; uint256 allowedAt; uint256 window; } /** * @dev Initializes the time locked task. It does not call upper contracts initializers. * @param config Time locked task config */ function __TimeLockedTask_init(TimeLockConfig memory config) internal onlyInitializing { __TimeLockedTask_init_unchained(config); } /** * @dev Initializes the time locked task. It does call upper contracts initializers. * @param config Time locked task config */ function __TimeLockedTask_init_unchained(TimeLockConfig memory config) internal onlyInitializing { _setTimeLock(config.mode, config.frequency, config.allowedAt, config.window); } /** * @dev Tells the time-lock related information */ function getTimeLock() external view returns (uint8 mode, uint256 frequency, uint256 allowedAt, uint256 window) { return (uint8(_mode), _frequency, _allowedAt, _window); } /** * @dev Sets a new time lock */ function setTimeLock(uint8 mode, uint256 frequency, uint256 allowedAt, uint256 window) external override authP(authParams(mode, frequency, allowedAt, window)) { _setTimeLock(mode, frequency, allowedAt, window); } /** * @dev Before time locked task hook */ function _beforeTimeLockedTask(address, uint256) internal virtual { // Load storage variables Mode mode = _mode; uint256 frequency = _frequency; uint256 allowedAt = _allowedAt; uint256 window = _window; // First we check the current timestamp is not in the past if (block.timestamp < allowedAt) revert TaskTimeLockActive(block.timestamp, allowedAt); if (mode == Mode.Seconds) { if (frequency == 0) return; // If no window is set, the next allowed date is simply moved the number of seconds set as frequency. // Otherwise, the offset must be validated and the next allowed date is set to the next period. if (window == 0) _nextAllowedAt = block.timestamp + frequency; else { uint256 diff = block.timestamp - allowedAt; uint256 periods = diff / frequency; uint256 offset = diff - (periods * frequency); if (offset > window) revert TaskTimeLockActive(block.timestamp, allowedAt); _nextAllowedAt = allowedAt + ((periods + 1) * frequency); } } else { if (block.timestamp >= allowedAt && block.timestamp <= allowedAt + window) { // Check the current timestamp has not passed the allowed date set _nextAllowedAt = _getNextAllowedDate(allowedAt, frequency); } else { // Check the current timestamp is not before the current allowed date uint256 currentAllowedDay = mode == Mode.OnDay ? allowedAt.getDay() : block.timestamp.getDaysInMonth(); uint256 currentAllowedAt = _getCurrentAllowedDate(allowedAt, currentAllowedDay); if (block.timestamp < currentAllowedAt) revert TaskTimeLockActive(block.timestamp, currentAllowedAt); // Check the current timestamp has not passed the allowed execution window uint256 extendedCurrentAllowedAt = currentAllowedAt + window; bool exceedsExecutionWindow = block.timestamp > extendedCurrentAllowedAt; if (exceedsExecutionWindow) revert TaskTimeLockActive(block.timestamp, extendedCurrentAllowedAt); // Finally set the next allowed date to the corresponding number of months from the current date _nextAllowedAt = _getNextAllowedDate(currentAllowedAt, frequency); } } } /** * @dev After time locked task hook */ function _afterTimeLockedTask(address, uint256) internal virtual { if (_nextAllowedAt == 0) return; _setTimeLockAllowedAt(_nextAllowedAt); _nextAllowedAt = 0; } /** * @dev Sets a new time lock */ function _setTimeLock(uint8 mode, uint256 frequency, uint256 allowedAt, uint256 window) internal { if (mode == uint8(Mode.Seconds)) { // The execution window and timestamp are optional, but both must be given or none // If given the execution window cannot be larger than the number of seconds // Also, if these are given the frequency must be checked as well, otherwise it could be unsetting the lock if (window > 0 || allowedAt > 0) { if (frequency == 0) revert TaskInvalidFrequency(mode, frequency); if (window == 0 || window > frequency) revert TaskInvalidAllowedWindow(mode, window); if (allowedAt == 0) revert TaskInvalidAllowedDate(mode, allowedAt); } } else { // The other modes can be "on-day" or "on-last-day" where the frequency represents a number of months // There is no limit for the frequency, it simply cannot be zero if (frequency == 0) revert TaskInvalidFrequency(mode, frequency); // The execution window cannot be larger than the number of months considering months of 28 days if (window == 0 || window > frequency * DAYS_28) revert TaskInvalidAllowedWindow(mode, window); // The allowed date cannot be zero if (allowedAt == 0) revert TaskInvalidAllowedDate(mode, allowedAt); // If the mode is "on-day", the allowed date must be valid for every month, then the allowed day cannot be // larger than 28. But if the mode is "on-last-day", the allowed date day must be the last day of the month if (mode == uint8(Mode.OnDay)) { if (allowedAt.getDay() > 28) revert TaskInvalidAllowedDate(mode, allowedAt); } else if (mode == uint8(Mode.OnLastMonthDay)) { if (allowedAt.getDay() != allowedAt.getDaysInMonth()) revert TaskInvalidAllowedDate(mode, allowedAt); } else { revert TaskInvalidFrequencyMode(mode); } } _mode = Mode(mode); _frequency = frequency; _allowedAt = allowedAt; _window = window; emit TimeLockSet(mode, frequency, allowedAt, window); } /** * @dev Sets the time-lock execution allowed timestamp * @param allowedAt New execution allowed timestamp to be set */ function _setTimeLockAllowedAt(uint256 allowedAt) internal { _allowedAt = allowedAt; emit TimeLockAllowedAtSet(allowedAt); } /** * @dev Tells the corresponding allowed date based on a current timestamp */ function _getCurrentAllowedDate(uint256 allowedAt, uint256 day) private view returns (uint256) { (uint256 year, uint256 month, ) = block.timestamp.timestampToDate(); return _getAllowedDateFor(allowedAt, year, month, day); } /** * @dev Tells the next allowed date based on a current allowed date considering a number of months to increase */ function _getNextAllowedDate(uint256 allowedAt, uint256 monthsToIncrease) private view returns (uint256) { (uint256 year, uint256 month, uint256 day) = allowedAt.timestampToDate(); uint256 increasedMonth = month + monthsToIncrease; uint256 nextMonth = increasedMonth % 12; uint256 nextYear = year + (increasedMonth / 12); uint256 nextDay = _mode == Mode.OnLastMonthDay ? DateTime._getDaysInMonth(nextYear, nextMonth) : day; return _getAllowedDateFor(allowedAt, nextYear, nextMonth, nextDay); } /** * @dev Builds an allowed date using a specific year, month, and day */ function _getAllowedDateFor(uint256 allowedAt, uint256 year, uint256 month, uint256 day) private pure returns (uint256) { return DateTime.timestampFromDateTime( year, month, day, allowedAt.getHour(), allowedAt.getMinute(), allowedAt.getSecond() ); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.3; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; import '@mimic-fi/v3-authorizer/contracts/Authorized.sol'; import '../interfaces/base/ITokenIndexedTask.sol'; /** * @dev Token indexed task. It defines a token acceptance list to tell which are the tokens supported by the * task. Tokens acceptance can be configured either as an allow list or as a deny list. */ abstract contract TokenIndexedTask is ITokenIndexedTask, Authorized { using EnumerableSet for EnumerableSet.AddressSet; // Acceptance list type TokensAcceptanceType public override tokensAcceptanceType; // Enumerable set of tokens included in the acceptance list EnumerableSet.AddressSet internal _tokens; /** * @dev Token index config. Only used in the initializer. * @param acceptanceType Token acceptance type to be set * @param tokens List of token addresses to be set for the acceptance list */ struct TokenIndexConfig { TokensAcceptanceType acceptanceType; address[] tokens; } /** * @dev Initializes the token indexed task. It does not call upper contracts initializers. * @param config Token indexed task config */ function __TokenIndexedTask_init(TokenIndexConfig memory config) internal onlyInitializing { __TokenIndexedTask_init_unchained(config); } /** * @dev Initializes the token indexed task. It does call upper contracts initializers. * @param config Token indexed task config */ function __TokenIndexedTask_init_unchained(TokenIndexConfig memory config) internal onlyInitializing { _setTokensAcceptanceType(config.acceptanceType); for (uint256 i = 0; i < config.tokens.length; i++) { _setTokenAcceptanceList(config.tokens[i], true); } } /** * @dev Tells whether a token is allowed or not * @param token Address of the token being queried */ function isTokenAllowed(address token) public view override returns (bool) { bool containsToken = _tokens.contains(token); return tokensAcceptanceType == TokensAcceptanceType.AllowList ? containsToken : !containsToken; } /** * @dev Sets the tokens acceptance type of the task * @param newTokensAcceptanceType New token acceptance type to be set */ function setTokensAcceptanceType(TokensAcceptanceType newTokensAcceptanceType) external override authP(authParams(uint8(newTokensAcceptanceType))) { _setTokensAcceptanceType(newTokensAcceptanceType); } /** * @dev Updates the list of tokens of the tokens acceptance list * @param tokens List of tokens to be updated from the acceptance list * @param added Whether each of the given tokens should be added or removed from the list */ function setTokensAcceptanceList(address[] memory tokens, bool[] memory added) external override auth { if (tokens.length != added.length) revert TaskAcceptanceInputLengthMismatch(); for (uint256 i = 0; i < tokens.length; i++) { _setTokenAcceptanceList(tokens[i], added[i]); } } /** * @dev Before token indexed task hook */ function _beforeTokenIndexedTask(address token, uint256) internal virtual { if (!isTokenAllowed(token)) revert TaskTokenNotAllowed(token); } /** * @dev After token indexed task hook */ function _afterTokenIndexedTask(address token, uint256) internal virtual { // solhint-disable-previous-line no-empty-blocks } /** * @dev Sets the tokens acceptance type of the task * @param newTokensAcceptanceType New token acceptance type to be set */ function _setTokensAcceptanceType(TokensAcceptanceType newTokensAcceptanceType) internal { tokensAcceptanceType = newTokensAcceptanceType; emit TokensAcceptanceTypeSet(newTokensAcceptanceType); } /** * @dev Updates a token from the tokens acceptance list * @param token Token to be updated from the acceptance list * @param added Whether the token should be added or removed from the list */ function _setTokenAcceptanceList(address token, bool added) internal { if (token == address(0)) revert TaskAcceptanceTokenZero(); added ? _tokens.add(token) : _tokens.remove(token); emit TokensAcceptanceListSet(token, added); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.3; import '@mimic-fi/v3-authorizer/contracts/Authorized.sol'; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '../interfaces/base/ITokenThresholdTask.sol'; /** * @dev Token threshold task. It mainly works with token threshold configs that can be used to tell if * a specific token amount is compliant with certain minimum or maximum values. Token threshold tasks * make use of a default threshold config as a fallback in case there is no custom threshold defined for the token * being evaluated. */ abstract contract TokenThresholdTask is ITokenThresholdTask, Authorized { using FixedPoint for uint256; // Default threshold Threshold internal _defaultThreshold; // Custom thresholds per token mapping (address => Threshold) internal _customThresholds; /** * @dev Threshold defined by a token address and min/max values */ struct Threshold { address token; uint256 min; uint256 max; } /** * @dev Custom token threshold config. Only used in the initializer. */ struct CustomThresholdConfig { address token; Threshold threshold; } /** * @dev Token threshold config. Only used in the initializer. * @param defaultThreshold Default threshold to be set * @param customThresholdConfigs List of custom threshold configs to be set */ struct TokenThresholdConfig { Threshold defaultThreshold; CustomThresholdConfig[] customThresholdConfigs; } /** * @dev Initializes the token threshold task. It does not call upper contracts initializers. * @param config Token threshold task config */ function __TokenThresholdTask_init(TokenThresholdConfig memory config) internal onlyInitializing { __TokenThresholdTask_init_unchained(config); } /** * @dev Initializes the token threshold task. It does call upper contracts initializers. * @param config Token threshold task config */ function __TokenThresholdTask_init_unchained(TokenThresholdConfig memory config) internal onlyInitializing { Threshold memory defaultThreshold = config.defaultThreshold; _setDefaultTokenThreshold(defaultThreshold.token, defaultThreshold.min, defaultThreshold.max); for (uint256 i = 0; i < config.customThresholdConfigs.length; i++) { CustomThresholdConfig memory customThresholdConfig = config.customThresholdConfigs[i]; Threshold memory custom = customThresholdConfig.threshold; _setCustomTokenThreshold(customThresholdConfig.token, custom.token, custom.min, custom.max); } } /** * @dev Tells the default token threshold */ function defaultTokenThreshold() external view override returns (address thresholdToken, uint256 min, uint256 max) { Threshold memory threshold = _defaultThreshold; return (threshold.token, threshold.min, threshold.max); } /** * @dev Tells the token threshold defined for a specific token * @param token Address of the token being queried */ function customTokenThreshold(address token) external view override returns (address thresholdToken, uint256 min, uint256 max) { Threshold memory threshold = _customThresholds[token]; return (threshold.token, threshold.min, threshold.max); } /** * @dev Tells the threshold that should be used for a token, it prioritizes custom thresholds over the default one * @param token Address of the token being queried */ function getTokenThreshold(address token) external view virtual override returns (address thresholdToken, uint256 min, uint256 max) { Threshold memory threshold = _getTokenThreshold(token); return (threshold.token, threshold.min, threshold.max); } /** * @dev Sets a new default threshold config * @param thresholdToken New threshold token to be set * @param min New threshold minimum to be set * @param max New threshold maximum to be set */ function setDefaultTokenThreshold(address thresholdToken, uint256 min, uint256 max) external override authP(authParams(thresholdToken, min, max)) { _setDefaultTokenThreshold(thresholdToken, min, max); } /** * @dev Sets a custom token threshold * @param token Address of the token to set a custom threshold for * @param thresholdToken New custom threshold token to be set * @param min New custom threshold minimum to be set * @param max New custom threshold maximum to be set */ function setCustomTokenThreshold(address token, address thresholdToken, uint256 min, uint256 max) external override authP(authParams(token, thresholdToken, min, max)) { _setCustomTokenThreshold(token, thresholdToken, min, max); } /** * @dev Fetches a base/quote price */ function _getPrice(address base, address quote) internal view virtual returns (uint256); /** * @dev Tells the threshold that should be used for a token, it prioritizes custom thresholds over the default one * @param token Address of the token being queried */ function _getTokenThreshold(address token) internal view returns (Threshold memory) { Threshold storage customThreshold = _customThresholds[token]; return customThreshold.token == address(0) ? _defaultThreshold : customThreshold; } /** * @dev Before token threshold task hook */ function _beforeTokenThresholdTask(address token, uint256 amount) internal virtual { Threshold memory threshold = _getTokenThreshold(token); if (threshold.token == address(0)) return; uint256 convertedAmount = threshold.token == token ? amount : amount.mulDown(_getPrice(token, threshold.token)); bool isValid = convertedAmount >= threshold.min && (threshold.max == 0 || convertedAmount <= threshold.max); if (!isValid) revert TaskTokenThresholdNotMet(threshold.token, convertedAmount, threshold.min, threshold.max); } /** * @dev After token threshold task hook */ function _afterTokenThresholdTask(address, uint256) internal virtual { // solhint-disable-previous-line no-empty-blocks } /** * @dev Sets a new default threshold config * @param thresholdToken New threshold token to be set * @param min New threshold minimum to be set * @param max New threshold maximum to be set */ function _setDefaultTokenThreshold(address thresholdToken, uint256 min, uint256 max) internal { _setTokenThreshold(_defaultThreshold, thresholdToken, min, max); emit DefaultTokenThresholdSet(thresholdToken, min, max); } /** * @dev Sets a custom of tokens thresholds * @param token Address of the token to set a custom threshold for * @param thresholdToken New custom threshold token to be set * @param min New custom threshold minimum to be set * @param max New custom threshold maximum to be set */ function _setCustomTokenThreshold(address token, address thresholdToken, uint256 min, uint256 max) internal { if (token == address(0)) revert TaskThresholdTokenZero(); _setTokenThreshold(_customThresholds[token], thresholdToken, min, max); emit CustomTokenThresholdSet(token, thresholdToken, min, max); } /** * @dev Sets a threshold * @param threshold Threshold to be updated * @param token New threshold token to be set * @param min New threshold minimum to be set * @param max New threshold maximum to be set */ function _setTokenThreshold(Threshold storage threshold, address token, uint256 min, uint256 max) private { // If there is no threshold, all values must be zero bool isZeroThreshold = token == address(0) && min == 0 && max == 0; bool isNonZeroThreshold = token != address(0) && (max == 0 || max >= min); if (!isZeroThreshold && !isNonZeroThreshold) revert TaskInvalidThresholdInput(token, min, max); threshold.token = token; threshold.min = min; threshold.max = max; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.17; import '@mimic-fi/v3-authorizer/contracts/Authorized.sol'; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '../interfaces/base/IVolumeLimitedTask.sol'; /** * @dev Volume limit config for tasks. It allows setting volume limit per period of time. */ abstract contract VolumeLimitedTask is IVolumeLimitedTask, Authorized { using FixedPoint for uint256; // Default volume limit VolumeLimit internal _defaultVolumeLimit; // Custom volume limits per token mapping (address => VolumeLimit) internal _customVolumeLimits; /** * @dev Volume limit config * @param token Address to measure the volume limit */ struct VolumeLimit { address token; uint256 amount; uint256 accrued; uint256 period; uint256 nextResetTime; } /** * @dev Volume limit params. Only used in the initializer. */ struct VolumeLimitParams { address token; uint256 amount; uint256 period; } /** * @dev Custom token volume limit config. Only used in the initializer. */ struct CustomVolumeLimitConfig { address token; VolumeLimitParams volumeLimit; } /** * @dev Volume limit config. Only used in the initializer. */ struct VolumeLimitConfig { VolumeLimitParams defaultVolumeLimit; CustomVolumeLimitConfig[] customVolumeLimitConfigs; } /** * @dev Initializes the volume limited task. It does call upper contracts initializers. * @param config Volume limited task config */ function __VolumeLimitedTask_init(VolumeLimitConfig memory config) internal onlyInitializing { __VolumeLimitedTask_init_unchained(config); } /** * @dev Initializes the volume limited task. It does not call upper contracts initializers. * @param config Volume limited task config */ function __VolumeLimitedTask_init_unchained(VolumeLimitConfig memory config) internal onlyInitializing { VolumeLimitParams memory defaultLimit = config.defaultVolumeLimit; _setDefaultVolumeLimit(defaultLimit.token, defaultLimit.amount, defaultLimit.period); for (uint256 i = 0; i < config.customVolumeLimitConfigs.length; i++) { CustomVolumeLimitConfig memory customVolumeLimitConfig = config.customVolumeLimitConfigs[i]; VolumeLimitParams memory custom = customVolumeLimitConfig.volumeLimit; _setCustomVolumeLimit(customVolumeLimitConfig.token, custom.token, custom.amount, custom.period); } } /** * @dev Tells the default volume limit set */ function defaultVolumeLimit() external view override returns (address limitToken, uint256 amount, uint256 accrued, uint256 period, uint256 nextResetTime) { VolumeLimit memory limit = _defaultVolumeLimit; return (limit.token, limit.amount, limit.accrued, limit.period, limit.nextResetTime); } /** * @dev Tells the custom volume limit set for a specific token * @param token Address of the token being queried */ function customVolumeLimit(address token) external view override returns (address limitToken, uint256 amount, uint256 accrued, uint256 period, uint256 nextResetTime) { VolumeLimit memory limit = _customVolumeLimits[token]; return (limit.token, limit.amount, limit.accrued, limit.period, limit.nextResetTime); } /** * @dev Tells the volume limit that should be used for a token, it prioritizes custom limits over the default one * @param token Address of the token being queried */ function getVolumeLimit(address token) external view override returns (address limitToken, uint256 amount, uint256 accrued, uint256 period, uint256 nextResetTime) { VolumeLimit memory limit = _getVolumeLimit(token); return (limit.token, limit.amount, limit.accrued, limit.period, limit.nextResetTime); } /** * @dev Sets a the default volume limit config * @param limitToken Address of the token to measure the volume limit * @param limitAmount Amount of tokens to be applied for the volume limit * @param limitPeriod Frequency to Amount of tokens to be applied for the volume limit */ function setDefaultVolumeLimit(address limitToken, uint256 limitAmount, uint256 limitPeriod) external override authP(authParams(limitToken, limitAmount, limitPeriod)) { _setDefaultVolumeLimit(limitToken, limitAmount, limitPeriod); } /** * @dev Sets a custom volume limit * @param token Address of the token to set a custom volume limit for * @param limitToken Address of the token to measure the volume limit * @param limitAmount Amount of tokens to be applied for the volume limit * @param limitPeriod Frequency to Amount of tokens to be applied for the volume limit */ function setCustomVolumeLimit(address token, address limitToken, uint256 limitAmount, uint256 limitPeriod) external override authP(authParams(token, limitToken, limitAmount, limitPeriod)) { _setCustomVolumeLimit(token, limitToken, limitAmount, limitPeriod); } /** * @dev Fetches a base/quote price */ function _getPrice(address base, address quote) internal view virtual returns (uint256); /** * @dev Tells the volume limit that should be used for a token, it prioritizes custom limits over the default one * @param token Address of the token being queried */ function _getVolumeLimit(address token) internal view returns (VolumeLimit storage) { VolumeLimit storage customLimit = _customVolumeLimits[token]; return customLimit.token == address(0) ? _defaultVolumeLimit : customLimit; } /** * @dev Before volume limited task hook */ function _beforeVolumeLimitedTask(address token, uint256 amount) internal virtual { VolumeLimit memory limit = _getVolumeLimit(token); if (limit.token == address(0)) return; uint256 amountInLimitToken = limit.token == token ? amount : amount.mulDown(_getPrice(token, limit.token)); uint256 processedVolume = amountInLimitToken + (block.timestamp < limit.nextResetTime ? limit.accrued : 0); if (processedVolume > limit.amount) revert TaskVolumeLimitExceeded(limit.token, limit.amount, processedVolume); } /** * @dev After volume limited task hook */ function _afterVolumeLimitedTask(address token, uint256 amount) internal virtual { VolumeLimit storage limit = _getVolumeLimit(token); if (limit.token == address(0)) return; uint256 amountInLimitToken = limit.token == token ? amount : amount.mulDown(_getPrice(token, limit.token)); if (block.timestamp >= limit.nextResetTime) { limit.accrued = 0; limit.nextResetTime = block.timestamp + limit.period; } limit.accrued += amountInLimitToken; } /** * @dev Sets the default volume limit * @param limitToken Address of the token to measure the volume limit * @param limitAmount Amount of tokens to be applied for the volume limit * @param limitPeriod Frequency to Amount of tokens to be applied for the volume limit */ function _setDefaultVolumeLimit(address limitToken, uint256 limitAmount, uint256 limitPeriod) internal { _setVolumeLimit(_defaultVolumeLimit, limitToken, limitAmount, limitPeriod); emit DefaultVolumeLimitSet(limitToken, limitAmount, limitPeriod); } /** * @dev Sets a custom volume limit * @param token Address of the token to set a custom volume limit for * @param limitToken Address of the token to measure the volume limit * @param limitAmount Amount of tokens to be applied for the volume limit * @param limitPeriod Frequency to Amount of tokens to be applied for the volume limit */ function _setCustomVolumeLimit(address token, address limitToken, uint256 limitAmount, uint256 limitPeriod) internal { if (token == address(0)) revert TaskVolumeLimitTokenZero(); _setVolumeLimit(_customVolumeLimits[token], limitToken, limitAmount, limitPeriod); emit CustomVolumeLimitSet(token, limitToken, limitAmount, limitPeriod); } /** * @dev Sets a volume limit * @param limit Volume limit to be updated * @param token Address of the token to measure the volume limit * @param amount Amount of tokens to be applied for the volume limit * @param period Frequency to Amount of tokens to be applied for the volume limit */ function _setVolumeLimit(VolumeLimit storage limit, address token, uint256 amount, uint256 period) private { // If there is no limit, all values must be zero bool isZeroLimit = token == address(0) && amount == 0 && period == 0; bool isNonZeroLimit = token != address(0) && amount > 0 && period > 0; if (!isZeroLimit && !isNonZeroLimit) revert TaskInvalidVolumeLimitInput(token, amount, period); // Changing the period only affects the end time of the next period, but not the end date of the current one limit.period = period; // Changing the amount does not affect the totalizator, it only applies when updating the accrued amount. // Note that it can happen that the new amount is lower than the accrued amount if the amount is lowered. // However, there shouldn't be any accounting issues with that. limit.amount = amount; // Therefore, only clean the totalizators if the limit is being removed if (isZeroLimit) { limit.accrued = 0; limit.nextResetTime = 0; } else { // If limit is not zero, set the next reset time if it wasn't set already // Otherwise, if the token is being changed the accrued amount must be updated accordingly if (limit.nextResetTime == 0) { limit.accrued = 0; limit.nextResetTime = block.timestamp + period; } else if (limit.token != token) { uint256 price = _getPrice(limit.token, token); limit.accrued = limit.accrued.mulDown(price); } } // Finally simply set the new requested token limit.token = token; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/axelar/IAxelarConnector.sol'; import './BaseBridgeTask.sol'; import '../interfaces/bridge/IAxelarBridger.sol'; /** * @title Axelar bridger * @dev Task that extends the base bridge task to use Axelar */ contract AxelarBridger is IAxelarBridger, BaseBridgeTask { using FixedPoint for uint256; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('AXELAR_BRIDGER'); /** * @dev Axelar bridge config. Only used in the initializer. */ struct AxelarBridgeConfig { BaseBridgeConfig baseBridgeConfig; } /** * @dev Initializes the Axelar bridger * @param config Axelar bridge config */ function initialize(AxelarBridgeConfig memory config) external virtual initializer { __AxelarBridger_init(config); } /** * @dev Initializes the Axelar bridger. It does call upper contracts initializers. * @param config Axelar bridge config */ function __AxelarBridger_init(AxelarBridgeConfig memory config) internal onlyInitializing { __BaseBridgeTask_init(config.baseBridgeConfig); __AxelarBridger_init_unchained(config); } /** * @dev Initializes the Axelar bridger. It does not call upper contracts initializers. * @param config Axelar bridge config */ function __AxelarBridger_init_unchained(AxelarBridgeConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Execute Axelar bridger */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeAxelarBridger(token, amount); bytes memory connectorData = abi.encodeWithSelector( IAxelarConnector.execute.selector, getDestinationChain(token), token, amount, recipient ); ISmartVault(smartVault).execute(connector, connectorData); _afterAxelarBridger(token, amount); } /** * @dev Before Axelar bridger hook */ function _beforeAxelarBridger(address token, uint256 amount) internal virtual { // Axelar does not support specifying slippage nor fee _beforeBaseBridgeTask(token, amount, 0, 0); } /** * @dev After Axelar bridger task hook */ function _afterAxelarBridger(address token, uint256 amount) internal virtual { // Axelar does not support specifying slippage nor fee _afterBaseBridgeTask(token, amount, 0, 0); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '../Task.sol'; import '../interfaces/bridge/IBaseBridgeTask.sol'; /** * @title Base bridge task * @dev Task that offers the basic components for more detailed bridge tasks */ abstract contract BaseBridgeTask is IBaseBridgeTask, Task { using FixedPoint for uint256; // Connector address address public override connector; // Connector address address public override recipient; // Default destination chain uint256 public override defaultDestinationChain; // Default maximum slippage in fixed point uint256 public override defaultMaxSlippage; // Default maximum fee MaxFee internal _defaultMaxFee; // Destination chain per token address mapping (address => uint256) public override customDestinationChain; // Maximum slippage per token address mapping (address => uint256) public override customMaxSlippage; // Maximum fee per token address mapping (address => MaxFee) internal _customMaxFee; /** * @dev Maximum fee defined by a token address and a max fee value */ struct MaxFee { address token; uint256 amount; } /** * @dev Custom destination chain config. Only used in the initializer. */ struct CustomDestinationChain { address token; uint256 destinationChain; } /** * @dev Custom max slippage config. Only used in the initializer. */ struct CustomMaxSlippage { address token; uint256 maxSlippage; } /** * @dev Custom max fee config. Only used in the initializer. */ struct CustomMaxFee { address token; MaxFee maxFee; } /** * @dev Base bridge config. Only used in the initializer. */ struct BaseBridgeConfig { address connector; address recipient; uint256 destinationChain; uint256 maxSlippage; MaxFee maxFee; CustomDestinationChain[] customDestinationChains; CustomMaxSlippage[] customMaxSlippages; CustomMaxFee[] customMaxFees; TaskConfig taskConfig; } /** * @dev Initializes the base bridge task. It does call upper contracts initializers. * @param config Base bridge config */ function __BaseBridgeTask_init(BaseBridgeConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __BaseBridgeTask_init_unchained(config); } /** * @dev Initializes the base bridge task. It does not call upper contracts initializers. * @param config Base bridge config */ function __BaseBridgeTask_init_unchained(BaseBridgeConfig memory config) internal onlyInitializing { _setConnector(config.connector); _setRecipient(config.recipient); _setDefaultDestinationChain(config.destinationChain); _setDefaultMaxSlippage(config.maxSlippage); MaxFee memory defaultFee = config.maxFee; _setDefaultMaxFee(defaultFee.token, defaultFee.amount); for (uint256 i = 0; i < config.customDestinationChains.length; i++) { CustomDestinationChain memory customConfig = config.customDestinationChains[i]; _setCustomDestinationChain(customConfig.token, customConfig.destinationChain); } for (uint256 i = 0; i < config.customMaxSlippages.length; i++) { _setCustomMaxSlippage(config.customMaxSlippages[i].token, config.customMaxSlippages[i].maxSlippage); } for (uint256 i = 0; i < config.customMaxFees.length; i++) { CustomMaxFee memory customConfig = config.customMaxFees[i]; MaxFee memory maxFee = customConfig.maxFee; _setCustomMaxFee(customConfig.token, maxFee.token, maxFee.amount); } } /** * @dev Tells the default max fee */ function defaultMaxFee() external view override returns (address maxFeeToken, uint256 amount) { MaxFee memory maxFee = _defaultMaxFee; return (maxFee.token, maxFee.amount); } /** * @dev Tells the max fee defined for a specific token * @param token Address of the token being queried */ function customMaxFee(address token) external view override returns (address maxFeeToken, uint256 amount) { MaxFee memory maxFee = _customMaxFee[token]; return (maxFee.token, maxFee.amount); } /** * @dev Tells the destination chain that should be used for a token * @param token Address of the token to get the destination chain for */ function getDestinationChain(address token) public view virtual override returns (uint256) { uint256 chain = customDestinationChain[token]; return chain == 0 ? defaultDestinationChain : chain; } /** * @dev Tells the max slippage that should be used for a token * @param token Address of the token to get the max slippage for */ function getMaxSlippage(address token) public view virtual override returns (uint256) { uint256 maxSlippage = customMaxSlippage[token]; return maxSlippage == 0 ? defaultMaxSlippage : maxSlippage; } /** * @dev Tells the max fee that should be used for a token * @param token Address of the token to get the max fee for */ function getMaxFee(address token) external view virtual override returns (address maxFeeToken, uint256 amount) { MaxFee memory maxFee = _getMaxFee(token); return (maxFee.token, maxFee.amount); } /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function setConnector(address newConnector) external override authP(authParams(newConnector)) { _setConnector(newConnector); } /** * @dev Sets the recipient address. Sender must be authorized. * @param newRecipient Address of the new recipient to be set */ function setRecipient(address newRecipient) external override authP(authParams(newRecipient)) { _setRecipient(newRecipient); } /** * @dev Sets the default destination chain * @param destinationChain Default destination chain to be set */ function setDefaultDestinationChain(uint256 destinationChain) external override authP(authParams(destinationChain)) { _setDefaultDestinationChain(destinationChain); } /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function setDefaultMaxSlippage(uint256 maxSlippage) external override authP(authParams(maxSlippage)) { _setDefaultMaxSlippage(maxSlippage); } /** * @dev Sets the default max fee * @param maxFeeToken Default max fee token to be set * @param amount Default max fee amount to be set */ function setDefaultMaxFee(address maxFeeToken, uint256 amount) external override authP(authParams(maxFeeToken, amount)) { _setDefaultMaxFee(maxFeeToken, amount); } /** * @dev Sets a custom destination chain * @param token Address of the token to set a custom destination chain for * @param destinationChain Destination chain to be set */ function setCustomDestinationChain(address token, uint256 destinationChain) external override authP(authParams(token, destinationChain)) { _setCustomDestinationChain(token, destinationChain); } /** * @dev Sets a custom max slippage * @param token Address of the token to set a custom max slippage for * @param maxSlippage Max slippage to be set */ function setCustomMaxSlippage(address token, uint256 maxSlippage) external override authP(authParams(token, maxSlippage)) { _setCustomMaxSlippage(token, maxSlippage); } /** * @dev Sets a custom max fee * @param token Address of the token to set a custom max fee for * @param maxFeeToken Max fee token to be set for the given token * @param amount Max fee amount to be set for the given token */ function setCustomMaxFee(address token, address maxFeeToken, uint256 amount) external override authP(authParams(token, maxFeeToken, amount)) { _setCustomMaxFee(token, maxFeeToken, amount); } /** * @dev Tells the max fee that should be used for a token * @param token Address of the token to get the max fee for */ function _getMaxFee(address token) internal view virtual returns (MaxFee memory) { MaxFee memory maxFee = _customMaxFee[token]; return maxFee.token == address(0) ? _defaultMaxFee : maxFee; } /** * @dev Before base bridge task hook */ function _beforeBaseBridgeTask(address token, uint256 amount, uint256 slippage, uint256 fee) internal virtual { _beforeTask(token, amount); if (token == address(0)) revert TaskTokenZero(); if (amount == 0) revert TaskAmountZero(); if (getDestinationChain(token) == 0) revert TaskDestinationChainNotSet(); uint256 maxSlippage = getMaxSlippage(token); if (slippage > maxSlippage) revert TaskSlippageAboveMax(slippage, maxSlippage); // If no fee is given we simply ignore the max fee config if (fee == 0) return; // Otherwise, we revert in case there is no max fee set MaxFee memory maxFee = _getMaxFee(token); if (maxFee.token == address(0)) revert TaskFeeAboveMax(fee, maxFee.amount); uint256 convertedFee = maxFee.token == token ? fee : fee.mulDown(_getPrice(token, maxFee.token)); if (convertedFee > maxFee.amount) revert TaskFeeAboveMax(convertedFee, maxFee.amount); } /** * @dev After base bridge task hook */ function _afterBaseBridgeTask(address token, uint256 amount, uint256, uint256) internal virtual { _afterTask(token, amount); } /** * @dev Sets the balance connectors. Next balance connector must be unset. * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function _setBalanceConnectors(bytes32 previous, bytes32 next) internal virtual override { if (next != bytes32(0)) revert TaskNextConnectorNotZero(next); super._setBalanceConnectors(previous, next); } /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function _setConnector(address newConnector) internal { if (newConnector == address(0)) revert TaskConnectorZero(); connector = newConnector; emit ConnectorSet(newConnector); } /** * @dev Sets the recipient address * @param newRecipient Address of the new recipient to be set */ function _setRecipient(address newRecipient) internal { if (newRecipient == address(0)) revert TaskRecipientZero(); recipient = newRecipient; emit RecipientSet(newRecipient); } /** * @dev Sets the default destination chain * @param destinationChain Default destination chain to be set */ function _setDefaultDestinationChain(uint256 destinationChain) internal { if (destinationChain == block.chainid) revert TaskBridgeCurrentChainId(destinationChain); defaultDestinationChain = destinationChain; emit DefaultDestinationChainSet(destinationChain); } /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function _setDefaultMaxSlippage(uint256 maxSlippage) internal { if (maxSlippage > FixedPoint.ONE) revert TaskSlippageAboveOne(); defaultMaxSlippage = maxSlippage; emit DefaultMaxSlippageSet(maxSlippage); } /** * @dev Sets the default max fee * @param maxFeeToken Default max fee token to be set * @param amount Default max fee amount to be set */ function _setDefaultMaxFee(address maxFeeToken, uint256 amount) internal { _setMaxFee(_defaultMaxFee, maxFeeToken, amount); emit DefaultMaxFeeSet(maxFeeToken, amount); } /** * @dev Sets a custom destination chain for a token * @param token Address of the token to set the custom destination chain for * @param destinationChain Destination chain to be set */ function _setCustomDestinationChain(address token, uint256 destinationChain) internal { if (token == address(0)) revert TaskTokenZero(); if (destinationChain == block.chainid) revert TaskBridgeCurrentChainId(destinationChain); customDestinationChain[token] = destinationChain; emit CustomDestinationChainSet(token, destinationChain); } /** * @dev Sets a custom max slippage for a token * @param token Address of the token to set the custom max slippage for * @param maxSlippage Max slippage to be set */ function _setCustomMaxSlippage(address token, uint256 maxSlippage) internal { if (token == address(0)) revert TaskTokenZero(); if (maxSlippage > FixedPoint.ONE) revert TaskSlippageAboveOne(); customMaxSlippage[token] = maxSlippage; emit CustomMaxSlippageSet(token, maxSlippage); } /** * @dev Sets a custom max fee for a token * @param token Address of the token to set the custom max fee for * @param maxFeeToken Max fee token to be set for the given token * @param amount Max fee amount to be set for the given token */ function _setCustomMaxFee(address token, address maxFeeToken, uint256 amount) internal { if (token == address(0)) revert TaskTokenZero(); _setMaxFee(_customMaxFee[token], maxFeeToken, amount); emit CustomMaxFeeSet(token, maxFeeToken, amount); } /** * @dev Sets a max fee * @param maxFee Max fee to be updated * @param token Max fee token to be set * @param amount Max fee amount to be set */ function _setMaxFee(MaxFee storage maxFee, address token, uint256 amount) private { if (token == address(0) && amount != 0) revert TaskInvalidMaxFee(); maxFee.token = token; maxFee.amount = amount; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/connext/IConnextConnector.sol'; import './BaseBridgeTask.sol'; import '../interfaces/bridge/IConnextBridger.sol'; /** * @title Connext bridger * @dev Task that extends the base bridge task to use Connext */ contract ConnextBridger is IConnextBridger, BaseBridgeTask { using FixedPoint for uint256; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('CONNEXT_BRIDGER'); /** * @dev Connext bridge config. Only used in the initializer. */ struct ConnextBridgeConfig { BaseBridgeConfig baseBridgeConfig; } /** * @dev Initializes the Connext bridger * @param config Connext bridge config */ function initialize(ConnextBridgeConfig memory config) external virtual initializer { __ConnextBridger_init(config); } /** * @dev Initializes the Connext bridger. It does call upper contracts initializers. * @param config Connext bridge config */ function __ConnextBridger_init(ConnextBridgeConfig memory config) internal onlyInitializing { __BaseBridgeTask_init(config.baseBridgeConfig); __ConnextBridger_init_unchained(config); } /** * @dev Initializes the Connext bridger. It does not call upper contracts initializers. * @param config Connext bridge config */ function __ConnextBridger_init_unchained(ConnextBridgeConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Execute Connext bridger */ function call(address token, uint256 amount, uint256 slippage, uint256 fee) external override authP(authParams(token, amount, slippage, fee)) { if (amount == 0) amount = getTaskAmount(token); _beforeConnextBridger(token, amount, slippage, fee); uint256 amountAfterFees = amount - fee; uint256 minAmountOut = amountAfterFees.mulUp(FixedPoint.ONE - slippage); bytes memory connectorData = abi.encodeWithSelector( IConnextConnector.execute.selector, getDestinationChain(token), token, amount, minAmountOut, recipient, fee ); ISmartVault(smartVault).execute(connector, connectorData); _afterConnextBridger(token, amount, slippage, fee); } /** * @dev Before connext bridger hook */ function _beforeConnextBridger(address token, uint256 amount, uint256 slippage, uint256 fee) internal virtual { _beforeBaseBridgeTask(token, amount, slippage, fee); } /** * @dev After connext bridger hook */ function _afterConnextBridger(address token, uint256 amount, uint256 slippage, uint256 fee) internal virtual { _afterBaseBridgeTask(token, amount, slippage, fee); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/hop/IHopBridgeConnector.sol'; import './BaseBridgeTask.sol'; import '../interfaces/bridge/IHopBridger.sol'; /** * @title Hop bridger * @dev Task that extends the base bridge task to use Hop */ contract HopBridger is IHopBridger, BaseBridgeTask { using FixedPoint for uint256; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('HOP_BRIDGER'); // Relayer address address public override relayer; // Maximum deadline in seconds uint256 public override maxDeadline; // List of Hop entrypoints per token mapping (address => address) public override tokenHopEntrypoint; /** * @dev Token Hop entrypoint config. Only used in the initializer. */ struct TokenHopEntrypoint { address token; address entrypoint; } /** * @dev Hop bridge config. Only used in the initializer. */ struct HopBridgeConfig { address relayer; uint256 maxDeadline; TokenHopEntrypoint[] tokenHopEntrypoints; BaseBridgeConfig baseBridgeConfig; } /** * @dev Initializes the Hop bridger * @param config Hop bridge config */ function initialize(HopBridgeConfig memory config) external virtual initializer { __HopBridger_init(config); } /** * @dev Initializes the Hop bridger. It does call upper contracts initializers. * @param config Hop bridge config */ function __HopBridger_init(HopBridgeConfig memory config) internal onlyInitializing { __BaseBridgeTask_init(config.baseBridgeConfig); __HopBridger_init_unchained(config); } /** * @dev Initializes the Hop bridger. It does not call upper contracts initializers. * @param config Hop bridge config */ function __HopBridger_init_unchained(HopBridgeConfig memory config) internal onlyInitializing { _setRelayer(config.relayer); _setMaxDeadline(config.maxDeadline); for (uint256 i = 0; i < config.tokenHopEntrypoints.length; i++) { TokenHopEntrypoint memory customConfig = config.tokenHopEntrypoints[i]; _setTokenHopEntrypoint(customConfig.token, customConfig.entrypoint); } } /** * @dev Sets the relayer, only used when bridging from L1 to L2 * @param newRelayer New relayer address to be set */ function setRelayer(address newRelayer) external override authP(authParams(newRelayer)) { _setRelayer(newRelayer); } /** * @dev Sets the max deadline * @param newMaxDeadline New max deadline to be set */ function setMaxDeadline(uint256 newMaxDeadline) external override authP(authParams(newMaxDeadline)) { _setMaxDeadline(newMaxDeadline); } /** * @dev Sets an entrypoint for a tokens * @param token Token address to set a Hop entrypoint for * @param entrypoint Hop entrypoint address to be set for a token */ function setTokenHopEntrypoint(address token, address entrypoint) external override authP(authParams(token, entrypoint)) { _setTokenHopEntrypoint(token, entrypoint); } /** * @dev Execute Hop bridger */ function call(address token, uint256 amount, uint256 slippage, uint256 fee) external override authP(authParams(token, amount, slippage, fee)) { if (amount == 0) amount = getTaskAmount(token); _beforeHopBridger(token, amount, slippage, fee); uint256 amountAfterFees = amount - fee; uint256 minAmountOut = amountAfterFees.mulUp(FixedPoint.ONE - slippage); bytes memory connectorData = abi.encodeWithSelector( IHopBridgeConnector.execute.selector, getDestinationChain(token), token, amount, minAmountOut, recipient, tokenHopEntrypoint[token], block.timestamp + maxDeadline, relayer, fee ); ISmartVault(smartVault).execute(connector, connectorData); _afterHopBridger(token, amount, slippage, fee); } /** * @dev Before Hop bridger hook */ function _beforeHopBridger(address token, uint256 amount, uint256 slippage, uint256 fee) internal virtual { _beforeBaseBridgeTask(token, amount, slippage, fee); if (tokenHopEntrypoint[token] == address(0)) revert TaskMissingHopEntrypoint(); } /** * @dev After Hop bridger hook */ function _afterHopBridger(address token, uint256 amount, uint256 slippage, uint256 fee) internal virtual { _afterBaseBridgeTask(token, amount, slippage, fee); } /** * @dev Sets the relayer address, only used when bridging from L1 to L2 */ function _setRelayer(address _relayer) internal { relayer = _relayer; emit RelayerSet(_relayer); } /** * @dev Sets the max deadline */ function _setMaxDeadline(uint256 _maxDeadline) internal { if (_maxDeadline == 0) revert TaskMaxDeadlineZero(); maxDeadline = _maxDeadline; emit MaxDeadlineSet(_maxDeadline); } /** * @dev Set a Hop entrypoint for a token * @param token Address of the token to set a Hop entrypoint for * @param entrypoint Hop entrypoint to be set */ function _setTokenHopEntrypoint(address token, address entrypoint) internal { if (token == address(0)) revert TaskTokenZero(); tokenHopEntrypoint[token] = entrypoint; emit TokenHopEntrypointSet(token, entrypoint); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/wormhole/IWormholeConnector.sol'; import './BaseBridgeTask.sol'; import '../interfaces/bridge/IWormholeBridger.sol'; /** * @title Wormhole bridger * @dev Task that extends the bridger task to use Wormhole */ contract WormholeBridger is IWormholeBridger, BaseBridgeTask { using FixedPoint for uint256; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('WORMHOLE_BRIDGER'); /** * @dev Wormhole bridge config. Only used in the initializer. */ struct WormholeBridgeConfig { BaseBridgeConfig baseBridgeConfig; } /** * @dev Initializes the Wormhole bridger * @param config Wormhole bridge config */ function initialize(WormholeBridgeConfig memory config) external virtual initializer { __WormholeBridger_init(config); } /** * @dev Initializes the Wormhole bridger. It does call upper contracts initializers. * @param config Wormhole bridge config */ function __WormholeBridger_init(WormholeBridgeConfig memory config) internal onlyInitializing { __BaseBridgeTask_init(config.baseBridgeConfig); __WormholeBridger_init_unchained(config); } /** * @dev Initializes the Wormhole bridger. It does not call upper contracts initializers. * @param config Wormhole bridge config */ function __WormholeBridger_init_unchained(WormholeBridgeConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Execute Wormhole bridger */ function call(address token, uint256 amount, uint256 fee) external override authP(authParams(token, amount, fee)) { if (amount == 0) amount = getTaskAmount(token); _beforeWormholeBridger(token, amount, fee); uint256 minAmountOut = amount - fee; bytes memory connectorData = abi.encodeWithSelector( IWormholeConnector.execute.selector, getDestinationChain(token), token, amount, minAmountOut, recipient ); ISmartVault(smartVault).execute(connector, connectorData); _afterWormholeBridger(token, amount, fee); } /** * @dev Before Wormhole bridger hook */ function _beforeWormholeBridger(address token, uint256 amount, uint256 fee) internal virtual { // Wormhole does not support specifying slippage _beforeBaseBridgeTask(token, amount, 0, fee); } /** * @dev After Wormhole bridger hook */ function _afterWormholeBridger(address token, uint256 amount, uint256 fee) internal virtual { // Wormhole does not support specifying slippage _afterBaseBridgeTask(token, amount, 0, fee); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '@mimic-fi/v3-authorizer/contracts/interfaces/IAuthorized.sol'; /** * @dev Base task interface */ interface IBaseTask is IAuthorized { // Execution type serves for relayers in order to distinguish how each task must be executed // solhint-disable-next-line func-name-mixedcase function EXECUTION_TYPE() external view returns (bytes32); /** * @dev The balance connectors are the same */ error TaskSameBalanceConnectors(bytes32 connectorId); /** * @dev The smart vault's price oracle is not set */ error TaskSmartVaultPriceOracleNotSet(address smartVault); /** * @dev Emitted every time a task is executed */ event Executed(); /** * @dev Emitted every time the balance connectors are set */ event BalanceConnectorsSet(bytes32 indexed previous, bytes32 indexed next); /** * @dev Tells the address of the Smart Vault tied to it, it cannot be changed */ function smartVault() external view returns (address); /** * @dev Tells the address from where the token amounts to execute this task are fetched. * This address must be the Smart Vault in case the previous balance connector is set. */ function getTokensSource() external view returns (address); /** * @dev Tells the amount a task should use for a token * @param token Address of the token being queried */ function getTaskAmount(address token) external view returns (uint256); /** * @dev Tells the previous and next balance connectors id of the previous task in the workflow */ function getBalanceConnectors() external view returns (bytes32 previous, bytes32 next); /** * @dev Sets the balance connector IDs * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function setBalanceConnectors(bytes32 previous, bytes32 next) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseTask.sol'; /** * @dev Gas limited task interface */ interface IGasLimitedTask is IBaseTask { /** * @dev The tx initial gas cache has not been initialized */ error TaskGasNotInitialized(); /** * @dev The gas price used is greater than the limit */ error TaskGasPriceLimitExceeded(uint256 gasPrice, uint256 gasPriceLimit); /** * @dev The priority fee used is greater than the priority fee limit */ error TaskPriorityFeeLimitExceeded(uint256 priorityFee, uint256 priorityFeeLimit); /** * @dev The transaction cost is greater than the transaction cost limit */ error TaskTxCostLimitExceeded(uint256 txCost, uint256 txCostLimit); /** * @dev The transaction cost percentage is greater than the transaction cost limit percentage */ error TaskTxCostLimitPctExceeded(uint256 txCostPct, uint256 txCostLimitPct); /** * @dev The new transaction cost limit percentage is greater than one */ error TaskTxCostLimitPctAboveOne(); /** * @dev Emitted every time the gas limits are set */ event GasLimitsSet(uint256 gasPriceLimit, uint256 priorityFeeLimit, uint256 txCostLimit, uint256 txCostLimitPct); /** * @dev Tells the gas limits config */ function getGasLimits() external view returns (uint256 gasPriceLimit, uint256 priorityFeeLimit, uint256 txCostLimit, uint256 txCostLimitPct); /** * @dev Sets the gas limits config * @param newGasPriceLimit New gas price limit to be set * @param newPriorityFeeLimit New priority fee limit to be set * @param newTxCostLimit New tx cost limit to be set * @param newTxCostLimitPct New tx cost percentage limit to be set */ function setGasLimits( uint256 newGasPriceLimit, uint256 newPriorityFeeLimit, uint256 newTxCostLimit, uint256 newTxCostLimitPct ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseTask.sol'; /** * @dev Pausable task interface */ interface IPausableTask is IBaseTask { /** * @dev The task is paused */ error TaskPaused(); /** * @dev The task is unpaused */ error TaskUnpaused(); /** * @dev Emitted every time a task is paused */ event Paused(); /** * @dev Emitted every time a task is unpaused */ event Unpaused(); /** * @dev Tells the task is paused or not */ function isPaused() external view returns (bool); /** * @dev Pauses a task */ function pause() external; /** * @dev Unpauses a task */ function unpause() external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseTask.sol'; /** * @dev Time-locked task interface */ interface ITimeLockedTask is IBaseTask { /** * @dev The time lock frequency mode requested is invalid */ error TaskInvalidFrequencyMode(uint8 mode); /** * @dev The time lock frequency is not valid */ error TaskInvalidFrequency(uint8 mode, uint256 frequency); /** * @dev The time lock allowed date is not valid */ error TaskInvalidAllowedDate(uint8 mode, uint256 date); /** * @dev The time lock allowed window is not valid */ error TaskInvalidAllowedWindow(uint8 mode, uint256 window); /** * @dev The time lock is still active */ error TaskTimeLockActive(uint256 currentTimestamp, uint256 expiration); /** * @dev Emitted every time a new time lock is set */ event TimeLockSet(uint8 mode, uint256 frequency, uint256 allowedAt, uint256 window); /** * @dev Emitted every time a new expiration timestamp is set */ event TimeLockAllowedAtSet(uint256 allowedAt); /** * @dev Tells all the time-lock related information */ function getTimeLock() external view returns (uint8 mode, uint256 frequency, uint256 allowedAt, uint256 window); /** * @dev Sets the time-lock * @param mode Time lock mode * @param frequency Time lock frequency * @param allowedAt Future timestamp since when the task can be executed * @param window Period in seconds during when a time-locked task can be executed since the allowed timestamp */ function setTimeLock(uint8 mode, uint256 frequency, uint256 allowedAt, uint256 window) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseTask.sol'; /** * @dev Token indexed task interface */ interface ITokenIndexedTask is IBaseTask { /** * @dev Acceptance list types: either deny-list to express "all except" or allow-list to express "only" */ enum TokensAcceptanceType { DenyList, AllowList } /** * @dev The acceptance token is zero */ error TaskAcceptanceTokenZero(); /** * @dev The tokens acceptance input length mismatch */ error TaskAcceptanceInputLengthMismatch(); /** * @dev The token is not allowed */ error TaskTokenNotAllowed(address token); /** * @dev Emitted every time a tokens acceptance type is set */ event TokensAcceptanceTypeSet(TokensAcceptanceType acceptanceType); /** * @dev Emitted every time a token is added or removed from the acceptance list */ event TokensAcceptanceListSet(address indexed token, bool added); /** * @dev Tells the acceptance type of the config */ function tokensAcceptanceType() external view returns (TokensAcceptanceType); /** * @dev Tells whether a token is allowed or not * @param token Address of the token being queried */ function isTokenAllowed(address token) external view returns (bool); /** * @dev Sets the tokens acceptance type of the task * @param newTokensAcceptanceType New token acceptance type to be set */ function setTokensAcceptanceType(TokensAcceptanceType newTokensAcceptanceType) external; /** * @dev Updates the list of tokens of the tokens acceptance list * @param tokens List of tokens to be updated from the acceptance list * @param added Whether each of the given tokens should be added or removed from the list */ function setTokensAcceptanceList(address[] memory tokens, bool[] memory added) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General External License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General External License for more details. // You should have received a copy of the GNU General External License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseTask.sol'; /** * @dev Token threshold task interface */ interface ITokenThresholdTask is IBaseTask { /** * @dev The token threshold token is zero */ error TaskThresholdTokenZero(); /** * @dev The token threshold to be set is invalid */ error TaskInvalidThresholdInput(address token, uint256 min, uint256 max); /** * @dev The token threshold has not been met */ error TaskTokenThresholdNotMet(address token, uint256 amount, uint256 min, uint256 max); /** * @dev Emitted every time a default threshold is set */ event DefaultTokenThresholdSet(address token, uint256 min, uint256 max); /** * @dev Emitted every time a token threshold is set */ event CustomTokenThresholdSet(address indexed token, address thresholdToken, uint256 min, uint256 max); /** * @dev Tells the default token threshold */ function defaultTokenThreshold() external view returns (address thresholdToken, uint256 min, uint256 max); /** * @dev Tells the custom threshold defined for a specific token * @param token Address of the token being queried */ function customTokenThreshold(address token) external view returns (address thresholdToken, uint256 min, uint256 max); /** * @dev Tells the threshold that should be used for a token * @param token Address of the token being queried */ function getTokenThreshold(address token) external view returns (address thresholdToken, uint256 min, uint256 max); /** * @dev Sets a new default threshold config * @param thresholdToken New threshold token to be set * @param min New threshold minimum to be set * @param max New threshold maximum to be set */ function setDefaultTokenThreshold(address thresholdToken, uint256 min, uint256 max) external; /** * @dev Sets a custom token threshold * @param token Address of the token to set a custom threshold * @param thresholdToken New custom threshold token to be set * @param min New custom threshold minimum to be set * @param max New custom threshold maximum to be set */ function setCustomTokenThreshold(address token, address thresholdToken, uint256 min, uint256 max) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseTask.sol'; /** * @dev Volume limited task interface */ interface IVolumeLimitedTask is IBaseTask { /** * @dev The volume limit token is zero */ error TaskVolumeLimitTokenZero(); /** * @dev The volume limit to be set is invalid */ error TaskInvalidVolumeLimitInput(address token, uint256 amount, uint256 period); /** * @dev The volume limit has been exceeded */ error TaskVolumeLimitExceeded(address token, uint256 limit, uint256 volume); /** * @dev Emitted every time a default volume limit is set */ event DefaultVolumeLimitSet(address indexed limitToken, uint256 amount, uint256 period); /** * @dev Emitted every time a custom volume limit is set */ event CustomVolumeLimitSet(address indexed token, address indexed limitToken, uint256 amount, uint256 period); /** * @dev Tells the default volume limit set */ function defaultVolumeLimit() external view returns (address limitToken, uint256 amount, uint256 accrued, uint256 period, uint256 nextResetTime); /** * @dev Tells the custom volume limit set for a specific token * @param token Address of the token being queried */ function customVolumeLimit(address token) external view returns (address limitToken, uint256 amount, uint256 accrued, uint256 period, uint256 nextResetTime); /** * @dev Tells the volume limit that should be used for a token * @param token Address of the token being queried */ function getVolumeLimit(address token) external view returns (address limitToken, uint256 amount, uint256 accrued, uint256 period, uint256 nextResetTime); /** * @dev Sets a the default volume limit config * @param limitToken Address of the token to measure the volume limit * @param limitAmount Amount of tokens to be applied for the volume limit * @param limitPeriod Frequency to Amount of tokens to be applied for the volume limit */ function setDefaultVolumeLimit(address limitToken, uint256 limitAmount, uint256 limitPeriod) external; /** * @dev Sets a custom volume limit * @param token Address of the token to set a custom volume limit for * @param limitToken Address of the token to measure the volume limit * @param limitAmount Amount of tokens to be applied for the volume limit * @param limitPeriod Frequency to Amount of tokens to be applied for the volume limit */ function setCustomVolumeLimit(address token, address limitToken, uint256 limitAmount, uint256 limitPeriod) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseBridgeTask.sol'; /** * @dev Axelar bridger task interface */ interface IAxelarBridger is IBaseBridgeTask { /** * @dev Execute Axelar bridger task */ function call(address token, uint256 amountIn) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Base bridge task interface */ interface IBaseBridgeTask is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The recipient is zero */ error TaskRecipientZero(); /** * @dev The connector is zero */ error TaskConnectorZero(); /** * @dev The next balance connector is not zero */ error TaskNextConnectorNotZero(bytes32 id); /** * @dev The destination chain is not set */ error TaskDestinationChainNotSet(); /** * @dev The destination chain id is the same as the current chain id */ error TaskBridgeCurrentChainId(uint256 destinationChain); /** * @dev The slippage to be set is greater than one */ error TaskSlippageAboveOne(); /** * @dev The requested slippage is greater than the maximum slippage */ error TaskSlippageAboveMax(uint256 slippage, uint256 maxSlippage); /** * @dev The requested fee is greater than the maximum fee */ error TaskFeeAboveMax(uint256 fee, uint256 maxFee); /** * @dev The max fee token is zero but the max fee value is not zero */ error TaskInvalidMaxFee(); /** * @dev Emitted every time the connector is set */ event ConnectorSet(address indexed connector); /** * @dev Emitted every time the recipient is set */ event RecipientSet(address indexed recipient); /** * @dev Emitted every time the default destination chain is set */ event DefaultDestinationChainSet(uint256 indexed defaultDestinationChain); /** * @dev Emitted every time the default max slippage is set */ event DefaultMaxSlippageSet(uint256 maxSlippage); /** * @dev Emitted every time the default max fee is set */ event DefaultMaxFeeSet(address indexed maxFeeToken, uint256 amount); /** * @dev Emitted every time a custom destination chain is set for a token */ event CustomDestinationChainSet(address indexed token, uint256 indexed destinationChain); /** * @dev Emitted every time a custom max slippage is set */ event CustomMaxSlippageSet(address indexed token, uint256 maxSlippage); /** * @dev Emitted every time a custom max fee is set */ event CustomMaxFeeSet(address indexed token, address indexed maxFeeToken, uint256 amount); /** * @dev Tells the connector tied to the task */ function connector() external view returns (address); /** * @dev Tells the address of the allowed recipient */ function recipient() external view returns (address); /** * @dev Tells the default destination chain */ function defaultDestinationChain() external view returns (uint256); /** * @dev Tells the default max slippage */ function defaultMaxSlippage() external view returns (uint256); /** * @dev Tells the default max fee */ function defaultMaxFee() external view returns (address maxFeeToken, uint256 amount); /** * @dev Tells the destination chain defined for a specific token * @param token Address of the token being queried */ function customDestinationChain(address token) external view returns (uint256); /** * @dev Tells the max slippage defined for a specific token * @param token Address of the token being queried */ function customMaxSlippage(address token) external view returns (uint256); /** * @dev Tells the max fee defined for a specific token * @param token Address of the token being queried */ function customMaxFee(address token) external view returns (address maxFeeToken, uint256 amount); /** * @dev Tells the destination chain that should be used for a token * @param token Address of the token to get the destination chain for */ function getDestinationChain(address token) external view returns (uint256); /** * @dev Tells the max slippage that should be used for a token * @param token Address of the token to get the max slippage for */ function getMaxSlippage(address token) external view returns (uint256); /** * @dev Tells the max fee that should be used for a token * @param token Address of the token to get the max fee for */ function getMaxFee(address token) external view returns (address maxFeeToken, uint256 amount); /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function setConnector(address newConnector) external; /** * @dev Sets the recipient address * @param recipient Address of the new recipient to be set */ function setRecipient(address recipient) external; /** * @dev Sets the default destination chain * @param destinationChain Default destination chain to be set */ function setDefaultDestinationChain(uint256 destinationChain) external; /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function setDefaultMaxSlippage(uint256 maxSlippage) external; /** * @dev Sets the default max fee * @param maxFeeToken Default max fee token to be set * @param amount Default max fee amount to be set */ function setDefaultMaxFee(address maxFeeToken, uint256 amount) external; /** * @dev Sets a custom destination chain for a token * @param token Address of the token to set a custom destination chain for * @param destinationChain Destination chain to be set */ function setCustomDestinationChain(address token, uint256 destinationChain) external; /** * @dev Sets a custom max slippage * @param token Address of the token to set a custom max slippage for * @param maxSlippage Max slippage to be set */ function setCustomMaxSlippage(address token, uint256 maxSlippage) external; /** * @dev Sets a custom max fee * @param token Address of the token to set a custom max fee for * @param maxFeeToken Max fee token to be set for the given token * @param amount Max fee amount to be set for the given token */ function setCustomMaxFee(address token, address maxFeeToken, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseBridgeTask.sol'; /** * @dev Connext bridger task interface */ interface IConnextBridger is IBaseBridgeTask { /** * @dev Execute Connext bridger task */ function call(address token, uint256 amountIn, uint256 slippage, uint256 relayerFee) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseBridgeTask.sol'; /** * @dev Hop bridger task interface */ interface IHopBridger is IBaseBridgeTask { /** * @dev The max deadline is zero */ error TaskMaxDeadlineZero(); /** * @dev The Hop entrypoint is zero */ error TaskMissingHopEntrypoint(); /** * @dev Emitted every time the relayer is set */ event RelayerSet(address indexed relayer); /** * @dev Emitted every time the max deadline is set */ event MaxDeadlineSet(uint256 maxDeadline); /** * @dev Emitted every time a Hop entrypoint is set for a token */ event TokenHopEntrypointSet(address indexed token, address indexed entrypoint); /** * @dev Tells the relayer address, only used when bridging from L1 to L2 */ function relayer() external view returns (address); /** * @dev Tells the max deadline */ function maxDeadline() external view returns (uint256); /** * @dev Tells Hop entrypoint set for a token */ function tokenHopEntrypoint(address token) external view returns (address entrypoint); /** * @dev Sets the relayer, only used when bridging from L1 to L2 * @param relayer New relayer address to be set */ function setRelayer(address relayer) external; /** * @dev Sets the max deadline * @param maxDeadline New max deadline to be set */ function setMaxDeadline(uint256 maxDeadline) external; /** * @dev Sets an entrypoint for a tokens * @param token Token address to set a Hop entrypoint for * @param entrypoint Hop entrypoint address to be set for a token */ function setTokenHopEntrypoint(address token, address entrypoint) external; /** * @dev Execution function */ function call(address token, uint256 amountIn, uint256 slippage, uint256 fee) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseBridgeTask.sol'; /** * @dev Wormhole bridger task interface */ interface IWormholeBridger is IBaseBridgeTask { /** * @dev Execute Wormhole bridger task */ function call(address token, uint256 amountIn, uint256 fee) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './base/IBaseTask.sol'; import './base/IGasLimitedTask.sol'; import './base/ITimeLockedTask.sol'; import './base/ITokenIndexedTask.sol'; import './base/ITokenThresholdTask.sol'; import './base/IVolumeLimitedTask.sol'; // solhint-disable no-empty-blocks /** * @dev Task interface */ interface ITask is IBaseTask, IGasLimitedTask, ITimeLockedTask, ITokenIndexedTask, ITokenThresholdTask, IVolumeLimitedTask { }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import './IBalancerPool.sol'; interface IBalancerBoostedPool is IBalancerPool { function getRate() external view returns (uint256); function getBptIndex() external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import './IBalancerPool.sol'; interface IBalancerLinearPool is IBalancerPool { function getRate() external view returns (uint256); function getMainToken() external view returns (address); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IBalancerPool is IERC20 { function getPoolId() external view returns (bytes32); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../../ITask.sol'; /** * @dev Balancer V2 pool exit task interface */ interface IBalancerV2PoolExiter is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The connector is zero */ error TaskConnectorZero(); /** * @dev The slippage to be set is greater than one */ error TaskSlippageAboveOne(); /** * @dev The requested slippage is greater than the maximum slippage */ error TaskSlippageAboveMax(uint256 slippage, uint256 maxSlippage); /** * @dev Emitted every time the connector is set */ event ConnectorSet(address indexed connector); /** * @dev Emitted every time the default max slippage is set */ event DefaultMaxSlippageSet(uint256 maxSlippage); /** * @dev Emitted every time a custom max slippage is set */ event CustomMaxSlippageSet(address indexed token, uint256 maxSlippage); /** * @dev Tells the connector tied to the task */ function connector() external view returns (address); /** * @dev Tells the default token threshold */ function defaultMaxSlippage() external view returns (uint256); /** * @dev Tells the max slippage defined for a specific token * @param token Address of the token being queried */ function customMaxSlippage(address token) external view returns (uint256); /** * @dev Tells the max slippage that should be used for a token */ function getMaxSlippage(address token) external view returns (uint256); /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function setConnector(address newConnector) external; /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function setDefaultMaxSlippage(uint256 maxSlippage) external; /** * @dev Sets a custom max slippage * @param token Address of the token to set a custom max slippage for * @param maxSlippage Max slippage to be set */ function setCustomMaxSlippage(address token, uint256 maxSlippage) external; /** * @dev Execute Balancer v2 pool exiter * @param tokenIn Address of the Balancer pool token to exit * @param amountIn Amount of Balancer pool tokens to exit * @param slippage Slippage to be applied */ function call(address tokenIn, uint256 amountIn, uint256 slippage) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IBalancerVault { function getPool(bytes32 poolId) external view returns (address, uint256); function getPoolTokens(bytes32 poolId) external view returns (IERC20[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock); struct JoinPoolRequest { IERC20[] assets; uint256[] maxAmountsIn; bytes userData; bool fromInternalBalance; } function joinPool(bytes32 poolId, address sender, address recipient, JoinPoolRequest memory request) external payable; struct ExitPoolRequest { IERC20[] assets; uint256[] minAmountsOut; bytes userData; bool toInternalBalance; } function exitPool(bytes32 poolId, address sender, address payable recipient, ExitPoolRequest memory request) external; enum SwapKind { GIVEN_IN, GIVEN_OUT } struct SingleSwap { bytes32 poolId; SwapKind kind; address assetIn; address assetOut; uint256 amount; bytes userData; } struct FundManagement { address sender; bool fromInternalBalance; address payable recipient; bool toInternalBalance; } function swap(SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline) external payable returns (uint256); struct BatchSwapStep { bytes32 poolId; uint256 assetInIndex; uint256 assetOutIndex; uint256 amount; bytes userData; } function batchSwap( SwapKind kind, BatchSwapStep[] memory swaps, address[] memory assets, FundManagement memory funds, int256[] memory limits, uint256 deadline ) external payable returns (int256[] memory); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../../ITask.sol'; /** * @dev Base Convex task interface */ interface IBaseConvexTask is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The connector is zero */ error TaskConnectorZero(); /** * @dev Emitted every time the connector is set */ event ConnectorSet(address indexed connector); /** * @dev Tells the connector tied to the task */ function connector() external view returns (address); /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function setConnector(address newConnector) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseConvexTask.sol'; /** * @dev Convex claimer task interface */ interface IConvexClaimer is IBaseConvexTask { /** * @dev The amount is not zero */ error TaskAmountNotZero(); /** * @dev The previous balance connector is not zero */ error TaskPreviousConnectorNotZero(bytes32 id); /** * @dev The length of the claim result mismatch */ error TaskClaimResultLengthMismatch(); /** * @dev Executes the Convex claimer task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseConvexTask.sol'; /** * @dev Convex exiter task interface */ interface IConvexExiter is IBaseConvexTask { /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev Executes the Convex exiter task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseConvexTask.sol'; /** * @dev Convex joiner task interface */ interface IConvexJoiner is IBaseConvexTask { /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev Executes the Convex joiner task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../../ITask.sol'; /** * @dev Base Curve task interface */ interface IBaseCurveTask is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The connector is zero */ error TaskConnectorZero(); /** * @dev The token out is not set */ error TaskTokenOutNotSet(); /** * @dev The slippage to be set is greater than one */ error TaskSlippageAboveOne(); /** * @dev The requested slippage is greater than the maximum slippage */ error TaskSlippageAboveMax(uint256 slippage, uint256 maxSlippage); /** * @dev Emitted every time the connector is set */ event ConnectorSet(address indexed connector); /** * @dev Emitted every time the default token out is set */ event DefaultTokenOutSet(address indexed tokenOut); /** * @dev Emitted every time the default max slippage is set */ event DefaultMaxSlippageSet(uint256 maxSlippage); /** * @dev Emitted every time a custom token out is set */ event CustomTokenOutSet(address indexed token, address tokenOut); /** * @dev Emitted every time a custom max slippage is set */ event CustomMaxSlippageSet(address indexed token, uint256 maxSlippage); /** * @dev Tells the connector tied to the task */ function connector() external view returns (address); /** * @dev Tells the default token out */ function defaultTokenOut() external view returns (address); /** * @dev Tells the default token threshold */ function defaultMaxSlippage() external view returns (uint256); /** * @dev Tells the token out defined for a specific token * @param token Address of the token being queried */ function customTokenOut(address token) external view returns (address); /** * @dev Tells the max slippage defined for a specific token * @param token Address of the token being queried */ function customMaxSlippage(address token) external view returns (uint256); /** * @dev Tells the token out that should be used for a token */ function getTokenOut(address token) external view returns (address); /** * @dev Tells the max slippage that should be used for a token */ function getMaxSlippage(address token) external view returns (uint256); /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function setConnector(address newConnector) external; /** * @dev Sets the default token out * @param tokenOut Address of the default token out to be set */ function setDefaultTokenOut(address tokenOut) external; /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function setDefaultMaxSlippage(uint256 maxSlippage) external; /** * @dev Sets a custom token out * @param token Address of the token to set a custom token out for * @param tokenOut Address of the token out to be set */ function setCustomTokenOut(address token, address tokenOut) external; /** * @dev Sets a custom max slippage * @param token Address of the token to set a custom max slippage for * @param maxSlippage Max slippage to be set */ function setCustomMaxSlippage(address token, uint256 maxSlippage) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseCurveTask.sol'; /** * @dev Curve 2CRV exiter task interface */ interface ICurve2CrvExiter is IBaseCurveTask { /** * @dev Executes the Curve 2CRV exiter task */ function call(address token, uint256 amount, uint256 slippage) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseCurveTask.sol'; /** * @dev Curve 2CRV joiner task interface */ interface ICurve2CrvJoiner is IBaseCurveTask { /** * @dev Executes the Curve 2CRV joiner task */ function call(address token, uint256 amount, uint256 slippage) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../../ITask.sol'; /** * @dev Base ERC4626 task interface */ interface IBaseERC4626Task is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The connector is zero */ error TaskConnectorZero(); /** * @dev Emitted every time the connector is set */ event ConnectorSet(address indexed connector); /** * @dev Tells the connector tied to the task */ function connector() external view returns (address); /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function setConnector(address newConnector) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseERC4626Task.sol'; /** * @dev ERC4626 exiter task interface */ interface IERC4626Exiter is IBaseERC4626Task { /** * @dev Executes the ERC4626 exiter task */ function call(address erc4626, uint256 amount, uint256 minAmountOut) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseERC4626Task.sol'; /** * @dev ERC4626 joiner task interface */ interface IERC4626Joiner is IBaseERC4626Task { /** * The ERC4626 reference is zero */ error TaskERC4626Zero(); /** * @dev Executes the ERC4626 joiner task */ function call(address token, uint256 amount, address erc4626, uint256 minAmountOut) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Collector task interface */ interface ICollector is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The tokens source is zero */ error TaskTokensSourceZero(); /** * @dev The previous balance connector is not zero */ error TaskPreviousConnectorNotZero(bytes32 id); /** * @dev Emitted every time the tokens source is set */ event TokensSourceSet(address indexed tokensSource); /** * @dev Sets the tokens source address * @param tokensSource Address of the tokens source to be set */ function setTokensSource(address tokensSource) external; /** * @dev Executes the collector task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Depositor task interface */ interface IDepositor is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The msg value is zero */ error TaskValueZero(); /** * @dev The previous balance connector is not zero */ error TaskPreviousConnectorNotZero(bytes32 id); /** * @dev Executes the withdrawer task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Hand over task interface */ interface IHandleOver is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The tokens source is zero */ error TaskConnectorZero(bytes32 id); /** * @dev Executes the hand over task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Unwrapper task interface */ interface IUnwrapper is ITask { /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The token is not the wrapped native token */ error TaskTokenNotWrapped(); /** * @dev Executes the unwrapper task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Withdrawer task interface */ interface IWithdrawer is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The recipient is zero */ error TaskRecipientZero(); /** * @dev The recipient to be set is the smart vault */ error TaskRecipientEqualsSmartVault(address recipient); /** * @dev The next balance connector is not zero */ error TaskNextConnectorNotZero(bytes32 id); /** * @dev Emitted every time the recipient is set */ event RecipientSet(address indexed recipient); /** * @dev Tells the address of the allowed recipient */ function recipient() external view returns (address); /** * @dev Sets the recipient address * @param recipient Address of the new recipient to be set */ function setRecipient(address recipient) external; /** * @dev Executes the withdrawer task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Wrapper task interface */ interface IWrapper is ITask { /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The token is not the native token */ error TaskTokenNotNative(); /** * @dev Executes the wrapper task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Base relayer fund task interface */ interface IBaseRelayerFundTask is ITask { /** * @dev The relayer is zero */ error TaskRelayerZero(); /** * @dev The task initializer is disabled */ error TaskInitializerDisabled(); /** * @dev There is no threshold set for the given token */ error TaskTokenThresholdNotSet(address token); /** * @dev The deposited amount is above the minimum threshold */ error TaskDepositAboveMinThreshold(uint256 balance, uint256 min); /** * @dev The new amount to be deposited does not cover the used quota */ error TaskDepositBelowUsedQuota(uint256 amount, uint256 quota); /** * @dev The requested amount would result in a new balance below the minimum threshold */ error TaskNewDepositBelowMinThreshold(uint256 balance, uint256 min); /** * @dev The requested amount would result in a new balance above the maximum threshold */ error TaskNewDepositAboveMaxThreshold(uint256 balance, uint256 max); /** * @dev Emitted every time the relayer is set */ event RelayerSet(address indexed relayer); /** * @dev Tells the relayer */ function relayer() external view returns (address); /** * @dev Sets the relayer * @param newRelayer Address of the relayer to be set */ function setRelayer(address newRelayer) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Relayer depositor task interface */ interface IRelayerDepositor is ITask { /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The relayer is zero */ error TaskRelayerZero(); /** * @dev Emitted every time the relayer is set */ event RelayerSet(address indexed relayer); /** * @dev Tells the relayer */ function relayer() external view returns (address); /** * @dev Sets the relayer * @param newRelayer Address of the relayer to be set */ function setRelayer(address newRelayer) external; /** * @dev Executes the relayer depositor task */ function call(address token, uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseSwapTask.sol'; /** * @dev Balancer v2 BPT swapper task interface */ interface IBalancerV2BptSwapper is IBaseSwapTask { /** * @dev Execution function */ function call(address tokenIn, uint256 amountIn, uint256 slippage) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import '../ITask.sol'; /** * @dev Base swap task interface */ interface IBaseSwapTask is ITask { /** * @dev The token is zero */ error TaskTokenZero(); /** * @dev The amount is zero */ error TaskAmountZero(); /** * @dev The connector is zero */ error TaskConnectorZero(); /** * @dev The token out is not set */ error TaskTokenOutNotSet(); /** * @dev The slippage to be set is greater than one */ error TaskSlippageAboveOne(); /** * @dev The slippage is greater than the maximum slippage */ error TaskSlippageAboveMax(uint256 slippage, uint256 maxSlippage); /** * @dev Emitted every time the connector is set */ event ConnectorSet(address indexed connector); /** * @dev Emitted every time the default token out is set */ event DefaultTokenOutSet(address indexed tokenOut); /** * @dev Emitted every time the default max slippage is set */ event DefaultMaxSlippageSet(uint256 maxSlippage); /** * @dev Emitted every time a custom token out is set */ event CustomTokenOutSet(address indexed token, address tokenOut); /** * @dev Emitted every time a custom max slippage is set */ event CustomMaxSlippageSet(address indexed token, uint256 maxSlippage); /** * @dev Tells the connector tied to the task */ function connector() external view returns (address); /** * @dev Tells the default token out */ function defaultTokenOut() external view returns (address); /** * @dev Tells the default max slippage */ function defaultMaxSlippage() external view returns (uint256); /** * @dev Tells the token out defined for a specific token * @param token Address of the token being queried */ function customTokenOut(address token) external view returns (address); /** * @dev Tells the max slippage defined for a specific token * @param token Address of the token being queried */ function customMaxSlippage(address token) external view returns (uint256); /** * @dev Tells the token out that should be used for a token */ function getTokenOut(address token) external view returns (address); /** * @dev Tells the max slippage that should be used for a token */ function getMaxSlippage(address token) external view returns (uint256); /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function setConnector(address newConnector) external; /** * @dev Sets the default token out * @param tokenOut Address of the default token out to be set */ function setDefaultTokenOut(address tokenOut) external; /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function setDefaultMaxSlippage(uint256 maxSlippage) external; /** * @dev Sets a custom token out * @param token Address of the token to set a custom token out for * @param tokenOut Address of the token out to be set */ function setCustomTokenOut(address token, address tokenOut) external; /** * @dev Sets a custom max slippage * @param token Address of the token to set a custom max slippage for * @param maxSlippage Max slippage to be set */ function setCustomMaxSlippage(address token, uint256 maxSlippage) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseSwapTask.sol'; /** * @dev L2 Hop swapper task interface */ interface IHopL2Swapper is IBaseSwapTask { /** * @dev The amm for the token is not set */ error TaskMissingHopTokenAmm(); /** * @dev The hToken to be set is not the hToken of the Hop L2 amm to be used */ error TaskHopTokenAmmMismatch(address hToken, address amm); /** * @dev Emitted every time an AMM is set for a token */ event TokenAmmSet(address indexed token, address amm); /** * @dev Tells AMM set for a token */ function tokenAmm(address token) external view returns (address); /** * @dev Sets an AMM for a hToken * @param hToken Address of the hToken to be set * @param amm AMM address to be set for the hToken */ function setTokenAmm(address hToken, address amm) external; /** * @dev Executes the L2 hop swapper task */ function call(address tokenIn, uint256 amountIn, uint256 slippage) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseSwapTask.sol'; /** * @dev 1inch v5 swapper task interface */ interface IOneInchV5Swapper is IBaseSwapTask { /** * @dev Execution function */ function call(address tokenIn, uint256 amountIn, uint256 slippage, bytes memory data) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseSwapTask.sol'; /** * @dev Paraswap v5 swapper task interface */ interface IParaswapV5Swapper is IBaseSwapTask { /** * @dev The quote signer is zero */ error TaskQuoteSignerZero(); /** * @dev The signer to be set is not the quote signer */ error TaskInvalidQuoteSigner(address signer, address quoteSigner); /** * @dev The deadline is in the past */ error TaskQuoteSignerPastDeadline(uint256 deadline, uint256 currentTimestamp); /** * @dev Emitted every time a quote signer is set */ event QuoteSignerSet(address indexed quoteSigner); /** * @dev Tells the address of the allowed quote signer */ function quoteSigner() external view returns (address); /** * @dev Sets the quote signer address. Sender must be authorized. * @param newQuoteSigner Address of the new quote signer to be set */ function setQuoteSigner(address newQuoteSigner) external; /** * @dev Executes Paraswap V5 swapper task */ function call( address tokenIn, uint256 amountIn, uint256 minAmountOut, uint256 expectedAmountOut, uint256 deadline, bytes memory data, bytes memory sig ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseSwapTask.sol'; /** * @dev Uniswap v2 swapper task interface */ interface IUniswapV2Swapper is IBaseSwapTask { /** * @dev Execution function */ function call(address tokenIn, uint256 amountIn, uint256 slippage, address[] memory hopTokens) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; import './IBaseSwapTask.sol'; /** * @dev Uniswap v3 swapper task interface */ interface IUniswapV3Swapper is IBaseSwapTask { /** * @dev Execution function */ function call( address tokenIn, uint256 amountIn, uint256 slippage, uint24 fee, address[] memory hopTokens, uint24[] memory hopFees ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/balancer/IBalancerV2Vault.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/balancer/IBalancerV2PoolConnector.sol'; import '../../Task.sol'; import '../../interfaces/liquidity/balancer/IBalancerPool.sol'; import '../../interfaces/liquidity/balancer/IBalancerV2PoolExiter.sol'; /** * @title Balancer v2 pool exiter * @dev Task that offers the components to exit Balancer pools */ contract BalancerV2PoolExiter is IBalancerV2PoolExiter, Task { using FixedPoint for uint256; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('BALANCER_V2_POOL_EXITER'); // Task connector address address public override connector; // Default maximum slippage in fixed point uint256 public override defaultMaxSlippage; // Maximum slippage per token address mapping (address => uint256) public override customMaxSlippage; /** * @dev Custom max slippage config. Only used in the initializer. */ struct CustomMaxSlippage { address token; uint256 maxSlippage; } /** * @dev Balancer pool exit config. Only used in the initializer. */ struct BalancerPoolExitConfig { address connector; uint256 maxSlippage; CustomMaxSlippage[] customMaxSlippages; TaskConfig taskConfig; } /** * @dev Initializes a Balancer v2 pool exiter * @param config Balancer pool exit config */ function initialize(BalancerPoolExitConfig memory config) external virtual initializer { __BalancerV2PoolExiter_init(config); } /** * @dev Initializes the Balancer v2 pool exiter. It does call upper contracts initializers. * @param config Balancer pool exit config */ function __BalancerV2PoolExiter_init(BalancerPoolExitConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __BalancerV2PoolExiter_init_unchained(config); } /** * @dev Initializes the Balancer v2 pool exiter. It does not call upper contracts initializers. * @param config Balancer pool exit config */ function __BalancerV2PoolExiter_init_unchained(BalancerPoolExitConfig memory config) internal onlyInitializing { _setConnector(config.connector); _setDefaultMaxSlippage(config.maxSlippage); for (uint256 i = 0; i < config.customMaxSlippages.length; i++) { _setCustomMaxSlippage(config.customMaxSlippages[i].token, config.customMaxSlippages[i].maxSlippage); } } /** * @dev Tells the max slippage that should be used for a token */ function getMaxSlippage(address token) public view virtual override returns (uint256) { uint256 maxSlippage = customMaxSlippage[token]; return maxSlippage == 0 ? defaultMaxSlippage : maxSlippage; } /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function setConnector(address newConnector) external override authP(authParams(newConnector)) { _setConnector(newConnector); } /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function setDefaultMaxSlippage(uint256 maxSlippage) external override authP(authParams(maxSlippage)) { _setDefaultMaxSlippage(maxSlippage); } /** * @dev Sets a custom max slippage * @param token Address of the token to set a custom max slippage for * @param maxSlippage Max slippage to be set */ function setCustomMaxSlippage(address token, uint256 maxSlippage) external override authP(authParams(token, maxSlippage)) { _setCustomMaxSlippage(token, maxSlippage); } /** * @dev Execute Balancer v2 pool exiter * @param tokenIn Address of the Balancer pool token to exit * @param amountIn Amount of Balancer pool tokens to exit * @param slippage Slippage to be applied */ function call(address tokenIn, uint256 amountIn, uint256 slippage) external override authP(authParams(tokenIn, amountIn, slippage)) { if (amountIn == 0) amountIn = getTaskAmount(tokenIn); _beforeBalancerV2PoolExiter(tokenIn, amountIn, slippage); (address[] memory tokensOut, uint256[] memory minAmountsOut) = _getTokensOut(tokenIn, amountIn, slippage); bytes memory connectorData = abi.encodeWithSelector( IBalancerV2PoolConnector.exit.selector, tokenIn, amountIn, tokensOut, minAmountsOut ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); uint256[] memory amountsOut = abi.decode(result, (uint256[])); _afterBalancerV2PoolExiter(tokenIn, amountIn, tokensOut, amountsOut); } /** * @dev Tells the list of tokens and min amounts out based on a number of BPTs to exit * @param tokenIn Address of the pool being exited * @param amountIn Amount of tokens to exit the pool with * @param slippage Slippage to be used */ function _getTokensOut(address tokenIn, uint256 amountIn, uint256 slippage) internal view returns (address[] memory tokensOut, uint256[] memory minAmountsOut) { uint256 bptTotalSupply = IERC20(tokenIn).totalSupply(); uint256 bptRatio = amountIn.divDown(bptTotalSupply); bytes32 poolId = IBalancerPool(tokenIn).getPoolId(); address balancerV2Vault = IBalancerV2PoolConnector(connector).balancerV2Vault(); (IERC20[] memory tokens, uint256[] memory balances, ) = IBalancerV2Vault(balancerV2Vault).getPoolTokens(poolId); tokensOut = new address[](tokens.length); minAmountsOut = new uint256[](tokens.length); for (uint256 i = 0; i < tokens.length; i++) { tokensOut[i] = address(tokens[i]); uint256 expectedAmountsOut = balances[i].mulDown(bptRatio); minAmountsOut[i] = expectedAmountsOut.mulDown(FixedPoint.ONE - slippage); } } /** * @dev Before Balancer v2 pool exiter hook */ function _beforeBalancerV2PoolExiter(address tokenIn, uint256 amountIn, uint256 slippage) internal virtual { _beforeTask(tokenIn, amountIn); if (tokenIn == address(0)) revert TaskTokenZero(); if (amountIn == 0) revert TaskAmountZero(); uint256 maxSlippage = getMaxSlippage(tokenIn); if (slippage > maxSlippage) revert TaskSlippageAboveMax(slippage, maxSlippage); } /** * @dev After Balancer v2 pool exiter hook */ function _afterBalancerV2PoolExiter( address tokenIn, uint256 amountIn, address[] memory tokensOut, uint256[] memory amountsOut ) internal virtual { for (uint256 i = 0; i < tokensOut.length; i++) _increaseBalanceConnector(tokensOut[i], amountsOut[i]); _afterTask(tokenIn, amountIn); } /** * @dev Sets the task connector * @param newConnector New connector to be set */ function _setConnector(address newConnector) internal { if (newConnector == address(0)) revert TaskConnectorZero(); connector = newConnector; emit ConnectorSet(newConnector); } /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function _setDefaultMaxSlippage(uint256 maxSlippage) internal { if (maxSlippage > FixedPoint.ONE) revert TaskSlippageAboveOne(); defaultMaxSlippage = maxSlippage; emit DefaultMaxSlippageSet(maxSlippage); } /** * @dev Sets a custom max slippage for a token * @param token Address of the token to set the custom max slippage for * @param maxSlippage Max slippage to be set */ function _setCustomMaxSlippage(address token, uint256 maxSlippage) internal { if (token == address(0)) revert TaskTokenZero(); if (maxSlippage > FixedPoint.ONE) revert TaskSlippageAboveOne(); customMaxSlippage[token] = maxSlippage; emit CustomMaxSlippageSet(token, maxSlippage); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '../../Task.sol'; import '../../interfaces/liquidity/convex/IBaseConvexTask.sol'; /** * @title Base Convex task * @dev Task that offers the basic components for more detailed Convex related tasks */ abstract contract BaseConvexTask is IBaseConvexTask, Task { // Task connector address address public override connector; /** * @dev Base Convex config. Only used in the initializer. */ struct BaseConvexConfig { address connector; TaskConfig taskConfig; } /** * @dev Initializes the base Convex task. It does call upper contracts initializers. * @param config Base Convex config */ function __BaseConvexTask_init(BaseConvexConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __BaseConvexTask_init_unchained(config); } /** * @dev Initializes the base Convex task. It does not call upper contracts initializers. * @param config Base Convex config */ function __BaseConvexTask_init_unchained(BaseConvexConfig memory config) internal onlyInitializing { _setConnector(config.connector); } /** * @dev Sets the task connector * @param newConnector Address of the new connector to be set */ function setConnector(address newConnector) external override authP(authParams(newConnector)) { _setConnector(newConnector); } /** * @dev Before base Convex task hook */ function _beforeBaseConvexTask(address token, uint256 amount) internal virtual { _beforeTask(token, amount); if (token == address(0)) revert TaskTokenZero(); } /** * @dev After base Convex task hook */ function _afterBaseConvexTask(address token, uint256 amount) internal virtual { _afterTask(token, amount); } /** * @dev Sets the task connector * @param newConnector New connector to be set */ function _setConnector(address newConnector) internal { if (newConnector == address(0)) revert TaskConnectorZero(); connector = newConnector; emit ConnectorSet(newConnector); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-connectors/contracts/interfaces/convex/IConvexConnector.sol'; import './BaseConvexTask.sol'; import '../../interfaces/liquidity/convex/IConvexClaimer.sol'; /** * @title Convex claimer */ contract ConvexClaimer is IConvexClaimer, BaseConvexTask { // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('CONVEX_CLAIMER'); /** * @dev Convex claim config. Only used in the initializer. */ struct ConvexClaimConfig { BaseConvexConfig baseConvexConfig; } /** * @dev Initializes a Convex claimer * @param config Convex claim config */ function initialize(ConvexClaimConfig memory config) external virtual initializer { __ConvexClaimer_init(config); } /** * @dev Initializes the Convex claimer. It does call upper contracts initializers. * @param config Convex claim config */ function __ConvexClaimer_init(ConvexClaimConfig memory config) internal onlyInitializing { __BaseConvexTask_init(config.baseConvexConfig); __ConvexClaimer_init_unchained(config); } /** * @dev Initializes the Convex claimer. It does not call upper contracts initializers. * @param config Convex claim config */ function __ConvexClaimer_init_unchained(ConvexClaimConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Tells the address from where the token amounts to execute this task are fetched */ function getTokensSource() external view virtual override(IBaseTask, BaseTask) returns (address) { return IConvexConnector(connector).booster(); } /** * @dev Tells the amount a task should use for a token, in this case always zero since it is not possible to * compute on-chain how many tokens are available to be claimed. */ function getTaskAmount(address) public pure virtual override(IBaseTask, BaseTask) returns (uint256) { return 0; } /** * @dev Execute Convex claimer * @param token Address of the Convex pool token to claim rewards for * @param amount Must be zero, it is not possible to claim a specific number of tokens */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeConvexClaimer(token, amount); bytes memory connectorData = abi.encodeWithSelector(IConvexConnector.claim.selector, token); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); (address[] memory tokens, uint256[] memory amounts) = abi.decode(result, (address[], uint256[])); _afterConvexClaimer(token, amount, tokens, amounts); } /** * @dev Before Convex claimer hook */ function _beforeConvexClaimer(address token, uint256 amount) internal virtual { _beforeBaseConvexTask(token, amount); if (amount != 0) revert TaskAmountNotZero(); } /** * @dev After Convex claimer hook */ function _afterConvexClaimer( address tokenIn, uint256 amountIn, address[] memory tokensOut, uint256[] memory amountsOut ) internal virtual { if (tokensOut.length != amountsOut.length) revert TaskClaimResultLengthMismatch(); for (uint256 i = 0; i < tokensOut.length; i++) _increaseBalanceConnector(tokensOut[i], amountsOut[i]); _afterBaseConvexTask(tokenIn, amountIn); } /** * @dev Sets the balance connectors. Previous balance connector must be unset. * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function _setBalanceConnectors(bytes32 previous, bytes32 next) internal virtual override { if (previous != bytes32(0)) revert TaskPreviousConnectorNotZero(previous); super._setBalanceConnectors(previous, next); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/convex/IConvexConnector.sol'; import './BaseConvexTask.sol'; import '../../interfaces/liquidity/convex/IConvexExiter.sol'; /** * @title Convex exiter * @dev Task that extends the base Convex task to exit Convex pools */ contract ConvexExiter is IConvexExiter, BaseConvexTask { using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('CONVEX_EXITER'); /** * @dev Convex exit config. Only used in the initializer. */ struct ConvexExitConfig { BaseConvexConfig baseConvexConfig; } /** * @dev Initializes a Convex exiter * @param config Convex exit config */ function initialize(ConvexExitConfig memory config) external virtual initializer { __ConvexExiter_init(config); } /** * @dev Initializes the Convex exiter. It does call upper contracts initializers. * @param config Convex exit config */ function __ConvexExiter_init(ConvexExitConfig memory config) internal onlyInitializing { __BaseConvexTask_init(config.baseConvexConfig); __ConvexExiter_init_unchained(config); } /** * @dev Initializes the Convex exiter. It does not call upper contracts initializers. * @param config Convex exit config */ function __ConvexExiter_init_unchained(ConvexExitConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Executes the Convex exiter task * @param token Address of the Convex pool token to be exited with * @param amount Amount of Convex pool tokens to be exited with */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeConvexExiter(token, amount); bytes memory connectorData = abi.encodeWithSelector(IConvexConnector.exit.selector, token, amount); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterConvexExiter(token, amount, IConvexConnector(connector).getCurvePool(token), result.toUint256()); } /** * @dev Before Convex exiter hook */ function _beforeConvexExiter(address token, uint256 amount) internal virtual { _beforeBaseConvexTask(token, amount); if (amount == 0) revert TaskAmountZero(); } /** * @dev After Convex exiter hook */ function _afterConvexExiter(address tokenIn, uint256 amountIn, address tokenOut, uint256 amountOut) internal virtual { _increaseBalanceConnector(tokenOut, amountOut); _afterBaseConvexTask(tokenIn, amountIn); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/convex/IConvexConnector.sol'; import './BaseConvexTask.sol'; import '../../interfaces/liquidity/convex/IConvexJoiner.sol'; /** * @title Convex joiner * @dev Task that extends the base Convex task to join Convex pools */ contract ConvexJoiner is IConvexJoiner, BaseConvexTask { using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('CONVEX_JOINER'); /** * @dev Convex join config. Only used in the initializer. */ struct ConvexJoinConfig { BaseConvexConfig baseConvexConfig; } /** * @dev Initializes a Convex joiner * @param config Convex join config */ function initialize(ConvexJoinConfig memory config) external virtual initializer { __ConvexJoiner_init(config); } /** * @dev Initializes the Convex joiner. It does call upper contracts initializers. * @param config Convex join config */ function __ConvexJoiner_init(ConvexJoinConfig memory config) internal onlyInitializing { __BaseConvexTask_init(config.baseConvexConfig); __ConvexJoiner_init_unchained(config); } /** * @dev Initializes the Convex joiner. It does not call upper contracts initializers. * @param config Convex join config */ function __ConvexJoiner_init_unchained(ConvexJoinConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Executes the Convex joiner task * @param token Address of the Curve pool token to be joined with * @param amount Amount of Curve pool tokens to be joined with */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeConvexJoiner(token, amount); bytes memory connectorData = abi.encodeWithSelector(IConvexConnector.join.selector, token, amount); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterConvexJoiner(token, amount, IConvexConnector(connector).getCvxPool(token), result.toUint256()); } /** * @dev Before Convex joiner hook */ function _beforeConvexJoiner(address token, uint256 amount) internal virtual { _beforeBaseConvexTask(token, amount); if (amount == 0) revert TaskAmountZero(); } /** * @dev After Convex joiner hook */ function _afterConvexJoiner(address tokenIn, uint256 amountIn, address tokenOut, uint256 amountOut) internal virtual { _increaseBalanceConnector(tokenOut, amountOut); _afterBaseConvexTask(tokenIn, amountIn); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '../../Task.sol'; import '../../interfaces/liquidity/curve/IBaseCurveTask.sol'; /** * @title Base Curve task * @dev Task that offers the basic components for more detailed Curve related tasks */ abstract contract BaseCurveTask is IBaseCurveTask, Task { using FixedPoint for uint256; // Task connector address address public override connector; // Default token out address public override defaultTokenOut; // Default maximum slippage in fixed point uint256 public override defaultMaxSlippage; // Token out per token mapping (address => address) public override customTokenOut; // Maximum slippage per token address mapping (address => uint256) public override customMaxSlippage; /** * @dev Custom token out config. Only used in the initializer. */ struct CustomTokenOut { address token; address tokenOut; } /** * @dev Custom max slippage config. Only used in the initializer. */ struct CustomMaxSlippage { address token; uint256 maxSlippage; } /** * @dev Base Curve config. Only used in the initializer. */ struct BaseCurveConfig { address connector; address tokenOut; uint256 maxSlippage; CustomTokenOut[] customTokensOut; CustomMaxSlippage[] customMaxSlippages; TaskConfig taskConfig; } /** * @dev Initializes the base Curve task. It does call upper contracts initializers. * @param config Base Curve config */ function __BaseCurveTask_init(BaseCurveConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __BaseCurveTask_init_unchained(config); } /** * @dev Initializes the base Curve task. It does not call upper contracts initializers. * @param config Base Curve config */ function __BaseCurveTask_init_unchained(BaseCurveConfig memory config) internal onlyInitializing { _setConnector(config.connector); _setDefaultTokenOut(config.tokenOut); _setDefaultMaxSlippage(config.maxSlippage); for (uint256 i = 0; i < config.customTokensOut.length; i++) { _setCustomTokenOut(config.customTokensOut[i].token, config.customTokensOut[i].tokenOut); } for (uint256 i = 0; i < config.customMaxSlippages.length; i++) { _setCustomMaxSlippage(config.customMaxSlippages[i].token, config.customMaxSlippages[i].maxSlippage); } } /** * @dev Tells the token out that should be used for a token */ function getTokenOut(address token) public view virtual override returns (address) { address tokenOut = customTokenOut[token]; return tokenOut == address(0) ? defaultTokenOut : tokenOut; } /** * @dev Tells the max slippage that should be used for a token */ function getMaxSlippage(address token) public view virtual override returns (uint256) { uint256 maxSlippage = customMaxSlippage[token]; return maxSlippage == 0 ? defaultMaxSlippage : maxSlippage; } /** * @dev Sets the task connector * @param newConnector Address of the new connector to be set */ function setConnector(address newConnector) external override authP(authParams(newConnector)) { _setConnector(newConnector); } /** * @dev Sets the default token out * @param tokenOut Address of the default token out to be set */ function setDefaultTokenOut(address tokenOut) external override authP(authParams(tokenOut)) { _setDefaultTokenOut(tokenOut); } /** * @dev Sets the default max slippage */ function setDefaultMaxSlippage(uint256 maxSlippage) external override authP(authParams(maxSlippage)) { _setDefaultMaxSlippage(maxSlippage); } /** * @dev Sets a custom token out * @param token Address of the token to set a custom token out for * @param tokenOut Address of the token out to be set */ function setCustomTokenOut(address token, address tokenOut) external override authP(authParams(token, tokenOut)) { _setCustomTokenOut(token, tokenOut); } /** * @dev Sets a a custom max slippage * @param token Address of the token to set a max slippage for * @param maxSlippage Max slippage to be set for the given token */ function setCustomMaxSlippage(address token, uint256 maxSlippage) external override authP(authParams(token, maxSlippage)) { _setCustomMaxSlippage(token, maxSlippage); } /** * @dev Before base Curve task hook */ function _beforeBaseCurveTask(address token, uint256 amount, uint256 slippage) internal virtual { _beforeTask(token, amount); if (token == address(0)) revert TaskTokenZero(); if (amount == 0) revert TaskAmountZero(); if (getTokenOut(token) == address(0)) revert TaskTokenOutNotSet(); uint256 maxSlippage = getMaxSlippage(token); if (slippage > maxSlippage) revert TaskSlippageAboveMax(slippage, maxSlippage); } /** * @dev After base Curve task hook */ function _afterBaseCurveTask(address tokenIn, uint256 amountIn, uint256, address tokenOut, uint256 amountOut) internal virtual { _increaseBalanceConnector(tokenOut, amountOut); _afterTask(tokenIn, amountIn); } /** * @dev Sets the task connector * @param newConnector New connector to be set */ function _setConnector(address newConnector) internal { if (newConnector == address(0)) revert TaskConnectorZero(); connector = newConnector; emit ConnectorSet(newConnector); } /** * @dev Sets the default token out * @param tokenOut Default token out to be set */ function _setDefaultTokenOut(address tokenOut) internal { defaultTokenOut = tokenOut; emit DefaultTokenOutSet(tokenOut); } /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function _setDefaultMaxSlippage(uint256 maxSlippage) internal { if (maxSlippage > FixedPoint.ONE) revert TaskSlippageAboveOne(); defaultMaxSlippage = maxSlippage; emit DefaultMaxSlippageSet(maxSlippage); } /** * @dev Sets a custom token out for a token * @param token Address of the token to set the custom token out for * @param tokenOut Address of the token out to be set */ function _setCustomTokenOut(address token, address tokenOut) internal { if (token == address(0)) revert TaskTokenZero(); customTokenOut[token] = tokenOut; emit CustomTokenOutSet(token, tokenOut); } /** * @dev Sets a custom max slippage for a token * @param token Address of the token to set the custom max slippage for * @param maxSlippage Max slippage to be set */ function _setCustomMaxSlippage(address token, uint256 maxSlippage) internal { if (token == address(0)) revert TaskTokenZero(); if (maxSlippage > FixedPoint.ONE) revert TaskSlippageAboveOne(); customMaxSlippage[token] = maxSlippage; emit CustomMaxSlippageSet(token, maxSlippage); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/curve/ICurve2CrvConnector.sol'; import './BaseCurveTask.sol'; import '../../interfaces/liquidity/curve/ICurve2CrvExiter.sol'; /** * @title Curve 2CRV exiter * @dev Task that extends the base Curve task to exit 2CRV pools */ contract Curve2CrvExiter is ICurve2CrvExiter, BaseCurveTask { using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('CURVE_2CRV_EXITER'); /** * @dev Curve 2CRV exit config. Only used in the initializer. */ struct Curve2CrvExitConfig { BaseCurveConfig baseCurveConfig; } /** * @dev Initializes a Curve 2CRV exiter * @param config Curve 2CRV exit config */ function initialize(Curve2CrvExitConfig memory config) external virtual initializer { __Curve2CrvExiter_init(config); } /** * @dev Initializes the Curve 2CRV exiter. It does call upper contracts initializers. * @param config Curve 2CRV exit config */ function __Curve2CrvExiter_init(Curve2CrvExitConfig memory config) internal onlyInitializing { __BaseCurveTask_init(config.baseCurveConfig); __Curve2CrvExiter_init_unchained(config); } /** * @dev Initializes the Curve 2CRV exiter. It does not call upper contracts initializers. * @param config Curve 2CRV exit config */ function __Curve2CrvExiter_init_unchained(Curve2CrvExitConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Execute Curve 2CRV exiter * @param token Address of the Curve pool token to exit * @param amount Amount of Curve pool tokens to exit */ function call(address token, uint256 amount, uint256 slippage) external override authP(authParams(token, amount, slippage)) { if (amount == 0) amount = getTaskAmount(token); _beforeCurve2CrvExiter(token, amount, slippage); address tokenOut = getTokenOut(token); bytes memory connectorData = abi.encodeWithSelector( ICurve2CrvConnector.exit.selector, token, amount, tokenOut, slippage ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterCurve2CrvExiter(token, amount, slippage, tokenOut, result.toUint256()); } /** * @dev Before Curve 2CRV exiter hook */ function _beforeCurve2CrvExiter(address token, uint256 amount, uint256 slippage) internal virtual { _beforeBaseCurveTask(token, amount, slippage); } /** * @dev After Curve 2CRV exiter hook */ function _afterCurve2CrvExiter( address tokenIn, uint256 amountIn, uint256 slippage, address tokenOut, uint256 amountOut ) internal virtual { _afterBaseCurveTask(tokenIn, amountIn, slippage, tokenOut, amountOut); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/curve/ICurve2CrvConnector.sol'; import './BaseCurveTask.sol'; import '../../interfaces/liquidity/curve/ICurve2CrvJoiner.sol'; /** * @title Curve 2CRV joiner * @dev Task that extends the base Curve task to join 2CRV pools */ contract Curve2CrvJoiner is ICurve2CrvJoiner, BaseCurveTask { using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('CURVE_2CRV_JOINER'); /** * @dev Curve 2CRV join config. Only used in the initializer. */ struct Curve2CrvJoinConfig { BaseCurveConfig baseCurveConfig; } /** * @dev Initializes a Curve 2CRV joiner * @param config Curve 2CRV join config */ function initialize(Curve2CrvJoinConfig memory config) external virtual initializer { __Curve2CrvJoiner_init(config); } /** * @dev Initializes the Curve 2CRV joiner. It does call upper contracts initializers. * @param config Curve 2CRV join config */ function __Curve2CrvJoiner_init(Curve2CrvJoinConfig memory config) internal onlyInitializing { __BaseCurveTask_init(config.baseCurveConfig); __Curve2CrvJoiner_init_unchained(config); } /** * @dev Initializes the Curve 2CRV joiner. It does not call upper contracts initializers. * @param config Curve 2CRV join config */ function __Curve2CrvJoiner_init_unchained(Curve2CrvJoinConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Execute Curve 2CRV joiner * @param token Address of the token to join the Curve pool with * @param amount Amount of tokens to join the Curve pool with */ function call(address token, uint256 amount, uint256 slippage) external override authP(authParams(token, amount, slippage)) { if (amount == 0) amount = getTaskAmount(token); _beforeCurve2CrvJoiner(token, amount, slippage); address tokenOut = getTokenOut(token); bytes memory connectorData = abi.encodeWithSelector( ICurve2CrvConnector.join.selector, tokenOut, token, amount, slippage ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterCurve2CrvJoiner(token, amount, slippage, tokenOut, result.toUint256()); } /** * @dev Before Curve 2CRV joiner hook */ function _beforeCurve2CrvJoiner(address token, uint256 amount, uint256 slippage) internal virtual { _beforeBaseCurveTask(token, amount, slippage); } /** * @dev After Curve 2CRV joiner hook */ function _afterCurve2CrvJoiner( address tokenIn, uint256 amountIn, uint256 slippage, address tokenOut, uint256 amountOut ) internal virtual { _afterBaseCurveTask(tokenIn, amountIn, slippage, tokenOut, amountOut); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '../../Task.sol'; import '../../interfaces/liquidity/erc4626/IBaseERC4626Task.sol'; /** * @title Base ERC4626 task * @dev Task that offers the basic components for more detailed ERC4626 related tasks */ abstract contract BaseERC4626Task is IBaseERC4626Task, Task { // Task connector address address public override connector; /** * @dev Base ERC4626 config. Only used in the initializer. */ struct BaseERC4626Config { address connector; TaskConfig taskConfig; } /** * @dev Initializes the base ERC4626 task. It does call upper contracts initializers. * @param config Base ERC4626 config */ function __BaseERC4626Task_init(BaseERC4626Config memory config) internal onlyInitializing { __Task_init(config.taskConfig); __BaseERC4626Task_init_unchained(config); } /** * @dev Initializes the base ERC4626 task. It does not call upper contracts initializers. * @param config Base ERC4626 config */ function __BaseERC4626Task_init_unchained(BaseERC4626Config memory config) internal onlyInitializing { _setConnector(config.connector); } /** * @dev Sets the task connector * @param newConnector Address of the new connector to be set */ function setConnector(address newConnector) external override authP(authParams(newConnector)) { _setConnector(newConnector); } /** * @dev Before base ERC4626 task hook */ function _beforeBaseERC4626Task(address token, uint256 amount) internal virtual { _beforeTask(token, amount); if (token == address(0)) revert TaskTokenZero(); if (amount == 0) revert TaskAmountZero(); } /** * @dev After base ERC4626 task hook */ function _afterBaseERC4626Task(address tokenIn, uint256 amountIn, address tokenOut, uint256 amountOut) internal virtual { _increaseBalanceConnector(tokenOut, amountOut); _afterTask(tokenIn, amountIn); } /** * @dev Sets the task connector * @param newConnector New connector to be set */ function _setConnector(address newConnector) internal { if (newConnector == address(0)) revert TaskConnectorZero(); connector = newConnector; emit ConnectorSet(newConnector); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-connectors/contracts/interfaces/erc4626/IERC4626Connector.sol'; import './BaseERC4626Task.sol'; import '../../interfaces/liquidity/erc4626/IERC4626Exiter.sol'; /** * @title ERC4626 exiter * @dev Task that extends the base ERC4626 task to exit an ERC4626 vault */ contract ERC4626Exiter is IERC4626Exiter, BaseERC4626Task { // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('ERC4626_EXITER'); /** * @dev ERC4626 exit config. Only used in the initializer. */ struct ERC4626ExitConfig { BaseERC4626Config baseERC4626Config; } /** * @dev Initializes a ERC4626 exiter * @param config ERC4626 exit config */ function initialize(ERC4626ExitConfig memory config) external virtual initializer { __ERC4626Exiter_init(config); } /** * @dev Initializes the ERC4626 exiter. It does call upper contracts initializers. * @param config ERC4626 exit config */ function __ERC4626Exiter_init(ERC4626ExitConfig memory config) internal onlyInitializing { __BaseERC4626Task_init(config.baseERC4626Config); __ERC4626Exiter_init_unchained(config); } /** * @dev Initializes the ERC4626 exiter. It does not call upper contracts initializers. * @param config ERC4626 exit config */ function __ERC4626Exiter_init_unchained(ERC4626ExitConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Executes the ERC4626 exiter task. Note that the ERC4626 is also the token. * @param erc4626 Address of the ERC4626 to be exited * @param amount Amount of shares to be exited with * @param minAmountOut Minimum amount of assets willing to receive */ function call(address erc4626, uint256 amount, uint256 minAmountOut) external override authP(authParams(erc4626, amount, minAmountOut)) { if (amount == 0) amount = getTaskAmount(erc4626); _beforeERC4626Exiter(erc4626, amount); bytes memory connectorData = abi.encodeWithSelector( IERC4626Connector.exit.selector, erc4626, amount, minAmountOut ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); (address tokenOut, uint256 amountOut) = abi.decode(result, (address, uint256)); _afterERC4626Exiter(erc4626, amount, tokenOut, amountOut); } /** * @dev Before ERC4626 exiter hook */ function _beforeERC4626Exiter(address token, uint256 amount) internal virtual { _beforeBaseERC4626Task(token, amount); } /** * @dev After ERC4626 exiter hook */ function _afterERC4626Exiter(address tokenIn, uint256 amountIn, address tokenOut, uint256 amountOut) internal virtual { _afterBaseERC4626Task(tokenIn, amountIn, tokenOut, amountOut); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-connectors/contracts/interfaces/erc4626/IERC4626Connector.sol'; import './BaseERC4626Task.sol'; import '../../interfaces/liquidity/erc4626/IERC4626Joiner.sol'; /** * @title ERC4626 joiner * @dev Task that extends the base ERC4626 task to join an ERC4626 vault */ contract ERC4626Joiner is IERC4626Joiner, BaseERC4626Task { // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('ERC4626_JOINER'); /** * @dev ERC4626 join config. Only used in the initializer. */ struct ERC4626JoinConfig { BaseERC4626Config baseERC4626Config; } /** * @dev Initializes a ERC4626 joiner * @param config ERC4626 join config */ function initialize(ERC4626JoinConfig memory config) external virtual initializer { __ERC4626Joiner_init(config); } /** * @dev Initializes the ERC4626 joiner. It does call upper contracts initializers. * @param config ERC4626 join config */ function __ERC4626Joiner_init(ERC4626JoinConfig memory config) internal onlyInitializing { __BaseERC4626Task_init(config.baseERC4626Config); __ERC4626Joiner_init_unchained(config); } /** * @dev Initializes the ERC4626 joiner. It does not call upper contracts initializers. * @param config ERC4626 join config */ function __ERC4626Joiner_init_unchained(ERC4626JoinConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Executes the ERC4626 joiner task * @param token Address of the token to be joined with * @param amount Amount of assets to be joined with * @param erc4626 Address of the ERC4626 to be joined * @param minAmountOut Minimum amount of shares willing to receive */ function call(address token, uint256 amount, address erc4626, uint256 minAmountOut) external override authP(authParams(token, amount, erc4626, minAmountOut)) { if (amount == 0) amount = getTaskAmount(token); _beforeERC4626Joiner(token, amount, erc4626); bytes memory connectorData = abi.encodeWithSelector( IERC4626Connector.join.selector, erc4626, token, amount, minAmountOut ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); (address tokenOut, uint256 amountOut) = abi.decode(result, (address, uint256)); _afterERC4626Joiner(token, amount, tokenOut, amountOut); } /** * @dev Before ERC4626 joiner hook */ function _beforeERC4626Joiner(address token, uint256 amount, address erc4626) internal virtual { _beforeBaseERC4626Task(token, amount); if (erc4626 == address(0)) revert TaskERC4626Zero(); } /** * @dev After ERC4626 joiner hook */ function _afterERC4626Joiner(address tokenIn, uint256 amountIn, address tokenOut, uint256 amountOut) internal virtual { _afterBaseERC4626Task(tokenIn, amountIn, tokenOut, amountOut); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/utils/ERC20Helpers.sol'; import '../Task.sol'; import '../interfaces/primitives/ICollector.sol'; /** * @title Collector * @dev Task that offers a source address where funds can be pulled from */ contract Collector is ICollector, Task { // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('COLLECTOR'); // Address from where the tokens will be pulled address internal _tokensSource; /** * @dev Collect config. Only used in the initializer. */ struct CollectConfig { address tokensSource; TaskConfig taskConfig; } /** * @dev Initializes the collector * @param config Collect config */ function initialize(CollectConfig memory config) external virtual initializer { __Collector_init(config); } /** * @dev Initializes the collector. It does call upper contracts initializers. * @param config Collect config */ function __Collector_init(CollectConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __Collector_init_unchained(config); } /** * @dev Initializes the collector. It does not call upper contracts initializers. * @param config Collect config */ function __Collector_init_unchained(CollectConfig memory config) internal onlyInitializing { _setTokensSource(config.tokensSource); } /** * @dev Tells the address from where the token amounts to execute this task are fetched */ function getTokensSource() public view virtual override(IBaseTask, BaseTask) returns (address) { return _tokensSource; } /** * @dev Tells the balance of the depositor for a given token * @param token Address of the token being queried */ function getTaskAmount(address token) public view virtual override(IBaseTask, BaseTask) returns (uint256) { return ERC20Helpers.balanceOf(token, getTokensSource()); } /** * @dev Sets the tokens source address. Sender must be authorized. * @param tokensSource Address of the tokens source to be set */ function setTokensSource(address tokensSource) external override authP(authParams(tokensSource)) { _setTokensSource(tokensSource); } /** * @dev Execute Collector */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeCollector(token, amount); ISmartVault(smartVault).collect(token, _tokensSource, amount); _afterCollector(token, amount); } /** * @dev Before collector hook */ function _beforeCollector(address token, uint256 amount) internal virtual { _beforeTask(token, amount); if (token == address(0)) revert TaskTokenZero(); if (amount == 0) revert TaskAmountZero(); } /** * @dev After collector hook */ function _afterCollector(address token, uint256 amount) internal virtual { _increaseBalanceConnector(token, amount); _afterTask(token, amount); } /** * @dev Sets the balance connectors. Previous balance connector must be unset. * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function _setBalanceConnectors(bytes32 previous, bytes32 next) internal virtual override { if (previous != bytes32(0)) revert TaskPreviousConnectorNotZero(previous); super._setBalanceConnectors(previous, next); } /** * @dev Sets the source address * @param tokensSource Address of the tokens source to be set */ function _setTokensSource(address tokensSource) internal virtual { if (tokensSource == address(0)) revert TaskTokensSourceZero(); _tokensSource = tokensSource; emit TokensSourceSet(tokensSource); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/utils/ERC20Helpers.sol'; import '../Task.sol'; import '../interfaces/primitives/IHandleOver.sol'; /** * @title Hand over task * @dev Task that simply moves tokens from one balance connector to the other */ contract HandleOver is IHandleOver, Task { // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('HANDLE_OVER'); /** * @dev Hand over config. Only used in the initializer. */ struct HandleOverConfig { TaskConfig taskConfig; } /** * @dev Initializes the hand over task * @param config Hand over config */ function initialize(HandleOverConfig memory config) external virtual initializer { __HandleOver_init(config); } /** * @dev Initializes the hand over task. It does call upper contracts initializers. * @param config Hand over config */ function __HandleOver_init(HandleOverConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __HandleOver_init_unchained(config); } /** * @dev Initializes the hand over task. It does not call upper contracts initializers. * @param config Hand over config */ function __HandleOver_init_unchained(HandleOverConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Execute the hand over taks */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeHandleOver(token, amount); _afterHandleOver(token, amount); } /** * @dev Before hand over task hook */ function _beforeHandleOver(address token, uint256 amount) internal virtual { _beforeTask(token, amount); if (token == address(0)) revert TaskTokenZero(); if (amount == 0) revert TaskAmountZero(); } /** * @dev After hand over task hook */ function _afterHandleOver(address token, uint256 amount) internal virtual { _increaseBalanceConnector(token, amount); _afterTask(token, amount); } /** * @dev Sets the balance connectors. Both balance connector must be set. * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function _setBalanceConnectors(bytes32 previous, bytes32 next) internal virtual override { if (previous == bytes32(0)) revert TaskConnectorZero(previous); if (next == bytes32(0)) revert TaskConnectorZero(next); super._setBalanceConnectors(previous, next); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '../Task.sol'; import '../interfaces/primitives/IUnwrapper.sol'; /** * @title Unwrapper * @dev Task that offers facilities to unwrap wrapped native tokens */ contract Unwrapper is IUnwrapper, Task { // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('UNWRAPPER'); /** * @dev Unwrap config. Only used in the initializer. * @param taskConfig Task config params */ struct UnwrapConfig { TaskConfig taskConfig; } /** * @dev Initializes the unwrapper * @param config Unwrap config */ function initialize(UnwrapConfig memory config) external virtual initializer { __Unwrapper_init(config); } /** * @dev Initializes the unwrapper. It does call upper contracts initializers. * @param config Unwrap config */ function __Unwrapper_init(UnwrapConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __Unwrapper_init_unchained(config); } /** * @dev Initializes the unwrapper. It does not call upper contracts initializers. * @param config Unwrap config */ function __Unwrapper_init_unchained(UnwrapConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Execute Unwrapper */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeUnwrapper(token, amount); ISmartVault(smartVault).unwrap(amount); _afterUnwrapper(token, amount); } /** * @dev Before unwrapper hook */ function _beforeUnwrapper(address token, uint256 amount) internal virtual { _beforeTask(token, amount); if (token != _wrappedNativeToken()) revert TaskTokenNotWrapped(); if (amount == 0) revert TaskAmountZero(); } /** * @dev After unwrapper hook */ function _afterUnwrapper(address token, uint256 amount) internal virtual { _increaseBalanceConnector(Denominations.NATIVE_TOKEN, amount); _afterTask(token, amount); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '../Task.sol'; import '../interfaces/primitives/IWithdrawer.sol'; /** * @title Withdrawer * @dev Task that offers a recipient address where funds can be withdrawn */ contract Withdrawer is IWithdrawer, Task { // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('WITHDRAWER'); // Address where tokens will be transferred to address public override recipient; /** * @dev Withdraw config. Only used in the initializer. */ struct WithdrawConfig { address recipient; TaskConfig taskConfig; } /** * @dev Initializes the withdrawer * @param config Withdraw config */ function initialize(WithdrawConfig memory config) external virtual initializer { __Withdrawer_init(config); } /** * @dev Initializes the withdrawer. It does call upper contracts initializers. * @param config Withdraw config */ function __Withdrawer_init(WithdrawConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __Withdrawer_init_unchained(config); } /** * @dev Initializes the withdrawer. It does not call upper contracts initializers. * @param config Withdraw config */ function __Withdrawer_init_unchained(WithdrawConfig memory config) internal onlyInitializing { _setRecipient(config.recipient); } /** * @dev Sets the recipient address. Sender must be authorized. * @param newRecipient Address of the new recipient to be set */ function setRecipient(address newRecipient) external override authP(authParams(newRecipient)) { _setRecipient(newRecipient); } /** * @dev Executes the Withdrawer */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeWithdrawer(token, amount); ISmartVault(smartVault).withdraw(token, recipient, amount); _afterWithdrawer(token, amount); } /** * @dev Before withdrawer hook */ function _beforeWithdrawer(address token, uint256 amount) internal virtual { _beforeTask(token, amount); if (token == address(0)) revert TaskTokenZero(); if (amount == 0) revert TaskAmountZero(); } /** * @dev After withdrawer hook */ function _afterWithdrawer(address token, uint256 amount) internal virtual { _afterTask(token, amount); } /** * @dev Sets the recipient address * @param newRecipient Address of the new recipient to be set */ function _setRecipient(address newRecipient) internal { if (newRecipient == address(0)) revert TaskRecipientZero(); if (newRecipient == smartVault) revert TaskRecipientEqualsSmartVault(newRecipient); recipient = newRecipient; emit RecipientSet(newRecipient); } /** * @dev Sets the balance connectors. Next balance connector must be unset. * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function _setBalanceConnectors(bytes32 previous, bytes32 next) internal virtual override { if (next != bytes32(0)) revert TaskNextConnectorNotZero(next); super._setBalanceConnectors(previous, next); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/utils/Denominations.sol'; import '../Task.sol'; import '../interfaces/primitives/IWrapper.sol'; /** * @title Wrapper * @dev Task that offers facilities to wrap native tokens */ contract Wrapper is IWrapper, Task { // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('WRAPPER'); /** * @dev Wrap config. Only used in the initializer. */ struct WrapConfig { TaskConfig taskConfig; } /** * @dev Initializes the wrapper * @param config Wrap config */ function initialize(WrapConfig memory config) external virtual initializer { __Wrapper_init(config); } /** * @dev Initializes the wrapper. It does call upper contracts initializers. * @param config Wrap config */ function __Wrapper_init(WrapConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __Wrapper_init_unchained(config); } /** * @dev Initializes the wrapper. It does not call upper contracts initializers. * @param config Wrap config */ function __Wrapper_init_unchained(WrapConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Execute Wrapper */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeWrapper(token, amount); ISmartVault(smartVault).wrap(amount); _afterWrapper(token, amount); } /** * @dev Before wrapper hook */ function _beforeWrapper(address token, uint256 amount) internal virtual { _beforeTask(token, amount); if (token != Denominations.NATIVE_TOKEN) revert TaskTokenNotNative(); if (amount == 0) revert TaskAmountZero(); } /** * @dev After wrapper hook */ function _afterWrapper(address token, uint256 amount) internal virtual { _increaseBalanceConnector(_wrappedNativeToken(), amount); _afterTask(token, amount); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-relayer/contracts/interfaces/IRelayer.sol'; import '../Task.sol'; import '../interfaces/relayer/IBaseRelayerFundTask.sol'; /** * @title Base relayer fund task * @dev Task that offers the basic components for more detailed relayer fund tasks */ abstract contract BaseRelayerFundTask is IBaseRelayerFundTask, Task { using FixedPoint for uint256; // Reference to the contract to be funded address public override relayer; /** * @dev Base relayer fund config. Only used in the initializer. */ struct BaseRelayerFundConfig { address relayer; TaskConfig taskConfig; } /** * @dev Initializes the base relayer fund task. It does call upper contracts initializers. * @param config Base relayer fund config */ function __BaseRelayerFundTask_init(BaseRelayerFundConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __BaseRelayerFundTask_init_unchained(config); } /** * @dev Initializes the base relayer fund task. It does not call upper contracts initializers. * @param config Base relayer fund config */ function __BaseRelayerFundTask_init_unchained(BaseRelayerFundConfig memory config) internal onlyInitializing { _setRelayer(config.relayer); } /** * @dev Tells the amount in `token` to be paid to the relayer * @param token Address of the token to be used to pay the relayer */ function getTaskAmount(address token) public view virtual override(IBaseTask, BaseTask) returns (uint256) { Threshold memory threshold = _getTokenThreshold(token); if (threshold.token == address(0)) return 0; uint256 depositedThresholdToken = _getDepositedInThresholdToken(threshold.token); if (depositedThresholdToken >= threshold.min) return 0; uint256 usedQuotaThresholdToken = _getUsedQuotaInThresholdToken(threshold.token); uint256 diff = threshold.max - depositedThresholdToken + usedQuotaThresholdToken; return (token == threshold.token) ? diff : diff.mulUp(_getPrice(threshold.token, token)); } /** * @dev Sets the relayer * @param newRelayer Address of the relayer to be set */ function setRelayer(address newRelayer) external override authP(authParams(newRelayer)) { _setRelayer(newRelayer); } /** * @dev Before token threshold task hook */ function _beforeTokenThresholdTask(address token, uint256 amount) internal virtual override { Threshold memory threshold = _getTokenThreshold(token); if (threshold.token == address(0)) revert TaskTokenThresholdNotSet(token); uint256 amountInThresholdToken = amount.mulUp(_getPrice(token, threshold.token)); uint256 depositedInThresholdToken = _getDepositedInThresholdToken(threshold.token); bool isCurrentBalanceAboveMin = depositedInThresholdToken >= threshold.min; if (isCurrentBalanceAboveMin) revert TaskDepositAboveMinThreshold(depositedInThresholdToken, threshold.min); uint256 usedQuotaInThresholdToken = _getUsedQuotaInThresholdToken(threshold.token); bool coversUsedQuota = amountInThresholdToken > usedQuotaInThresholdToken; if (!coversUsedQuota) revert TaskDepositBelowUsedQuota(amountInThresholdToken, usedQuotaInThresholdToken); uint256 balanceAfterDeposit = amountInThresholdToken + depositedInThresholdToken - usedQuotaInThresholdToken; bool isNewBalanceBelowMin = balanceAfterDeposit < threshold.min; if (isNewBalanceBelowMin) revert TaskNewDepositBelowMinThreshold(balanceAfterDeposit, threshold.min); bool isNewBalanceAboveMax = balanceAfterDeposit > threshold.max; if (isNewBalanceAboveMax) revert TaskNewDepositAboveMaxThreshold(balanceAfterDeposit, threshold.max); } /** * @dev Tells the deposited balance in the relayer expressed in another token */ function _getDepositedInThresholdToken(address token) internal view returns (uint256) { // Relayer balance is expressed in ETH uint256 depositedNativeToken = IRelayer(relayer).getSmartVaultBalance(smartVault); return depositedNativeToken.mulUp(_getPrice(_wrappedNativeToken(), token)); } /** * @dev Tells the used quota in the relayer expressed in another token */ function _getUsedQuotaInThresholdToken(address token) internal view returns (uint256) { // Relayer used quota is expressed in ETH uint256 usedQuotaNativeToken = IRelayer(relayer).getSmartVaultUsedQuota(smartVault); return usedQuotaNativeToken.mulUp(_getPrice(_wrappedNativeToken(), token)); } /** * @dev Sets the relayer * @param newRelayer Address of the relayer to be set */ function _setRelayer(address newRelayer) internal { if (newRelayer == address(0)) revert TaskRelayerZero(); relayer = newRelayer; emit RelayerSet(newRelayer); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '../primitives/Collector.sol'; import './BaseRelayerFundTask.sol'; /** * @title Collector relayer funder * @dev Task used to convert funds in order to pay relayers using an collector */ contract CollectorRelayerFunder is BaseRelayerFundTask, Collector { /** * @dev Disables the default collector initializer */ function initialize(CollectConfig memory) external pure override { revert TaskInitializerDisabled(); } /** * @dev Initializes the collector relayer funder * @param config Collect config * @param relayer Relayer address */ function initializeCollectorRelayerFunder(CollectConfig memory config, address relayer) external virtual initializer { __CollectorRelayerFunder_init(config, relayer); } /** * @dev Initializes the collector relayer funder. It does call upper contracts initializers. * @param config Collect config * @param relayer Relayer address */ function __CollectorRelayerFunder_init(CollectConfig memory config, address relayer) internal onlyInitializing { __Collector_init(config); __BaseRelayerFundTask_init_unchained(BaseRelayerFundConfig(relayer, config.taskConfig)); __CollectorRelayerFunder_init_unchained(config, relayer); } /** * @dev Initializes the collector relayer funder. It does not call upper contracts initializers. * @param config Collect config * @param relayer Relayer address */ function __CollectorRelayerFunder_init_unchained(CollectConfig memory config, address relayer) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Tells the address from where the token amounts to execute this task are fetched */ function getTokensSource() public view override(Collector, IBaseTask, BaseTask) returns (address) { return Collector.getTokensSource(); } /** * @dev Tells the `token` amount to be funded * @param token Address of the token to be used to fund the relayer */ function getTaskAmount(address token) public view override(BaseRelayerFundTask, Collector) returns (uint256) { return BaseRelayerFundTask.getTaskAmount(token); } /** * @dev Before token threshold task hook */ function _beforeTokenThresholdTask(address token, uint256 amount) internal override(BaseRelayerFundTask, TokenThresholdTask) { BaseRelayerFundTask._beforeTokenThresholdTask(token, amount); } /** * @dev Sets the balance connectors. Previous balance connector must be unset. * @param previous Balance connector id of the previous task in the workflow * @param next Balance connector id of the next task in the workflow */ function _setBalanceConnectors(bytes32 previous, bytes32 next) internal override(Collector, BaseTask) { Collector._setBalanceConnectors(previous, next); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import './BaseRelayerFundTask.sol'; import '../swap/OneInchV5Swapper.sol'; /** * @title 1inch v5 relayer funder * @dev Task used to convert funds in order to pay relayers using a 1inch v5 swapper */ contract OneInchV5RelayerFunder is BaseRelayerFundTask, OneInchV5Swapper { /** * @dev Disables the default 1inch v5 swapper initializer */ function initialize(OneInchV5SwapConfig memory) external pure override { revert TaskInitializerDisabled(); } /** * @dev Initializes the 1inch v5 relayer funder * @param config 1inch v5 swap config * @param relayer Relayer address */ function initializeOneInchV5RelayerFunder(OneInchV5SwapConfig memory config, address relayer) external virtual initializer { __OneInchV5RelayerFunder_init(config, relayer); } /** * @dev Initializes the 1inch v5 relayer funder. It does call upper contracts initializers. * @param config 1inch v5 swap config * @param relayer Relayer address */ function __OneInchV5RelayerFunder_init(OneInchV5SwapConfig memory config, address relayer) internal onlyInitializing { __OneInchV5Swapper_init(config); __BaseRelayerFundTask_init_unchained(BaseRelayerFundConfig(relayer, config.baseSwapConfig.taskConfig)); __OneInchV5RelayerFunder_init_unchained(config, relayer); } /** * @dev Initializes the 1inch v5 relayer funder. It does not call upper contracts initializers. * @param config Unwrap config * @param relayer Relayer address */ function __OneInchV5RelayerFunder_init_unchained(OneInchV5SwapConfig memory config, address relayer) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Tells the amount in `token` to be funded * @param token Address of the token to be used for funding */ function getTaskAmount(address token) public view override(BaseRelayerFundTask, IBaseTask, BaseTask) returns (uint256) { return BaseRelayerFundTask.getTaskAmount(token); } /** * @dev Before token threshold task hook */ function _beforeTokenThresholdTask(address token, uint256 amount) internal override(BaseRelayerFundTask, TokenThresholdTask) { BaseRelayerFundTask._beforeTokenThresholdTask(token, amount); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-relayer/contracts/interfaces/IRelayer.sol'; import '../Task.sol'; import '../interfaces/relayer/IRelayerDepositor.sol'; /** * @title Relayer depositor * @dev Task that offers facilities to deposit balance for Mimic relayers */ contract RelayerDepositor is IRelayerDepositor, Task { using FixedPoint for uint256; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('RELAYER_DEPOSITOR'); // Reference to the contract to be funded address public override relayer; /** * @dev Initializes the relayer depositor * @param config Task config * @param _relayer Relayer address */ function initialize(TaskConfig memory config, address _relayer) external virtual initializer { __RelayerDepositor_init(config, _relayer); } /** * @dev Initializes the relayer depositor. It does call upper contracts initializers. * @param config Task config * @param _relayer Relayer address */ function __RelayerDepositor_init(TaskConfig memory config, address _relayer) internal onlyInitializing { __Task_init(config); __RelayerDepositor_init_unchained(config, _relayer); } /** * @dev Initializes the relayer depositor. It does not call upper contracts initializers. * @param _relayer Relayer address */ function __RelayerDepositor_init_unchained(TaskConfig memory, address _relayer) internal onlyInitializing { _setRelayer(_relayer); } /** * @dev Sets the relayer * @param newRelayer Address of the relayer to be set */ function setRelayer(address newRelayer) external override authP(authParams(newRelayer)) { _setRelayer(newRelayer); } /** * @dev Executes the relayer depositor task */ function call(address token, uint256 amount) external override authP(authParams(token, amount)) { if (amount == 0) amount = getTaskAmount(token); _beforeRelayerDepositor(token, amount); bytes memory relayerData = abi.encodeWithSelector(IRelayer.deposit.selector, smartVault, amount); // solhint-disable-next-line avoid-low-level-calls ISmartVault(smartVault).call(relayer, relayerData, amount); _afterRelayerDepositor(token, amount); } /** * @dev Before relayer depositor hook */ function _beforeRelayerDepositor(address token, uint256 amount) internal virtual { _beforeTask(token, amount); if (amount == 0) revert TaskAmountZero(); } /** * @dev After relayer depositor hook */ function _afterRelayerDepositor(address token, uint256 amount) internal virtual { _afterTask(token, amount); } /** * @dev Sets the relayer * @param newRelayer Address of the relayer to be set */ function _setRelayer(address newRelayer) internal { if (newRelayer == address(0)) revert TaskRelayerZero(); relayer = newRelayer; emit RelayerSet(newRelayer); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import './BaseRelayerFundTask.sol'; import '../primitives/Unwrapper.sol'; /** * @title Unwrapper relayer funder * @dev Task used to convert funds in order to pay relayers using an unwrapper */ contract UnwrapperRelayerFunder is BaseRelayerFundTask, Unwrapper { /** * @dev Disables the default unwrapper initializer */ function initialize(UnwrapConfig memory) external pure override { revert TaskInitializerDisabled(); } /** * @dev Initializes the unwrapper relayer funder * @param config Unwrap config * @param relayer Relayer address */ function initializeUnwrapperRelayerFunder(UnwrapConfig memory config, address relayer) external virtual initializer { __UnwrapperRelayerFunder_init(config, relayer); } /** * @dev Initializes the unwrapper relayer funder. It does call upper contracts initializers. * @param config Unwrap config * @param relayer Relayer address */ function __UnwrapperRelayerFunder_init(UnwrapConfig memory config, address relayer) internal onlyInitializing { __Unwrapper_init(config); __BaseRelayerFundTask_init_unchained(BaseRelayerFundConfig(relayer, config.taskConfig)); __UnwrapperRelayerFunder_init_unchained(config, relayer); } /** * @dev Initializes the unwrapper relayer funder. It does not call upper contracts initializers. * @param config Unwrap config * @param relayer Relayer address */ function __UnwrapperRelayerFunder_init_unchained(UnwrapConfig memory config, address relayer) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Tells the `token` amount to be funded * @param token Address of the token to be used to fund the relayer */ function getTaskAmount(address token) public view override(BaseRelayerFundTask, IBaseTask, BaseTask) returns (uint256) { return BaseRelayerFundTask.getTaskAmount(token); } /** * @dev Before token threshold task hook */ function _beforeTokenThresholdTask(address token, uint256 amount) internal override(BaseRelayerFundTask, TokenThresholdTask) { BaseRelayerFundTask._beforeTokenThresholdTask(token, amount); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/balancer/IBalancerV2Vault.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/balancer/IBalancerV2SwapConnector.sol'; import './BalancerV2BptSwapper.sol'; import '../interfaces/liquidity/balancer/IBalancerBoostedPool.sol'; /** * @title Balancer v2 boosted swapper task * @dev Task that extends the Balancer v2 BPT swapper task specially for boosted pools */ contract BalancerV2BoostedSwapper is BalancerV2BptSwapper { /** * @dev Tells the token out that should be used for a token. In case there is no token out defined for the * requested token, it will use one of the underlying pool tokens. */ function getTokenOut(address token) public view virtual override(IBaseSwapTask, BaseSwapTask) returns (address) { address tokenOut = BaseSwapTask.getTokenOut(token); if (tokenOut != address(0)) return tokenOut; bytes32 poolId = IBalancerBoostedPool(token).getPoolId(); uint256 bptIndex = IBalancerBoostedPool(token).getBptIndex(); address balancerV2Vault = IBalancerV2SwapConnector(connector).balancerV2Vault(); (IERC20[] memory tokens, , ) = IBalancerV2Vault(balancerV2Vault).getPoolTokens(poolId); return address(bptIndex == 0 ? tokens[1] : tokens[0]); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/balancer/IBalancerV2SwapConnector.sol'; import './BaseSwapTask.sol'; import '../interfaces/swap/IBalancerV2BptSwapper.sol'; import '../interfaces/liquidity/balancer/IBalancerPool.sol'; /** * @title Balancer v2 BPT swapper task * @dev Task that extends the swapper task to use Balancer v2 */ contract BalancerV2BptSwapper is IBalancerV2BptSwapper, BaseSwapTask { using FixedPoint for uint256; using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('BALANCER_V2_BPT_SWAPPER'); /** * @dev Balancer v2 BPT swap config. Only used in the initializer. */ struct BalancerV2BptSwapConfig { BaseSwapConfig baseSwapConfig; } /** * @dev Initializes the Balancer v2 BPT swapper * @param config Balancer v2 BPT swap config */ function initialize(BalancerV2BptSwapConfig memory config) external initializer { __BalancerV2BptSwapper_init(config); } /** * @dev Initializes the Balancer v2 BPT swapper. It does call upper contracts. * @param config Balancer v2 BPT swap config */ function __BalancerV2BptSwapper_init(BalancerV2BptSwapConfig memory config) internal onlyInitializing { __BaseSwapTask_init(config.baseSwapConfig); __BalancerV2BptSwapper_init_unchained(config); } /** * @dev Initializes the Balancer v2 BPT swapper. It does not call upper contracts. * @param config Balancer v2 BPT swap config */ function __BalancerV2BptSwapper_init_unchained(BalancerV2BptSwapConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Executes the Balancer v2 BPT swapper task */ function call(address tokenIn, uint256 amountIn, uint256 slippage) external override authP(authParams(tokenIn, amountIn, slippage)) { if (amountIn == 0) amountIn = getTaskAmount(tokenIn); _beforeBalancerV2BptSwapper(tokenIn, amountIn, slippage); address tokenOut = getTokenOut(tokenIn); uint256 price = _getPrice(tokenIn, tokenOut); uint256 minAmountOut = amountIn.mulUp(price).mulUp(FixedPoint.ONE - slippage); bytes memory connectorData = abi.encodeWithSelector( IBalancerV2SwapConnector.execute.selector, tokenIn, tokenOut, amountIn, minAmountOut, IBalancerPool(tokenIn).getPoolId(), new bytes32[](0), new address[](0) ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterBalancerV2BptSwapper(tokenIn, amountIn, slippage, tokenOut, result.toUint256()); } /** * @dev Before Balancer v2 BPT swapper task */ function _beforeBalancerV2BptSwapper(address token, uint256 amount, uint256 slippage) internal virtual { _beforeBaseSwapTask(token, amount, slippage); } /** * @dev After Balancer v2 BPT swapper hook */ function _afterBalancerV2BptSwapper( address tokenIn, uint256 amountIn, uint256 slippage, address tokenOut, uint256 amountOut ) internal virtual { _afterBaseSwapTask(tokenIn, amountIn, slippage, tokenOut, amountOut); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/balancer/IBalancerV2SwapConnector.sol'; import './BalancerV2BptSwapper.sol'; import '../interfaces/liquidity/balancer/IBalancerLinearPool.sol'; /** * @title Balancer v2 linear swapper task * @dev Task that extends the Balancer v2 BPT swapper task specially for linear pools */ contract BalancerV2LinearSwapper is BalancerV2BptSwapper { /** * @dev Tells the token out that should be used for a token. In case there is no token out defined for the * requested token, it will use the linear pool main token. */ function getTokenOut(address token) public view virtual override(IBaseSwapTask, BaseSwapTask) returns (address) { address tokenOut = BaseSwapTask.getTokenOut(token); if (tokenOut != address(0)) return tokenOut; return IBalancerLinearPool(token).getMainToken(); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-helpers/contracts/utils/Denominations.sol'; import '../Task.sol'; import '../interfaces/swap/IBaseSwapTask.sol'; /** * @title Base swap task * @dev Task that offers the basic components for more detailed swap tasks */ abstract contract BaseSwapTask is IBaseSwapTask, Task { using FixedPoint for uint256; // Connector address address public override connector; // Default token out address public override defaultTokenOut; // Default maximum slippage in fixed point uint256 public override defaultMaxSlippage; // Token out per token mapping (address => address) public override customTokenOut; // Maximum slippage per token address mapping (address => uint256) public override customMaxSlippage; /** * @dev Custom token out config. Only used in the initializer. */ struct CustomTokenOut { address token; address tokenOut; } /** * @dev Custom max slippage config. Only used in the initializer. */ struct CustomMaxSlippage { address token; uint256 maxSlippage; } /** * @dev Base swap config. Only used in the initializer. */ struct BaseSwapConfig { address connector; address tokenOut; uint256 maxSlippage; CustomTokenOut[] customTokensOut; CustomMaxSlippage[] customMaxSlippages; TaskConfig taskConfig; } /** * @dev Initializes the base swap task. It does call upper contracts initializers. * @param config Base swap config */ function __BaseSwapTask_init(BaseSwapConfig memory config) internal onlyInitializing { __Task_init(config.taskConfig); __BaseSwapTask_init_unchained(config); } /** * @dev Initializes the base swap task. It does not call upper contracts initializers. * @param config Base swap config */ function __BaseSwapTask_init_unchained(BaseSwapConfig memory config) internal onlyInitializing { _setConnector(config.connector); _setDefaultTokenOut(config.tokenOut); _setDefaultMaxSlippage(config.maxSlippage); for (uint256 i = 0; i < config.customTokensOut.length; i++) { _setCustomTokenOut(config.customTokensOut[i].token, config.customTokensOut[i].tokenOut); } for (uint256 i = 0; i < config.customMaxSlippages.length; i++) { _setCustomMaxSlippage(config.customMaxSlippages[i].token, config.customMaxSlippages[i].maxSlippage); } } /** * @dev Tells the token out that should be used for a token */ function getTokenOut(address token) public view virtual override returns (address) { address tokenOut = customTokenOut[token]; return tokenOut == address(0) ? defaultTokenOut : tokenOut; } /** * @dev Tells the max slippage that should be used for a token */ function getMaxSlippage(address token) public view virtual override returns (uint256) { uint256 maxSlippage = customMaxSlippage[token]; return maxSlippage == 0 ? defaultMaxSlippage : maxSlippage; } /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function setConnector(address newConnector) external override authP(authParams(newConnector)) { _setConnector(newConnector); } /** * @dev Sets the default token out * @param tokenOut Address of the default token out to be set */ function setDefaultTokenOut(address tokenOut) external override authP(authParams(tokenOut)) { _setDefaultTokenOut(tokenOut); } /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function setDefaultMaxSlippage(uint256 maxSlippage) external override authP(authParams(maxSlippage)) { _setDefaultMaxSlippage(maxSlippage); } /** * @dev Sets a custom token out * @param token Address of the token to set a custom token out for * @param tokenOut Address of the token out to be set */ function setCustomTokenOut(address token, address tokenOut) external override authP(authParams(token, tokenOut)) { _setCustomTokenOut(token, tokenOut); } /** * @dev Sets a custom max slippage * @param token Address of the token to set a custom max slippage for * @param maxSlippage Max slippage to be set */ function setCustomMaxSlippage(address token, uint256 maxSlippage) external override authP(authParams(token, maxSlippage)) { _setCustomMaxSlippage(token, maxSlippage); } /** * @dev Before base swap task hook */ function _beforeBaseSwapTask(address token, uint256 amount, uint256 slippage) internal virtual { _beforeTask(token, amount); if (token == address(0)) revert TaskTokenZero(); if (amount == 0) revert TaskAmountZero(); if (getTokenOut(token) == address(0)) revert TaskTokenOutNotSet(); uint256 maxSlippage = getMaxSlippage(token); if (slippage > maxSlippage) revert TaskSlippageAboveMax(slippage, maxSlippage); } /** * @dev After base swap task hook */ function _afterBaseSwapTask(address tokenIn, uint256 amountIn, uint256, address tokenOut, uint256 amountOut) internal virtual { _increaseBalanceConnector(tokenOut, amountOut); _afterTask(tokenIn, amountIn); } /** * @dev Sets a new connector * @param newConnector Address of the connector to be set */ function _setConnector(address newConnector) internal { if (newConnector == address(0)) revert TaskConnectorZero(); connector = newConnector; emit ConnectorSet(newConnector); } /** * @dev Sets the default token out * @param tokenOut Default token out to be set */ function _setDefaultTokenOut(address tokenOut) internal { defaultTokenOut = tokenOut; emit DefaultTokenOutSet(tokenOut); } /** * @dev Sets the default max slippage * @param maxSlippage Default max slippage to be set */ function _setDefaultMaxSlippage(uint256 maxSlippage) internal { if (maxSlippage > FixedPoint.ONE) revert TaskSlippageAboveOne(); defaultMaxSlippage = maxSlippage; emit DefaultMaxSlippageSet(maxSlippage); } /** * @dev Sets a custom token out for a token * @param token Address of the token to set the custom token out for * @param tokenOut Address of the token out to be set */ function _setCustomTokenOut(address token, address tokenOut) internal { if (token == address(0)) revert TaskTokenZero(); customTokenOut[token] = tokenOut; emit CustomTokenOutSet(token, tokenOut); } /** * @dev Sets a custom max slippage for a token * @param token Address of the token to set the custom max slippage for * @param maxSlippage Max slippage to be set */ function _setCustomMaxSlippage(address token, uint256 maxSlippage) internal { if (token == address(0)) revert TaskTokenZero(); if (maxSlippage > FixedPoint.ONE) revert TaskSlippageAboveOne(); customMaxSlippage[token] = maxSlippage; emit CustomMaxSlippageSet(token, maxSlippage); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/hop/IHopL2Amm.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/hop/IHopSwapConnector.sol'; import './BaseSwapTask.sol'; import '../interfaces/swap/IHopL2Swapper.sol'; /** * @title Hop L2 swapper * @dev Task that extends the base swap task to use Hop */ contract HopL2Swapper is IHopL2Swapper, BaseSwapTask { using FixedPoint for uint256; using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('HOP_L2_SWAPPER'); // List of AMMs per token mapping (address => address) public override tokenAmm; /** * @dev Token amm config. Only used in the initializer. */ struct TokenAmm { address token; address amm; } /** * @dev Hop L2 swap config. Only used in the initializer. */ struct HopL2SwapConfig { TokenAmm[] tokenAmms; BaseSwapConfig baseSwapConfig; } /** * @dev Initializes the Hop L2 swapper * @param config Hop L2 swap config */ function initialize(HopL2SwapConfig memory config) external virtual initializer { __HopL2Swapper_init(config); } /** * @dev Initializes the Hop L2 swapper. It does call upper contracts initializers. * @param config Hop L2 swap config */ function __HopL2Swapper_init(HopL2SwapConfig memory config) internal onlyInitializing { __BaseSwapTask_init(config.baseSwapConfig); __HopL2Swapper_init_unchained(config); } /** * @dev Initializes the Hop L2 swapper. It does not call upper contracts initializers. * @param config Hop L2 swap config */ function __HopL2Swapper_init_unchained(HopL2SwapConfig memory config) internal onlyInitializing { for (uint256 i = 0; i < config.tokenAmms.length; i++) { _setTokenAmm(config.tokenAmms[i].token, config.tokenAmms[i].amm); } } /** * @dev Sets an AMM for a hToken * @param hToken Address of the hToken to be set * @param amm AMM address to be set for the hToken */ function setTokenAmm(address hToken, address amm) external authP(authParams(hToken, amm)) { _setTokenAmm(hToken, amm); } /** * @dev Execution function */ function call(address hToken, uint256 amount, uint256 slippage) external override authP(authParams(hToken, amount, slippage)) { if (amount == 0) amount = getTaskAmount(hToken); _beforeHopL2Swapper(hToken, amount, slippage); address tokenOut = getTokenOut(hToken); address dexAddress = IHopL2Amm(tokenAmm[hToken]).exchangeAddress(); uint256 minAmountOut = amount.mulUp(FixedPoint.ONE - slippage); bytes memory connectorData = abi.encodeWithSelector( IHopSwapConnector.execute.selector, hToken, tokenOut, amount, minAmountOut, dexAddress ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterHopL2Swapper(hToken, amount, slippage, tokenOut, result.toUint256()); } /** * @dev Before Hop L2 swapper hook */ function _beforeHopL2Swapper(address token, uint256 amount, uint256 slippage) internal virtual { _beforeBaseSwapTask(token, amount, slippage); if (tokenAmm[token] == address(0)) revert TaskMissingHopTokenAmm(); } /** * @dev After Hop L2 swapper hook */ function _afterHopL2Swapper( address tokenIn, uint256 amountIn, uint256 slippage, address tokenOut, uint256 amountOut ) internal virtual { _afterBaseSwapTask(tokenIn, amountIn, slippage, tokenOut, amountOut); } /** * @dev Set an AMM for a Hop token * @param hToken Address of the hToken to set an AMM for * @param amm AMM to be set */ function _setTokenAmm(address hToken, address amm) internal { if (hToken == address(0)) revert TaskTokenZero(); if (amm != address(0) && hToken != IHopL2Amm(amm).hToken()) revert TaskHopTokenAmmMismatch(hToken, amm); tokenAmm[hToken] = amm; emit TokenAmmSet(hToken, amm); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/1inch/IOneInchV5Connector.sol'; import './BaseSwapTask.sol'; import '../interfaces/swap/IOneInchV5Swapper.sol'; /** * @title 1inch v5 swapper * @dev Task that extends the base swap task to use 1inch v5 */ contract OneInchV5Swapper is IOneInchV5Swapper, BaseSwapTask { using FixedPoint for uint256; using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('1INCH_V5_SWAPPER'); /** * @dev 1inch v5 swap config. Only used in the initializer. */ struct OneInchV5SwapConfig { BaseSwapConfig baseSwapConfig; } /** * @dev Initializes the 1inch v5 swapper * @param config 1inch v5 swap config */ function initialize(OneInchV5SwapConfig memory config) external virtual initializer { __OneInchV5Swapper_init(config); } /** * @dev Initializes the 1inch v5 swapper. It does call upper contracts initializers. * @param config 1inch v5 swap config */ function __OneInchV5Swapper_init(OneInchV5SwapConfig memory config) internal onlyInitializing { __BaseSwapTask_init(config.baseSwapConfig); __OneInchV5Swapper_init_unchained(config); } /** * @dev Initializes the 1inch v5 swapper. It does not call upper contracts initializers. * @param config 1inch v5 swap config */ function __OneInchV5Swapper_init_unchained(OneInchV5SwapConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Executes the 1inch V5 swapper task */ function call(address tokenIn, uint256 amountIn, uint256 slippage, bytes memory data) external override authP(authParams(tokenIn, amountIn, slippage)) { if (amountIn == 0) amountIn = getTaskAmount(tokenIn); _beforeOneInchV5Swapper(tokenIn, amountIn, slippage); address tokenOut = getTokenOut(tokenIn); uint256 price = _getPrice(tokenIn, tokenOut); uint256 minAmountOut = amountIn.mulUp(price).mulUp(FixedPoint.ONE - slippage); bytes memory connectorData = abi.encodeWithSelector( IOneInchV5Connector.execute.selector, tokenIn, tokenOut, amountIn, minAmountOut, data ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterOneInchV5Swapper(tokenIn, amountIn, slippage, tokenOut, result.toUint256()); } /** * @dev Before 1inch v5 swapper hook */ function _beforeOneInchV5Swapper(address token, uint256 amount, uint256 slippage) internal virtual { _beforeBaseSwapTask(token, amount, slippage); } /** * @dev After 1inch v5 swapper hook */ function _afterOneInchV5Swapper( address tokenIn, uint256 amountIn, uint256 slippage, address tokenOut, uint256 amountOut ) internal virtual { _afterBaseSwapTask(tokenIn, amountIn, slippage, tokenOut, amountOut); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol'; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/paraswap/IParaswapV5Connector.sol'; import './BaseSwapTask.sol'; import '../interfaces/swap/IParaswapV5Swapper.sol'; /** * @title Paraswap V5 swapper task * @dev Task that extends the swapper task to use Paraswap v5 */ contract ParaswapV5Swapper is IParaswapV5Swapper, BaseSwapTask { using FixedPoint for uint256; using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('PARASWAP_V5_SWAPPER'); // Address of the Paraswap quote signer address public override quoteSigner; /** * @dev Paraswap v5 swap config. Only used in the initializer. */ struct ParaswapV5SwapConfig { address quoteSigner; BaseSwapConfig baseSwapConfig; } /** * @dev Initializes the Paraswap v5 swapper * @param config Paraswap v5 swap config */ function initialize(ParaswapV5SwapConfig memory config) external virtual initializer { __ParaswapV5Swapper_init(config); } /** * @dev Initializes the Paraswap v5 swapper. It does call upper contracts initializers. * @param config Paraswap v5 swap config */ function __ParaswapV5Swapper_init(ParaswapV5SwapConfig memory config) internal onlyInitializing { __BaseSwapTask_init(config.baseSwapConfig); __ParaswapV5Swapper_init_unchained(config); } /** * @dev Initializes the Paraswap v5 swapper. It does not call upper contracts initializers. * @param config Paraswap v5 swap config */ function __ParaswapV5Swapper_init_unchained(ParaswapV5SwapConfig memory config) internal onlyInitializing { _setQuoteSigner(config.quoteSigner); } /** * @dev Sets the quote signer address * @param newQuoteSigner Address of the new quote signer to be set */ function setQuoteSigner(address newQuoteSigner) external override authP(authParams(newQuoteSigner)) { _setQuoteSigner(newQuoteSigner); } /** * @dev Execute Paraswap v5 swapper task */ function call( address tokenIn, uint256 amountIn, uint256 minAmountOut, uint256 expectedAmountOut, uint256 deadline, bytes memory data, bytes memory sig ) external override authP(authParams(tokenIn, amountIn, minAmountOut, expectedAmountOut, deadline)) { if (amountIn == 0) amountIn = getTaskAmount(tokenIn); address tokenOut = getTokenOut(tokenIn); uint256 slippage = FixedPoint.ONE - minAmountOut.divUp(expectedAmountOut); _beforeParaswapV5Swapper( tokenIn, tokenOut, amountIn, slippage, minAmountOut, expectedAmountOut, deadline, data, sig ); bytes memory connectorData = abi.encodeWithSelector( IParaswapV5Connector.execute.selector, tokenIn, tokenOut, amountIn, minAmountOut, data ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterParaswapV5Swapper(tokenIn, amountIn, slippage, tokenOut, result.toUint256()); } /** * @dev Before Paraswap v5 swapper hook */ function _beforeParaswapV5Swapper( address tokenIn, address tokenOut, uint256 amountIn, uint256 slippage, uint256 minAmountOut, uint256 expectedAmountOut, uint256 deadline, bytes memory data, bytes memory sig ) internal virtual { _beforeBaseSwapTask(tokenIn, amountIn, slippage); bool isBuy = false; bytes32 message = keccak256( abi.encodePacked(tokenIn, tokenOut, isBuy, amountIn, minAmountOut, expectedAmountOut, deadline, data) ); address signer = ECDSA.recover(ECDSA.toEthSignedMessageHash(message), sig); if (signer != quoteSigner) revert TaskInvalidQuoteSigner(signer, quoteSigner); if (block.timestamp > deadline) revert TaskQuoteSignerPastDeadline(deadline, block.timestamp); } /** * @dev After Paraswap v5 swapper hook */ function _afterParaswapV5Swapper( address tokenIn, uint256 amountIn, uint256 slippage, address tokenOut, uint256 amountOut ) internal virtual { _afterBaseSwapTask(tokenIn, amountIn, slippage, tokenOut, amountOut); } /** * @dev Sets the quote signer address * @param newQuoteSigner Address of the new quote signer to be set */ function _setQuoteSigner(address newQuoteSigner) internal { if (newQuoteSigner == address(0)) revert TaskQuoteSignerZero(); quoteSigner = newQuoteSigner; emit QuoteSignerSet(newQuoteSigner); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/uniswap/IUniswapV2Connector.sol'; import './BaseSwapTask.sol'; import '../interfaces/swap/IUniswapV2Swapper.sol'; /** * @title Uniswap v2 swapper * @dev Task that extends the base swap task to use Uniswap v2 */ contract UniswapV2Swapper is IUniswapV2Swapper, BaseSwapTask { using FixedPoint for uint256; using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('UNISWAP_V2_SWAPPER'); /** * @dev Uniswap v2 swap config. Only used in the initializer. */ struct UniswapV2SwapConfig { BaseSwapConfig baseSwapConfig; } /** * @dev Initializes the Uniswap v2 swapper * @param config Uniswap v2 swap config */ function initialize(UniswapV2SwapConfig memory config) external initializer { __UniswapV2Swapper_init(config); } /** * @dev Initializes the Uniswap v2 swapper. It does call upper contracts. * @param config Uniswap v2 swap config */ function __UniswapV2Swapper_init(UniswapV2SwapConfig memory config) internal onlyInitializing { __BaseSwapTask_init(config.baseSwapConfig); __UniswapV2Swapper_init_unchained(config); } /** * @dev Initializes the Uniswap v2 swapper. It does not call upper contracts. * @param config Uniswap v2 swap config */ function __UniswapV2Swapper_init_unchained(UniswapV2SwapConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Executes the Uniswap v2 swapper task */ function call(address tokenIn, uint256 amountIn, uint256 slippage, address[] memory hopTokens) external override authP(authParams(tokenIn, amountIn, slippage)) { if (amountIn == 0) amountIn = getTaskAmount(tokenIn); _beforeUniswapV2Swapper(tokenIn, amountIn, slippage); address tokenOut = getTokenOut(tokenIn); uint256 price = _getPrice(tokenIn, tokenOut); uint256 minAmountOut = amountIn.mulUp(price).mulUp(FixedPoint.ONE - slippage); bytes memory connectorData = abi.encodeWithSelector( IUniswapV2Connector.execute.selector, tokenIn, tokenOut, amountIn, minAmountOut, hopTokens ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterUniswapV2Swapper(tokenIn, amountIn, slippage, tokenOut, result.toUint256()); } /** * @dev Before Uniswap v2 swapper hook */ function _beforeUniswapV2Swapper(address token, uint256 amount, uint256 slippage) internal virtual { _beforeBaseSwapTask(token, amount, slippage); } /** * @dev After Uniswap v2 swapper hook */ function _afterUniswapV2Swapper( address tokenIn, uint256 amountIn, uint256 slippage, address tokenOut, uint256 amountOut ) internal virtual { _afterBaseSwapTask(tokenIn, amountIn, slippage, tokenOut, amountOut); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol'; import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol'; import '@mimic-fi/v3-connectors/contracts/interfaces/uniswap/IUniswapV3Connector.sol'; import './BaseSwapTask.sol'; import '../interfaces/swap/IUniswapV3Swapper.sol'; /** * @title Uniswap v3 swapper task * @dev Task that extends the swapper task to use Uniswap v3 */ contract UniswapV3Swapper is IUniswapV3Swapper, BaseSwapTask { using FixedPoint for uint256; using BytesHelpers for bytes; // Execution type for relayers bytes32 public constant override EXECUTION_TYPE = keccak256('UNISWAP_V3_SWAPPER'); /** * @dev Uniswap v3 swap config. Only used in the initializer. */ struct UniswapV3SwapConfig { BaseSwapConfig baseSwapConfig; } /** * @dev Initializes the Uniswap v3 swapper * @param config Uniswap v3 swap config */ function initialize(UniswapV3SwapConfig memory config) external initializer { __UniswapV3Swapper_init(config); } /** * @dev Initializes the Uniswap V3 swapper. It does call upper contracts. * @param config Uniswap v3 swap config */ function __UniswapV3Swapper_init(UniswapV3SwapConfig memory config) internal onlyInitializing { __BaseSwapTask_init(config.baseSwapConfig); __UniswapV3Swapper_init_unchained(config); } /** * @dev Initializes the Uniswap V3 swapper. It does not call upper contracts. * @param config Uniswap v3 swap config */ function __UniswapV3Swapper_init_unchained(UniswapV3SwapConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Executes the Uniswap v3 swapper task */ function call( address tokenIn, uint256 amountIn, uint256 slippage, uint24 fee, address[] memory hopTokens, uint24[] memory hopFees ) external override authP(authParams(tokenIn, amountIn, slippage, fee)) { if (amountIn == 0) amountIn = getTaskAmount(tokenIn); _beforeUniswapV3Swapper(tokenIn, amountIn, slippage); address tokenOut = getTokenOut(tokenIn); uint256 price = _getPrice(tokenIn, tokenOut); uint256 minAmountOut = amountIn.mulUp(price).mulUp(FixedPoint.ONE - slippage); bytes memory connectorData = abi.encodeWithSelector( IUniswapV3Connector.execute.selector, tokenIn, tokenOut, amountIn, minAmountOut, fee, hopTokens, hopFees ); bytes memory result = ISmartVault(smartVault).execute(connector, connectorData); _afterUniswapV3Swapper(tokenIn, amountIn, slippage, tokenOut, result.toUint256()); } /** * @dev Before Uniswap v3 swapper task */ function _beforeUniswapV3Swapper(address token, uint256 amount, uint256 slippage) internal virtual { _beforeBaseSwapTask(token, amount, slippage); } /** * @dev After Uniswap v3 swapper hook */ function _afterUniswapV3Swapper( address tokenIn, uint256 amountIn, uint256 slippage, address tokenOut, uint256 amountOut ) internal virtual { _afterBaseSwapTask(tokenIn, amountIn, slippage, tokenOut, amountOut); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import './interfaces/ITask.sol'; import './base/BaseTask.sol'; import './base/PausableTask.sol'; import './base/GasLimitedTask.sol'; import './base/TimeLockedTask.sol'; import './base/TokenIndexedTask.sol'; import './base/TokenThresholdTask.sol'; import './base/VolumeLimitedTask.sol'; /** * @title Task * @dev Shared components across all tasks */ abstract contract Task is ITask, BaseTask, PausableTask, GasLimitedTask, TimeLockedTask, TokenIndexedTask, TokenThresholdTask, VolumeLimitedTask { /** * @dev Task config. Only used in the initializer. */ struct TaskConfig { BaseConfig baseConfig; GasLimitConfig gasLimitConfig; TimeLockConfig timeLockConfig; TokenIndexConfig tokenIndexConfig; TokenThresholdConfig tokenThresholdConfig; VolumeLimitConfig volumeLimitConfig; } /** * @dev Initializes the task. It does call upper contracts initializers. * @param config Task config */ function __Task_init(TaskConfig memory config) internal onlyInitializing { __BaseTask_init(config.baseConfig); __PausableTask_init(); __GasLimitedTask_init(config.gasLimitConfig); __TimeLockedTask_init(config.timeLockConfig); __TokenIndexedTask_init(config.tokenIndexConfig); __TokenThresholdTask_init(config.tokenThresholdConfig); __VolumeLimitedTask_init(config.volumeLimitConfig); __Task_init_unchained(config); } /** * @dev Initializes the task. It does not call upper contracts initializers. * @param config Task config */ function __Task_init_unchained(TaskConfig memory config) internal onlyInitializing { // solhint-disable-previous-line no-empty-blocks } /** * @dev Fetches a base/quote price */ function _getPrice(address base, address quote) internal view override(BaseTask, GasLimitedTask, TokenThresholdTask, VolumeLimitedTask) returns (uint256) { return BaseTask._getPrice(base, quote); } /** * @dev Before task hook */ function _beforeTask(address token, uint256 amount) internal virtual { _beforeBaseTask(token, amount); _beforePausableTask(token, amount); _beforeGasLimitedTask(token, amount); _beforeTimeLockedTask(token, amount); _beforeTokenIndexedTask(token, amount); _beforeTokenThresholdTask(token, amount); _beforeVolumeLimitedTask(token, amount); } /** * @dev After task hook */ function _afterTask(address token, uint256 amount) internal virtual { _afterVolumeLimitedTask(token, amount); _afterTokenThresholdTask(token, amount); _afterTokenIndexedTask(token, amount); _afterTimeLockedTask(token, amount); _afterGasLimitedTask(token, amount); _afterPausableTask(token, amount); _afterBaseTask(token, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../../base/BaseTask.sol'; contract BaseTaskMock is BaseTask { bytes32 public constant override EXECUTION_TYPE = keccak256('BASE_TASK'); function initialize(BaseConfig memory config) external virtual initializer { __BaseTask_init(config); } function call(address token, uint256 amount) external { _beforeBaseTask(token, amount); _afterBaseTask(token, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../../base/BaseTask.sol'; import '../../base/GasLimitedTask.sol'; contract GasLimitedTaskMock is BaseTask, GasLimitedTask { bytes32 public constant override EXECUTION_TYPE = keccak256('GAS_LIMITED_TASK'); struct GasLimitMockConfig { BaseConfig baseConfig; GasLimitConfig gasLimitConfig; } function initialize(GasLimitMockConfig memory config) external virtual initializer { __BaseTask_init(config.baseConfig); __GasLimitedTask_init(config.gasLimitConfig); } function call(address token, uint256 amount) external { _beforeGasLimitedTaskMock(token, amount); _afterGasLimitedTaskMock(token, amount); } /** * @dev Fetches a base/quote price */ function _getPrice(address base, address quote) internal view override(BaseTask, GasLimitedTask) returns (uint256) { return BaseTask._getPrice(base, quote); } /** * @dev Before gas limited task mock hook */ function _beforeGasLimitedTaskMock(address token, uint256 amount) internal virtual { _beforeBaseTask(token, amount); _beforeGasLimitedTask(token, amount); } /** * @dev After gas limited task mock hook */ function _afterGasLimitedTaskMock(address token, uint256 amount) internal virtual { _afterGasLimitedTask(token, amount); _afterBaseTask(token, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../../base/BaseTask.sol'; import '../../base/PausableTask.sol'; contract PausableTaskMock is BaseTask, PausableTask { bytes32 public constant override EXECUTION_TYPE = keccak256('PAUSABLE_TASK'); struct PauseMockConfig { BaseConfig baseConfig; } function initialize(PauseMockConfig memory config) external virtual initializer { __BaseTask_init(config.baseConfig); __PausableTask_init(); } function call(address token, uint256 amount) external { if (amount == 0) amount = getTaskAmount(token); _beforePausableTaskMock(token, amount); _afterPausableTaskMock(token, amount); } /** * @dev Before pausable task mock hook */ function _beforePausableTaskMock(address token, uint256 amount) internal virtual { _beforeBaseTask(token, amount); _beforePausableTask(token, amount); } /** * @dev After pausable task mock hook */ function _afterPausableTaskMock(address token, uint256 amount) internal virtual { _afterPausableTask(token, amount); _afterBaseTask(token, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../../base/BaseTask.sol'; import '../../base/TimeLockedTask.sol'; contract TimeLockedTaskMock is BaseTask, TimeLockedTask { bytes32 public constant override EXECUTION_TYPE = keccak256('TIME_LOCKED_TASK'); struct TimeLockMockConfig { BaseConfig baseConfig; TimeLockConfig timeLockConfig; } function initialize(TimeLockMockConfig memory config) external virtual initializer { __BaseTask_init(config.baseConfig); __TimeLockedTask_init(config.timeLockConfig); } function call() external { _beforeTimeLockedTaskMock(); _afterTimeLockedTaskMock(); } /** * @dev Before time locked task mock hook */ function _beforeTimeLockedTaskMock() internal virtual { _beforeBaseTask(address(0), 0); _beforeTimeLockedTask(address(0), 0); } /** * @dev After time locked task mock hook */ function _afterTimeLockedTaskMock() internal virtual { _afterTimeLockedTask(address(0), 0); _afterBaseTask(address(0), 0); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../../base/BaseTask.sol'; import '../../base/TokenIndexedTask.sol'; contract TokenIndexedTaskMock is BaseTask, TokenIndexedTask { using EnumerableSet for EnumerableSet.AddressSet; bytes32 public constant override EXECUTION_TYPE = keccak256('TOKEN_INDEXED_TASK'); struct TokenIndexMockConfig { BaseConfig baseConfig; TokenIndexConfig tokenIndexConfig; } function initialize(TokenIndexMockConfig memory config) external virtual initializer { __BaseTask_init(config.baseConfig); __TokenIndexedTask_init(config.tokenIndexConfig); } function call(address token) external { _beforeTokenIndexedTaskMock(token); _afterTokenIndexedTaskMock(token); } /** * @dev Before token indexed task mock hook */ function _beforeTokenIndexedTaskMock(address token) internal virtual { _beforeBaseTask(token, 0); _beforeTokenIndexedTask(token, 0); } /** * @dev After token indexed task mock hook */ function _afterTokenIndexedTaskMock(address token) internal virtual { _afterTokenIndexedTask(token, 0); _afterBaseTask(token, 0); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../../base/BaseTask.sol'; import '../../base/TokenThresholdTask.sol'; contract TokenThresholdTaskMock is BaseTask, TokenThresholdTask { bytes32 public constant override EXECUTION_TYPE = keccak256('TOKEN_THRESHOLD_TASK'); struct TokenThresholdMockConfig { BaseConfig baseConfig; TokenThresholdConfig tokenThresholdConfig; } function initialize(TokenThresholdMockConfig memory config) external virtual initializer { __BaseTask_init(config.baseConfig); __TokenThresholdTask_init(config.tokenThresholdConfig); } function call(address token, uint256 amount) external { _beforeTokenThresholdTask(token, amount); _afterTokenThresholdTask(token, amount); } /** * @dev Fetches a base/quote price */ function _getPrice(address base, address quote) internal view override(BaseTask, TokenThresholdTask) returns (uint256) { return BaseTask._getPrice(base, quote); } /** * @dev Before token threshold task mock hook */ function _beforeTokenThresholdTaskMock(address token, uint256 amount) internal virtual { _beforeBaseTask(token, amount); _beforeTokenThresholdTask(token, amount); } /** * @dev After token threshold task mock hook */ function _afterTokenThresholdTaskMock(address token, uint256 amount) internal virtual { _afterTokenThresholdTask(token, amount); _afterBaseTask(token, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../../base/BaseTask.sol'; import '../../base/VolumeLimitedTask.sol'; contract VolumeLimitedTaskMock is BaseTask, VolumeLimitedTask { bytes32 public constant override EXECUTION_TYPE = keccak256('VOLUME_LIMITED_TASK'); struct VolumeLimitMockConfig { BaseConfig baseConfig; VolumeLimitConfig volumeLimitConfig; } function initialize(VolumeLimitMockConfig memory config) external virtual initializer { __BaseTask_init(config.baseConfig); __VolumeLimitedTask_init(config.volumeLimitConfig); } function call(address token, uint256 amount) external { _beforeVolumeLimitedTaskMock(token, amount); _afterVolumeLimitedTaskMock(token, amount); } /** * @dev Fetches a base/quote price */ function _getPrice(address base, address quote) internal view override(BaseTask, VolumeLimitedTask) returns (uint256) { return BaseTask._getPrice(base, quote); } /** * @dev Before volume limited task mock hook */ function _beforeVolumeLimitedTaskMock(address token, uint256 amount) internal virtual { _beforeBaseTask(token, amount); _beforeVolumeLimitedTask(token, amount); } /** * @dev After volume limited task mock hook */ function _afterVolumeLimitedTaskMock(address token, uint256 amount) internal virtual { _afterVolumeLimitedTask(token, amount); _afterBaseTask(token, amount); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract AxelarConnectorMock { event LogExecute(uint256 chainId, address token, uint256 amount, address recipient); function execute(uint256 chainId, address token, uint256 amount, address recipient) external { emit LogExecute(chainId, token, amount, recipient); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract ConnextConnectorMock { event LogExecute( uint256 chainId, address token, uint256 amount, uint256 minAmountOut, address recipient, uint256 relayerFee ); function execute( uint256 chainId, address token, uint256 amount, uint256 minAmountOut, address recipient, uint256 relayerFee ) external { emit LogExecute(chainId, token, amount, minAmountOut, recipient, relayerFee); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract HopBridgeConnectorMock { event LogExecute( uint256 chainId, address token, uint256 amount, uint256 minAmountOut, address recipient, address bridge, uint256 deadline, address relayer, uint256 fee ); function execute( uint256 chainId, address token, uint256 amount, uint256 minAmountOut, address recipient, address bridge, uint256 deadline, address relayer, uint256 fee ) external { emit LogExecute(chainId, token, amount, minAmountOut, recipient, bridge, deadline, relayer, fee); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract WormholeConnectorMock { event LogExecute(uint256 chainId, address token, uint256 amount, uint256 minAmountOut, address recipient); function execute(uint256 chainId, address token, uint256 amount, uint256 minAmountOut, address recipient) external { emit LogExecute(chainId, token, amount, minAmountOut, recipient); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. pragma solidity ^0.8.0; contract BalancerV2PoolConnectorMock { address public immutable balancerV2Vault; constructor(address _balancerV2Vault) { balancerV2Vault = _balancerV2Vault; } event LogExecute(address tokenIn, uint256 amountIn, address[] tokensOut, uint256[] minAmountsOut); function exit(address tokenIn, uint256 amountIn, address[] memory tokensOut, uint256[] memory minAmountsOut) external returns (uint256[] memory amountsOut) { emit LogExecute(tokenIn, amountIn, tokensOut, minAmountsOut); return minAmountsOut; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; import '@mimic-fi/v3-helpers/contracts/mocks/TokenMock.sol'; contract ConvexConnectorMock { IERC20 public immutable rewardToken; uint256 public immutable rewardAmount; constructor() { rewardAmount = 5e18; rewardToken = new TokenMock('Convex Claimer Reward', 18); } mapping (address => address) public getCvxPool; mapping (address => address) public getCurvePool; event LogClaim(address cvxPool); event LogJoin(address curvePool, uint256 amount); event LogExit(address cvxPool, uint256 amount); function setCvxPool(address curvePool, address cvxPool) external { getCvxPool[curvePool] = cvxPool; } function setCurvePool(address cvxPool, address curvePool) external { getCurvePool[cvxPool] = curvePool; } function claim(address cvxPool) external returns (address[] memory tokens, uint256[] memory amounts) { tokens = new address[](1); tokens[0] = address(rewardToken); amounts = new uint256[](1); amounts[0] = rewardAmount; emit LogClaim(cvxPool); } function join(address curvePool, uint256 amount) external returns (uint256) { emit LogJoin(curvePool, amount); return amount; } function exit(address cvxPool, uint256 amount) external returns (uint256) { emit LogExit(cvxPool, amount); return amount; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract Curve2CrvConnectorMock { event LogJoin(address pool, address tokenIn, uint256 amountIn, uint256 slippage); event LogExit(address pool, uint256 amountIn, address tokenOut, uint256 slippage); function join(address pool, address tokenIn, uint256 amountIn, uint256 slippage) external returns (uint256) { emit LogJoin(pool, tokenIn, amountIn, slippage); return amountIn; } function exit(address pool, uint256 amountIn, address tokenOut, uint256 slippage) external returns (uint256) { emit LogExit(pool, amountIn, tokenOut, slippage); return amountIn; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract ERC4626ConnectorMock { address public immutable tokenOut; event LogJoin(address erc4626, address token, uint256 amount, uint256 minAmountOut); event LogExit(address erc4626, uint256 amount, uint256 minAmountOut); constructor(address _tokenOut) { tokenOut = _tokenOut; } function join(address erc4626, address token, uint256 assets, uint256 minSharesOut) external returns (address, uint256) { emit LogJoin(erc4626, token, assets, minSharesOut); return (erc4626, minSharesOut); } function exit(address erc4626, uint256 shares, uint256 minAssetsOut) external returns (address, uint256) { emit LogExit(erc4626, shares, minAssetsOut); return (tokenOut, minAssetsOut); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract HopL2AmmMock { address public immutable hToken; address public immutable l2CanonicalToken; constructor(address _token, address _hToken) { l2CanonicalToken = _token; hToken = _hToken; } function exchangeAddress() external view returns (address) { return address(this); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract RelayerMock { event Deposited(address smartVault, uint256 amount); mapping (address => uint256) public getSmartVaultBalance; mapping (address => uint256) public getSmartVaultUsedQuota; function deposit(address smartVault, uint256 amount) external payable { getSmartVaultBalance[smartVault] += amount; emit Deposited(smartVault, amount); } function setSmartVaultUsedQuota(address smartVault, uint256 quota) external { getSmartVaultUsedQuota[smartVault] = quota; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. pragma solidity ^0.8.0; contract BalancerV2SwapConnectorMock { address public immutable balancerV2Vault; constructor(address _balancerV2Vault) { balancerV2Vault = _balancerV2Vault; } event LogExecute( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes32 poolId, bytes32[] hopPoolsIds, address[] hopTokens ); function execute( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes32 poolId, bytes32[] memory hopPoolsIds, address[] memory hopTokens ) external returns (uint256) { emit LogExecute(tokenIn, tokenOut, amountIn, minAmountOut, poolId, hopPoolsIds, hopTokens); return minAmountOut; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract HopSwapConnectorMock { event LogExecute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, address hopDexAddress); function execute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, address hopDexAddress) external returns (uint256) { emit LogExecute(tokenIn, tokenOut, amountIn, minAmountOut, hopDexAddress); return minAmountOut; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract OneInchV5ConnectorMock { event LogExecute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data); function execute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes memory data) external returns (uint256) { emit LogExecute(tokenIn, tokenOut, amountIn, minAmountOut, data); return minAmountOut; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract ParaswapV5ConnectorMock { event LogExecute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data); function execute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes memory data) external returns (uint256) { emit LogExecute(tokenIn, tokenOut, amountIn, minAmountOut, data); return minAmountOut; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.0; contract UniswapV2ConnectorMock { event LogExecute(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, address[] hopTokens); function execute( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, address[] memory hopTokens ) external returns (uint256) { emit LogExecute(tokenIn, tokenOut, amountIn, minAmountOut, hopTokens); return minAmountOut; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. pragma solidity ^0.8.0; contract UniswapV3ConnectorMock { event LogExecute( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, uint24 fee, address[] hopTokens, uint24[] hopFees ); function execute( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, uint24 fee, address[] memory hopTokens, uint24[] memory hopFees ) external returns (uint256) { emit LogExecute(tokenIn, tokenOut, amountIn, minAmountOut, fee, hopTokens, hopFees); return minAmountOut; } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"},{"internalType":"uint256[]","name":"how","type":"uint256[]"}],"name":"AuthSenderNotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"aInflated","type":"uint256"}],"name":"FixedPointDivInternal","type":"error"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"name":"FixedPointMulOverflow","type":"error"},{"inputs":[],"name":"FixedPointZeroDivision","type":"error"},{"inputs":[],"name":"TaskAcceptanceInputLengthMismatch","type":"error"},{"inputs":[],"name":"TaskAcceptanceTokenZero","type":"error"},{"inputs":[],"name":"TaskAmountZero","type":"error"},{"inputs":[],"name":"TaskGasNotInitialized","type":"error"},{"inputs":[{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasPriceLimit","type":"uint256"}],"name":"TaskGasPriceLimitExceeded","type":"error"},{"inputs":[{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"uint256","name":"date","type":"uint256"}],"name":"TaskInvalidAllowedDate","type":"error"},{"inputs":[{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"uint256","name":"window","type":"uint256"}],"name":"TaskInvalidAllowedWindow","type":"error"},{"inputs":[{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"uint256","name":"frequency","type":"uint256"}],"name":"TaskInvalidFrequency","type":"error"},{"inputs":[{"internalType":"uint8","name":"mode","type":"uint8"}],"name":"TaskInvalidFrequencyMode","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"TaskInvalidThresholdInput","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"period","type":"uint256"}],"name":"TaskInvalidVolumeLimitInput","type":"error"},{"inputs":[],"name":"TaskPaused","type":"error"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"TaskPreviousConnectorNotZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"priorityFee","type":"uint256"},{"internalType":"uint256","name":"priorityFeeLimit","type":"uint256"}],"name":"TaskPriorityFeeLimitExceeded","type":"error"},{"inputs":[{"internalType":"bytes32","name":"connectorId","type":"bytes32"}],"name":"TaskSameBalanceConnectors","type":"error"},{"inputs":[{"internalType":"address","name":"smartVault","type":"address"}],"name":"TaskSmartVaultPriceOracleNotSet","type":"error"},{"inputs":[],"name":"TaskThresholdTokenZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentTimestamp","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"name":"TaskTimeLockActive","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"TaskTokenNotAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"TaskTokenThresholdNotMet","type":"error"},{"inputs":[],"name":"TaskTokenZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"txCost","type":"uint256"},{"internalType":"uint256","name":"txCostLimit","type":"uint256"}],"name":"TaskTxCostLimitExceeded","type":"error"},{"inputs":[],"name":"TaskTxCostLimitPctAboveOne","type":"error"},{"inputs":[{"internalType":"uint256","name":"txCostPct","type":"uint256"},{"internalType":"uint256","name":"txCostLimitPct","type":"uint256"}],"name":"TaskTxCostLimitPctExceeded","type":"error"},{"inputs":[],"name":"TaskUnpaused","type":"error"},{"inputs":[],"name":"TaskValueZero","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"volume","type":"uint256"}],"name":"TaskVolumeLimitExceeded","type":"error"},{"inputs":[],"name":"TaskVolumeLimitTokenZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"previous","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"next","type":"bytes32"}],"name":"BalanceConnectorsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"thresholdToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"min","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"max","type":"uint256"}],"name":"CustomTokenThresholdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"limitToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"period","type":"uint256"}],"name":"CustomVolumeLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"min","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"max","type":"uint256"}],"name":"DefaultTokenThresholdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"limitToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"period","type":"uint256"}],"name":"DefaultVolumeLimitSet","type":"event"},{"anonymous":false,"inputs":[],"name":"Executed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"gasPriceLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priorityFeeLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"txCostLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"txCostLimitPct","type":"uint256"}],"name":"GasLimitsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"allowedAt","type":"uint256"}],"name":"TimeLockAllowedAtSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"mode","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"frequency","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allowedAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"window","type":"uint256"}],"name":"TimeLockSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bool","name":"added","type":"bool"}],"name":"TokensAcceptanceListSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum ITokenIndexedTask.TokensAcceptanceType","name":"acceptanceType","type":"uint8"}],"name":"TokensAcceptanceTypeSet","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpaused","type":"event"},{"inputs":[],"name":"EXECUTION_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authorizer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"call","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"customTokenThreshold","outputs":[{"internalType":"address","name":"thresholdToken","type":"address"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"customVolumeLimit","outputs":[{"internalType":"address","name":"limitToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"accrued","type":"uint256"},{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"nextResetTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultTokenThreshold","outputs":[{"internalType":"address","name":"thresholdToken","type":"address"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultVolumeLimit","outputs":[{"internalType":"address","name":"limitToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"accrued","type":"uint256"},{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"nextResetTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalanceConnectors","outputs":[{"internalType":"bytes32","name":"previous","type":"bytes32"},{"internalType":"bytes32","name":"next","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGasLimits","outputs":[{"internalType":"uint256","name":"gasPriceLimit","type":"uint256"},{"internalType":"uint256","name":"priorityFeeLimit","type":"uint256"},{"internalType":"uint256","name":"txCostLimit","type":"uint256"},{"internalType":"uint256","name":"txCostLimitPct","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getTaskAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTimeLock","outputs":[{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"uint256","name":"frequency","type":"uint256"},{"internalType":"uint256","name":"allowedAt","type":"uint256"},{"internalType":"uint256","name":"window","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getTokenThreshold","outputs":[{"internalType":"address","name":"thresholdToken","type":"address"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokensSource","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getVolumeLimit","outputs":[{"internalType":"address","name":"limitToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"accrued","type":"uint256"},{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"nextResetTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"components":[{"internalType":"address","name":"smartVault","type":"address"},{"internalType":"bytes32","name":"previousBalanceConnectorId","type":"bytes32"},{"internalType":"bytes32","name":"nextBalanceConnectorId","type":"bytes32"}],"internalType":"struct BaseTask.BaseConfig","name":"baseConfig","type":"tuple"},{"components":[{"internalType":"uint256","name":"gasPriceLimit","type":"uint256"},{"internalType":"uint256","name":"priorityFeeLimit","type":"uint256"},{"internalType":"uint256","name":"txCostLimit","type":"uint256"},{"internalType":"uint256","name":"txCostLimitPct","type":"uint256"}],"internalType":"struct GasLimitedTask.GasLimitConfig","name":"gasLimitConfig","type":"tuple"},{"components":[{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"uint256","name":"frequency","type":"uint256"},{"internalType":"uint256","name":"allowedAt","type":"uint256"},{"internalType":"uint256","name":"window","type":"uint256"}],"internalType":"struct TimeLockedTask.TimeLockConfig","name":"timeLockConfig","type":"tuple"},{"components":[{"internalType":"enum ITokenIndexedTask.TokensAcceptanceType","name":"acceptanceType","type":"uint8"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"internalType":"struct TokenIndexedTask.TokenIndexConfig","name":"tokenIndexConfig","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"internalType":"struct TokenThresholdTask.Threshold","name":"defaultThreshold","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"internalType":"struct TokenThresholdTask.Threshold","name":"threshold","type":"tuple"}],"internalType":"struct TokenThresholdTask.CustomThresholdConfig[]","name":"customThresholdConfigs","type":"tuple[]"}],"internalType":"struct TokenThresholdTask.TokenThresholdConfig","name":"tokenThresholdConfig","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"period","type":"uint256"}],"internalType":"struct VolumeLimitedTask.VolumeLimitParams","name":"defaultVolumeLimit","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"period","type":"uint256"}],"internalType":"struct VolumeLimitedTask.VolumeLimitParams","name":"volumeLimit","type":"tuple"}],"internalType":"struct VolumeLimitedTask.CustomVolumeLimitConfig[]","name":"customVolumeLimitConfigs","type":"tuple[]"}],"internalType":"struct VolumeLimitedTask.VolumeLimitConfig","name":"volumeLimitConfig","type":"tuple"}],"internalType":"struct Task.TaskConfig","name":"taskConfig","type":"tuple"}],"internalType":"struct Depositor.DepositConfig","name":"config","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"isTokenAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"previous","type":"bytes32"},{"internalType":"bytes32","name":"next","type":"bytes32"}],"name":"setBalanceConnectors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"thresholdToken","type":"address"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"setCustomTokenThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"limitToken","type":"address"},{"internalType":"uint256","name":"limitAmount","type":"uint256"},{"internalType":"uint256","name":"limitPeriod","type":"uint256"}],"name":"setCustomVolumeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"thresholdToken","type":"address"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"setDefaultTokenThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"limitToken","type":"address"},{"internalType":"uint256","name":"limitAmount","type":"uint256"},{"internalType":"uint256","name":"limitPeriod","type":"uint256"}],"name":"setDefaultVolumeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newGasPriceLimit","type":"uint256"},{"internalType":"uint256","name":"newPriorityFeeLimit","type":"uint256"},{"internalType":"uint256","name":"newTxCostLimit","type":"uint256"},{"internalType":"uint256","name":"newTxCostLimitPct","type":"uint256"}],"name":"setGasLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"uint256","name":"frequency","type":"uint256"},{"internalType":"uint256","name":"allowedAt","type":"uint256"},{"internalType":"uint256","name":"window","type":"uint256"}],"name":"setTimeLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"bool[]","name":"added","type":"bool[]"}],"name":"setTokensAcceptanceList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum ITokenIndexedTask.TokensAcceptanceType","name":"newTokensAcceptanceType","type":"uint8"}],"name":"setTokensAcceptanceType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"smartVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensAcceptanceType","outputs":[{"internalType":"enum ITokenIndexedTask.TokensAcceptanceType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
BSC | 99.98% | $0.004571 | 208,254,079,582,202.97 | $951,957,622,076.81 | |
BSC | 0.02% | $0.009053 | 20,274,739,394.5902 | $183,537,078.37 | |
BSC | <0.01% | $0.004571 | 8,330,892,343.0911 | $38,081,637.97 | |
BSC | <0.01% | $1.17 | 27,792.5228 | $32,517.25 | |
BSC | <0.01% | $115.47 | 165.7413 | $19,138.15 | |
BSC | <0.01% | $2.83 | 603.7784 | $1,709.01 | |
BSC | <0.01% | $688.93 | 2.0823 | $1,434.54 | |
BSC | <0.01% | $0.998941 | 1,358.5504 | $1,357.11 | |
BSC | <0.01% | $0.000304 | 4,035,922.6502 | $1,227.69 | |
BSC | <0.01% | $0.000324 | 3,477,392.2093 | $1,128.17 | |
BSC | <0.01% | $0.051477 | 7,896.5897 | $406.49 | |
BSC | <0.01% | $9.75 | 39.9724 | $389.92 | |
BSC | <0.01% | $0.033182 | 11,322.7018 | $375.71 | |
BSC | <0.01% | <$0.000001 | 3,768,904,437.3191 | $367.28 | |
BSC | <0.01% | $0.031525 | 9,487.3399 | $299.09 | |
BSC | <0.01% | $0.291995 | 951.5002 | $277.83 | |
BSC | <0.01% | <$0.000001 | 128,268,536,374.6682 | $277.44 | |
BSC | <0.01% | <$0.000001 | 61,102,783,530.7671 | $252.9 | |
BSC | <0.01% | $3.09 | 63.1993 | $195.11 | |
BSC | <0.01% | $102,331.08 | 0.00188846 | $193.25 | |
BSC | <0.01% | $0.039863 | 4,803.5256 | $191.48 | |
BSC | <0.01% | $0.000001 | 262,980,975.0301 | $191.29 | |
BSC | <0.01% | $0.002696 | 67,435.4325 | $181.83 | |
BSC | <0.01% | $0.000316 | 515,100.3665 | $162.72 | |
BSC | <0.01% | $0.678396 | 234.6065 | $159.16 | |
BSC | <0.01% | $0.113569 | 1,300.7827 | $147.73 | |
BSC | <0.01% | $0.100674 | 1,362.8514 | $137.2 | |
BSC | <0.01% | $0.56741 | 240.8651 | $136.67 | |
BSC | <0.01% | $5.01 | 25.7635 | $128.97 | |
BSC | <0.01% | $1 | 124.0237 | $124.04 | |
BSC | <0.01% | $0.034387 | 3,181.0425 | $109.39 | |
BSC | <0.01% | $0.444069 | 225.9985 | $100.36 | |
BSC | <0.01% | $26.11 | 3.7999 | $99.21 | |
BSC | <0.01% | $0.343442 | 288.4429 | $99.06 | |
BSC | <0.01% | $1.14 | 86.0269 | $97.68 | |
BSC | <0.01% | $0.000061 | 1,528,809.78 | $93.52 | |
BSC | <0.01% | $3,281.28 | 0.0285 | $93.46 | |
BSC | <0.01% | $7,725.17 | 0.012 | $92.68 | |
BSC | <0.01% | $0.329368 | 280.3665 | $92.34 | |
BSC | <0.01% | $0.045997 | 1,949.469 | $89.67 | |
BSC | <0.01% | $0.000697 | 127,739.8677 | $89.02 | |
BSC | <0.01% | <$0.000001 | 118,212,112,827.5825 | $88.12 | |
BSC | <0.01% | $0.010596 | 8,312.3683 | $88.08 | |
BSC | <0.01% | $0.690404 | 127.3046 | $87.89 | |
BSC | <0.01% | $304.82 | 0.2854 | $87 | |
BSC | <0.01% | $0.300605 | 285.1977 | $85.73 | |
BSC | <0.01% | $0.095307 | 895.3 | $85.33 | |
BSC | <0.01% | $0.522958 | 159.7194 | $83.53 | |
BSC | <0.01% | $3.7 | 22.2801 | $82.44 | |
BSC | <0.01% | $0.014952 | 5,498.6376 | $82.21 | |
BSC | <0.01% | $13.32 | 6.1569 | $82.01 | |
BSC | <0.01% | $0.016387 | 4,945.7151 | $81.04 | |
BSC | <0.01% | $0.999845 | 78.7331 | $78.72 | |
BSC | <0.01% | $0.010306 | 7,468.0604 | $76.97 | |
BSC | <0.01% | $1.25 | 60.4994 | $75.61 | |
BSC | <0.01% | $0.011109 | 6,800.6481 | $75.55 | |
BSC | <0.01% | $245.43 | 0.3069 | $75.31 | |
BSC | <0.01% | $0.075533 | 994.615 | $75.13 | |
BSC | <0.01% | $1.78 | 41.9981 | $74.76 | |
BSC | <0.01% | $0.000001 | 75,786,661.8658 | $74.39 | |
BSC | <0.01% | $0.999983 | 74.225 | $74.22 | |
BSC | <0.01% | $0.596939 | 121.9659 | $72.81 | |
BSC | <0.01% | $1.66 | 43.0739 | $71.5 | |
BSC | <0.01% | $0.000155 | 460,606.1548 | $71.26 | |
BSC | <0.01% | $0.232155 | 303.4417 | $70.45 | |
BSC | <0.01% | $0.015864 | 4,390.066 | $69.64 | |
BSC | <0.01% | $0.038636 | 1,780.6945 | $68.8 | |
BSC | <0.01% | $0.021782 | 3,134.2578 | $68.27 | |
BSC | <0.01% | $0.008066 | 8,402.6391 | $67.78 | |
BSC | <0.01% | $0.11051 | 610.2246 | $67.44 | |
BSC | <0.01% | $1.3 | 51.6552 | $67.29 | |
BSC | <0.01% | $0.362085 | 185.6941 | $67.24 | |
BSC | <0.01% | $0.000006 | 11,111,183.7892 | $67.22 | |
BSC | <0.01% | <$0.000001 | 19,456,496,592.7127 | $67.12 | |
BSC | <0.01% | <$0.000001 | 6,070,785,926.8503 | $66.78 | |
BSC | <0.01% | $0.084954 | 777.1543 | $66.02 | |
BSC | <0.01% | $8.67 | 7.6064 | $65.94 | |
BSC | <0.01% | <$0.000001 | 138,208,566.4442 | $65.84 | |
BSC | <0.01% | $0.066121 | 986.3829 | $65.22 | |
BSC | <0.01% | $7.73 | 8.3796 | $64.77 | |
BSC | <0.01% | <$0.000001 | 1,547,362,345.7344 | $64.5 | |
BSC | <0.01% | $0.026314 | 2,446.8609 | $64.39 | |
BSC | <0.01% | $0.019974 | 3,218.359 | $64.28 | |
BSC | <0.01% | $0.028446 | 2,238.1368 | $63.67 | |
BSC | <0.01% | $0.795153 | 79.8079 | $63.46 | |
BSC | <0.01% | $18.1 | 3.5053 | $63.45 | |
BSC | <0.01% | $0.000352 | 179,631.0583 | $63.32 | |
BSC | <0.01% | $0.37893 | 166.4558 | $63.08 | |
BSC | <0.01% | $0.006446 | 9,669.0767 | $62.33 | |
BSC | <0.01% | $5.99 | 10.3987 | $62.26 | |
BSC | <0.01% | $1.22 | 50.7978 | $61.97 | |
BSC | <0.01% | $24.39 | 2.5311 | $61.73 | |
BSC | <0.01% | $39.19 | 1.5557 | $60.97 | |
BSC | <0.01% | $0.207552 | 289.7305 | $60.13 | |
BSC | <0.01% | $0.009325 | 6,431.5698 | $59.98 | |
BSC | <0.01% | $4.94 | 12.122 | $59.88 | |
BSC | <0.01% | $0.043032 | 1,363.0722 | $58.66 | |
BSC | <0.01% | $0.319832 | 183.2752 | $58.62 | |
BSC | <0.01% | $0.496074 | 117.113 | $58.1 | |
BSC | <0.01% | $0.004541 | 12,774.5281 | $58.01 | |
BSC | <0.01% | $0.021426 | 2,706.62 | $57.99 | |
BSC | <0.01% | $0.119979 | 482.1935 | $57.85 | |
BSC | <0.01% | $0.000363 | 157,693.2668 | $57.17 | |
BSC | <0.01% | $0.256224 | 223.084 | $57.16 | |
BSC | <0.01% | $0.029495 | 1,928.0973 | $56.87 | |
BSC | <0.01% | $26.08 | 2.1804 | $56.86 | |
BSC | <0.01% | $2.93 | 19.2655 | $56.46 | |
BSC | <0.01% | $0.060497 | 921.1065 | $55.72 | |
BSC | <0.01% | $11.41 | 4.8438 | $55.25 | |
BSC | <0.01% | $0.10404 | 527.269 | $54.86 | |
BSC | <0.01% | $0.001014 | 53,902.5712 | $54.64 | |
BSC | <0.01% | $0.147657 | 367.4755 | $54.26 | |
BSC | <0.01% | $0.742098 | 72.7204 | $53.97 | |
BSC | <0.01% | $1.17 | 46.2272 | $53.93 | |
BSC | <0.01% | $0.003961 | 13,520.4766 | $53.56 | |
BSC | <0.01% | $0.026657 | 1,995.1891 | $53.19 | |
BSC | <0.01% | $2.78 | 19.1278 | $53.09 | |
BSC | <0.01% | $0.000237 | 223,013.8764 | $52.95 | |
BSC | <0.01% | $0.072483 | 728.3623 | $52.79 | |
BSC | <0.01% | $0.202198 | 260.6665 | $52.71 | |
BSC | <0.01% | $0.005033 | 10,423.5764 | $52.47 | |
BSC | <0.01% | $1.24 | 42.156 | $52.13 | |
BSC | <0.01% | $1.21 | 42.825 | $52 | |
BSC | <0.01% | $0.008264 | 6,227.0626 | $51.46 | |
BSC | <0.01% | $0.042824 | 1,194.9577 | $51.17 | |
BSC | <0.01% | $0.000029 | 1,753,060.5847 | $51.08 | |
BSC | <0.01% | <$0.000001 | 45,165,450,256.5283 | $50.86 | |
BSC | <0.01% | <$0.000001 | 2,846,591,788,603.0757 | $50.22 | |
BSC | <0.01% | $0.59031 | 84.7625 | $50.04 | |
BSC | <0.01% | $0.049778 | 1,002.2492 | $49.89 | |
BSC | <0.01% | $0.096846 | 510.8378 | $49.47 | |
BSC | <0.01% | $0.106598 | 461.9301 | $49.24 | |
BSC | <0.01% | $4.17 | 11.7643 | $49.06 | |
BSC | <0.01% | $0.041497 | 1,171.7197 | $48.62 | |
BSC | <0.01% | $0.000034 | 1,429,375.2664 | $48.1 | |
BSC | <0.01% | $0.006865 | 6,999.2734 | $48.05 | |
BSC | <0.01% | $0.759858 | 63.0212 | $47.89 | |
BSC | <0.01% | $0.074503 | 637.9984 | $47.53 | |
BSC | <0.01% | $0.444149 | 106.5911 | $47.34 | |
BSC | <0.01% | $0.45046 | 105.0755 | $47.33 | |
BSC | <0.01% | $0.000001 | 44,468,005.3196 | $47.3 | |
BSC | <0.01% | $0.023207 | 2,029.4064 | $47.1 | |
BSC | <0.01% | $0.525601 | 89.2481 | $46.91 | |
BSC | <0.01% | $0.033965 | 1,374.853 | $46.7 | |
BSC | <0.01% | $0.084066 | 553.7458 | $46.55 | |
BSC | <0.01% | $0.009779 | 4,746.9891 | $46.42 | |
BSC | <0.01% | $0.010745 | 4,294.6725 | $46.15 | |
BSC | <0.01% | $0.159632 | 287.9327 | $45.96 | |
BSC | <0.01% | $0.999244 | 45.7748 | $45.74 | |
BSC | <0.01% | $0.262579 | 174.0461 | $45.7 | |
BSC | <0.01% | $0.000837 | 54,547.8419 | $45.67 | |
BSC | <0.01% | $0.151869 | 299.8408 | $45.54 | |
BSC | <0.01% | $0.142685 | 318.2145 | $45.4 | |
BSC | <0.01% | $0.133052 | 340.2559 | $45.27 | |
BSC | <0.01% | $0.042308 | 1,055.2773 | $44.65 | |
BSC | <0.01% | $0.401711 | 110.6894 | $44.47 | |
BSC | <0.01% | $0.079543 | 554.9039 | $44.14 | |
BSC | <0.01% | $758.35 | 0.058 | $43.98 | |
BSC | <0.01% | $0.018927 | 2,318.9203 | $43.89 | |
BSC | <0.01% | $0.000003 | 13,018,195.1814 | $43.87 | |
BSC | <0.01% | $0.058131 | 753.7742 | $43.82 | |
BSC | <0.01% | $0.338951 | 128.8803 | $43.68 | |
BSC | <0.01% | $1.74 | 24.6796 | $42.94 | |
BSC | <0.01% | $0.186292 | 226.4402 | $42.18 | |
BSC | <0.01% | $0.066151 | 634.4698 | $41.97 | |
BSC | <0.01% | $0.011815 | 3,532.2196 | $41.73 | |
BSC | <0.01% | $0.064333 | 645.516 | $41.53 | |
BSC | <0.01% | $0.020379 | 2,033.1173 | $41.43 | |
BSC | <0.01% | $0.000008 | 5,329,045.6345 | $41.3 | |
BSC | <0.01% | $0.000348 | 118,641.314 | $41.23 | |
BSC | <0.01% | $0.106144 | 388.2788 | $41.21 | |
BSC | <0.01% | $0.038144 | 1,076.6414 | $41.07 | |
BSC | <0.01% | <$0.000001 | 2,035,938,804.8461 | $40.49 | |
BSC | <0.01% | $0.009507 | 4,254.4928 | $40.45 | |
BSC | <0.01% | $0.003623 | 11,153.807 | $40.41 | |
BSC | <0.01% | $3.57 | 11.2824 | $40.28 | |
BSC | <0.01% | $2.93 | 13.713 | $40.12 | |
BSC | <0.01% | $0.518929 | 77.1847 | $40.05 | |
BSC | <0.01% | $2.39 | 16.7431 | $40.02 | |
BSC | <0.01% | $0.228161 | 174.5697 | $39.83 | |
BSC | <0.01% | $0.001257 | 31,624.8635 | $39.76 | |
BSC | <0.01% | <$0.000001 | 39,687,630,627.6161 | $39.69 | |
BSC | <0.01% | $0.017414 | 2,275.1827 | $39.62 | |
BSC | <0.01% | $0.183197 | 215.9998 | $39.57 | |
BSC | <0.01% | $0.012666 | 3,104.1907 | $39.32 | |
BSC | <0.01% | $0.808969 | 48.5589 | $39.28 | |
BSC | <0.01% | $0.000776 | 50,369.4385 | $39.1 | |
BSC | <0.01% | $0.000142 | 275,025.7431 | $39.01 | |
BSC | <0.01% | $0.11872 | 327.6461 | $38.9 | |
BSC | <0.01% | $0.000229 | 168,434.7887 | $38.56 | |
BSC | <0.01% | <$0.000001 | 438,690,940.914 | $38.07 | |
BSC | <0.01% | $0.000753 | 50,218.4347 | $37.8 | |
BSC | <0.01% | $16.99 | 2.203 | $37.44 | |
BSC | <0.01% | $0.00703 | 5,318.688 | $37.39 | |
BSC | <0.01% | $0.037401 | 998.7162 | $37.35 | |
BSC | <0.01% | $0.031319 | 1,185.6562 | $37.13 | |
BSC | <0.01% | $0.098363 | 370.7218 | $36.47 | |
BSC | <0.01% | $0.007481 | 4,845.6354 | $36.25 | |
BSC | <0.01% | $0.035383 | 1,021.281 | $36.14 | |
BSC | <0.01% | $2.97 | 12.0948 | $35.87 | |
BSC | <0.01% | $0.18653 | 189.434 | $35.34 | |
BSC | <0.01% | $0.996902 | 35.3437 | $35.23 | |
BSC | <0.01% | $0.066758 | 527.0006 | $35.18 | |
BSC | <0.01% | $0.101265 | 346.8969 | $35.13 | |
BSC | <0.01% | $0.328968 | 106.0393 | $34.88 | |
BSC | <0.01% | $0.162177 | 213.7165 | $34.66 | |
BSC | <0.01% | $0.861899 | 39.8949 | $34.39 | |
BSC | <0.01% | $0.023745 | 1,445.8086 | $34.33 | |
BSC | <0.01% | $7.79 | 4.3942 | $34.21 | |
BSC | <0.01% | $0.104006 | 328.1694 | $34.13 | |
BSC | <0.01% | $2.38 | 14.288 | $34.01 | |
BSC | <0.01% | $0.32947 | 102.9898 | $33.93 | |
BSC | <0.01% | $0.045237 | 749.4885 | $33.9 | |
BSC | <0.01% | $0.022889 | 1,480.713 | $33.89 | |
BSC | <0.01% | <$0.000001 | 1,425,069,507.7438 | $33.85 | |
BSC | <0.01% | $0.000186 | 181,443.8653 | $33.77 | |
BSC | <0.01% | <$0.000001 | 56,166,163,960.5096 | $33.51 | |
BSC | <0.01% | $0.000539 | 62,219.9349 | $33.51 | |
BSC | <0.01% | <$0.000001 | 70,232,619.4559 | $33.46 | |
BSC | <0.01% | $0.206382 | 161.5912 | $33.35 | |
BSC | <0.01% | $1.4 | 23.6403 | $33.1 | |
BSC | <0.01% | $0.012242 | 2,679.1961 | $32.8 | |
BSC | <0.01% | $1.04 | 31.3461 | $32.57 | |
BSC | <0.01% | $3.27 | 9.9409 | $32.51 | |
BSC | <0.01% | $0.088904 | 365.1748 | $32.47 | |
BSC | <0.01% | $0.004488 | 7,214.543 | $32.38 | |
BSC | <0.01% | $0.004429 | 7,170.0188 | $31.76 | |
BSC | <0.01% | $0.016623 | 1,907.4952 | $31.71 | |
BSC | <0.01% | $0.513156 | 61.5659 | $31.59 | |
BSC | <0.01% | $0.000115 | 274,178.4671 | $31.41 | |
BSC | <0.01% | $0.000193 | 160,720.0064 | $31.05 | |
BSC | <0.01% | $0.000589 | 52,634.7934 | $31.03 | |
BSC | <0.01% | <$0.000001 | 251,237,557.201 | $31.01 | |
BSC | <0.01% | $0.000676 | 45,615.9461 | $30.86 | |
BSC | <0.01% | $0.000021 | 1,493,729.5989 | $30.77 | |
BSC | <0.01% | $0.000229 | 134,495.5023 | $30.76 | |
BSC | <0.01% | $1.08 | 28.3584 | $30.71 | |
BSC | <0.01% | $0.00624 | 4,915.3983 | $30.67 | |
BSC | <0.01% | $0.003457 | 8,812.3518 | $30.46 | |
BSC | <0.01% | $0.00779 | 3,905.57 | $30.42 | |
BSC | <0.01% | $0.135514 | 224.4315 | $30.41 | |
BSC | <0.01% | <$0.000001 | 2,247,845,603.7477 | $30.37 | |
BSC | <0.01% | $0.008623 | 3,517.882 | $30.34 | |
BSC | <0.01% | <$0.000001 | 5,148,302,770.9579 | $30.03 | |
BSC | <0.01% | $0.000036 | 838,813.809 | $29.97 | |
BSC | <0.01% | $0.029104 | 1,028.0302 | $29.92 | |
BSC | <0.01% | $0.000092 | 324,257.9528 | $29.82 | |
BSC | <0.01% | $0.000002 | 17,227,468.6309 | $29.8 | |
BSC | <0.01% | $0.391842 | 75.0816 | $29.42 | |
BSC | <0.01% | $0.00001 | 2,787,435.2329 | $29.16 | |
BSC | <0.01% | <$0.000001 | 3,556,450,410.732 | $28.92 | |
BSC | <0.01% | $1.49 | 19.353 | $28.78 | |
BSC | <0.01% | <$0.000001 | 71,653,981,913.7681 | $28.66 | |
BSC | <0.01% | $0.070792 | 403.1164 | $28.54 | |
BSC | <0.01% | $0.454284 | 62.3463 | $28.32 | |
BSC | <0.01% | $0.008116 | 3,437.9609 | $27.9 | |
BSC | <0.01% | $0.000161 | 173,225.4408 | $27.89 | |
BSC | <0.01% | $0.000777 | 35,853.8658 | $27.84 | |
BSC | <0.01% | $0.999012 | 27.7483 | $27.72 | |
BSC | <0.01% | $0.000087 | 319,816.1917 | $27.71 | |
BSC | <0.01% | $0.158119 | 174.2288 | $27.55 | |
BSC | <0.01% | $0.018038 | 1,521.1061 | $27.44 | |
BSC | <0.01% | $0.00375 | 7,284.7605 | $27.32 | |
BSC | <0.01% | $0.342781 | 79.661 | $27.31 | |
BSC | <0.01% | $0.000034 | 804,619.216 | $27.11 | |
BSC | <0.01% | $0.086229 | 310.8001 | $26.8 | |
BSC | <0.01% | $0.005224 | 5,120.9222 | $26.75 | |
BSC | <0.01% | $1,314.15 | 0.0203 | $26.74 | |
BSC | <0.01% | <$0.000001 | 6,847,847,602.0121 | $26.67 | |
BSC | <0.01% | $0.019843 | 1,343.8158 | $26.66 | |
BSC | <0.01% | $0.170686 | 155.7341 | $26.58 | |
BSC | <0.01% | $0.025152 | 1,050.3038 | $26.42 | |
BSC | <0.01% | <$0.000001 | 225,903,818,986.8381 | $26.3 | |
BSC | <0.01% | $0.050451 | 521.2835 | $26.3 | |
BSC | <0.01% | $0.00052 | 50,558.2112 | $26.27 | |
BSC | <0.01% | <$0.000001 | 167,566,829.7807 | $26.24 | |
BSC | <0.01% | $0.016227 | 1,612.2085 | $26.16 | |
BSC | <0.01% | $0.003692 | 7,045.8832 | $26.01 | |
BSC | <0.01% | $0.000791 | 32,596.1186 | $25.79 | |
BSC | <0.01% | $0.000014 | 1,779,189.9045 | $25.76 | |
BSC | <0.01% | $0.002451 | 10,401.2129 | $25.49 | |
BSC | <0.01% | <$0.000001 | 2,379,281,372,945.2227 | $25.32 | |
BSC | <0.01% | $0.015107 | 1,663.0704 | $25.12 | |
BSC | <0.01% | $0.074868 | 331.0513 | $24.79 | |
BSC | <0.01% | $0.188451 | 131.0439 | $24.7 | |
BSC | <0.01% | $0.000001 | 34,478,211.0943 | $24.69 | |
BSC | <0.01% | $20.64 | 1.1692 | $24.13 | |
BSC | <0.01% | $0.028571 | 839.8236 | $23.99 | |
BSC | <0.01% | $0.002203 | 10,872.4271 | $23.95 | |
BSC | <0.01% | $0.060797 | 393.1268 | $23.9 | |
BSC | <0.01% | $0.033059 | 721.4876 | $23.85 | |
BSC | <0.01% | $0.665901 | 35.6478 | $23.74 | |
BSC | <0.01% | $0.021006 | 1,125.1183 | $23.63 | |
BSC | <0.01% | $0.054965 | 428.3191 | $23.54 | |
BSC | <0.01% | $0.025229 | 928.4168 | $23.42 | |
BSC | <0.01% | $0.182505 | 128.0085 | $23.36 | |
BSC | <0.01% | $0.000333 | 68,813.996 | $22.89 | |
BSC | <0.01% | $0.004506 | 5,058.9535 | $22.8 | |
BSC | <0.01% | $0.000692 | 32,851.8224 | $22.74 | |
BSC | <0.01% | $5.03 | 4.51 | $22.69 | |
BSC | <0.01% | $0.047974 | 471.6392 | $22.63 | |
BSC | <0.01% | $0.059122 | 382.2152 | $22.6 | |
BSC | <0.01% | $0.000005 | 4,887,358.9634 | $22.48 | |
BSC | <0.01% | $2.36 | 9.4673 | $22.32 | |
BSC | <0.01% | <$0.000001 | 5,229,840,340,270.6113 | $22.14 | |
BSC | <0.01% | $0.129716 | 168.7837 | $21.89 | |
BSC | <0.01% | $2 | 10.8545 | $21.71 | |
BSC | <0.01% | $0.003463 | 6,253.752 | $21.66 | |
BSC | <0.01% | $0.003722 | 5,815.4224 | $21.64 | |
BSC | <0.01% | $0.000182 | 118,264.907 | $21.54 | |
BSC | <0.01% | $0.093128 | 231.335 | $21.54 | |
BSC | <0.01% | $0.195099 | 109.5855 | $21.38 | |
BSC | <0.01% | $0.026491 | 806.735 | $21.37 | |
BSC | <0.01% | $0.399183 | 53.0224 | $21.17 | |
BSC | <0.01% | $0.173298 | 121.1657 | $21 | |
BSC | <0.01% | $0.322219 | 65.0678 | $20.97 | |
BSC | <0.01% | <$0.000001 | 100,080,143.8369 | $20.9 | |
BSC | <0.01% | $0.000231 | 90,080.5865 | $20.84 | |
BSC | <0.01% | $0.004097 | 5,017.915 | $20.56 | |
BSC | <0.01% | $0.018756 | 1,094.3593 | $20.53 | |
BSC | <0.01% | $0.678562 | 30.135 | $20.45 | |
BSC | <0.01% | $0.003436 | 5,873.293 | $20.18 | |
BSC | <0.01% | $0.074867 | 269.4306 | $20.17 | |
BSC | <0.01% | $0.997062 | 19.8814 | $19.82 | |
BSC | <0.01% | $2.97 | 6.673 | $19.82 | |
BSC | <0.01% | $1.69 | 11.719 | $19.81 | |
BSC | <0.01% | <$0.000001 | 67,137,467.8042 | $19.57 | |
BSC | <0.01% | $0.004125 | 4,745.2629 | $19.57 | |
BSC | <0.01% | $0.000189 | 103,480.3357 | $19.53 | |
BSC | <0.01% | $0.058392 | 331.8409 | $19.38 | |
BSC | <0.01% | $0.003099 | 6,226.0438 | $19.29 | |
BSC | <0.01% | <$0.000001 | 129,943,242.608 | $19.24 | |
BSC | <0.01% | $0.047933 | 390.5123 | $18.72 | |
BSC | <0.01% | $0.548524 | 34.0987 | $18.7 | |
BSC | <0.01% | $0.000461 | 40,553.4375 | $18.68 | |
BSC | <0.01% | $0.017334 | 1,075.4898 | $18.64 | |
BSC | <0.01% | <$0.000001 | 60,301,758,562.9163 | $18.63 | |
BSC | <0.01% | $0.060427 | 307.3603 | $18.57 | |
BSC | <0.01% | <$0.000001 | 18,699,233,526.113 | $18.57 | |
BSC | <0.01% | $0.011807 | 1,556.0896 | $18.37 | |
BSC | <0.01% | $0.023293 | 765.8539 | $17.84 | |
BSC | <0.01% | <$0.000001 | 49,098,576,548.6487 | $17.8 | |
BSC | <0.01% | $0.047142 | 376.936 | $17.77 | |
BSC | <0.01% | $0.000213 | 83,123.2489 | $17.69 | |
BSC | <0.01% | $0.446107 | 39.5472 | $17.64 | |
BSC | <0.01% | $0.004434 | 3,962.1267 | $17.57 | |
BSC | <0.01% | $0.003964 | 4,427.8931 | $17.55 | |
BSC | <0.01% | $0.000665 | 26,345.4384 | $17.51 | |
BSC | <0.01% | $0.001417 | 12,297.2231 | $17.42 | |
BSC | <0.01% | $0.000027 | 634,246.1959 | $17.41 | |
BSC | <0.01% | $0.002135 | 8,151.5588 | $17.4 | |
BSC | <0.01% | $0.000467 | 37,217.4978 | $17.37 | |
BSC | <0.01% | $0.223446 | 77.7058 | $17.36 | |
BSC | <0.01% | $1.83 | 9.4762 | $17.34 | |
BSC | <0.01% | $0.002669 | 6,471.5672 | $17.27 | |
BSC | <0.01% | <$0.000001 | 25,018,674,024.6472 | $17.23 | |
BSC | <0.01% | <$0.000001 | 2,188,975,933,671.4365 | $17.14 | |
BSC | <0.01% | $0.624057 | 27.3308 | $17.06 | |
BSC | <0.01% | $0.00064 | 26,662.7985 | $17.05 | |
BSC | <0.01% | $0.000091 | 187,445.9274 | $17 | |
BSC | <0.01% | $0.000219 | 77,326.8073 | $16.96 | |
BSC | <0.01% | <$0.000001 | 1,211,850,092.1955 | $16.95 | |
BSC | <0.01% | $6.36 | 2.6576 | $16.91 | |
BSC | <0.01% | $1.32 | 12.7332 | $16.81 | |
BSC | <0.01% | $0.003729 | 4,503.4288 | $16.79 | |
BSC | <0.01% | $0.057759 | 289.1584 | $16.7 | |
BSC | <0.01% | $0.00631 | 2,635.4964 | $16.63 | |
BSC | <0.01% | $0.000442 | 37,552.5018 | $16.58 | |
BSC | <0.01% | $0.998405 | 16.5985 | $16.57 | |
BSC | <0.01% | $81.87 | 0.2019 | $16.53 | |
BSC | <0.01% | <$0.000001 | 4,133,369,270.0201 | $16.33 | |
BSC | <0.01% | $0.034649 | 470.9618 | $16.32 | |
BSC | <0.01% | $0.000029 | 568,968.7692 | $16.29 | |
BSC | <0.01% | $0.468084 | 34.6539 | $16.22 | |
BSC | <0.01% | $0.99516 | 16.1824 | $16.1 | |
BSC | <0.01% | $0.007932 | 2,004.1473 | $15.9 | |
BSC | <0.01% | $0.826722 | 18.9451 | $15.66 | |
BSC | <0.01% | $116.34 | 0.1334 | $15.53 | |
BSC | <0.01% | $0.909163 | 17.0573 | $15.51 | |
BSC | <0.01% | <$0.000001 | 6,252,254,017.4027 | $15.3 | |
BSC | <0.01% | $0.254723 | 59.8047 | $15.23 | |
BSC | <0.01% | $0.035971 | 421.779 | $15.17 | |
BSC | <0.01% | <$0.000001 | 42,851,965.4405 | $15.11 | |
BSC | <0.01% | <$0.000001 | 8,789,872,354.7045 | $15.08 | |
BSC | <0.01% | $0.000016 | 952,470.5494 | $15 | |
BSC | <0.01% | $0.007865 | 1,879.4465 | $14.78 | |
BSC | <0.01% | $0.01514 | 956.1219 | $14.48 | |
BSC | <0.01% | $0.871471 | 16.5907 | $14.46 | |
BSC | <0.01% | $0.782276 | 18.422 | $14.41 | |
BSC | <0.01% | $0.025069 | 574.4234 | $14.4 | |
BSC | <0.01% | $0.898009 | 15.8635 | $14.25 | |
BSC | <0.01% | $0.01181 | 1,205.5007 | $14.24 | |
BSC | <0.01% | $0.00065 | 21,788.8328 | $14.16 | |
BSC | <0.01% | $0.178134 | 79.4246 | $14.15 | |
BSC | <0.01% | $0.00031 | 45,219.3069 | $14.04 | |
BSC | <0.01% | $0.008067 | 1,732.6902 | $13.98 | |
BSC | <0.01% | $0.176291 | 78.2438 | $13.79 | |
BSC | <0.01% | $317.43 | 0.0434 | $13.78 | |
BSC | <0.01% | $0.000266 | 51,638.1952 | $13.73 | |
BSC | <0.01% | $0.840201 | 16.2902 | $13.69 | |
BSC | <0.01% | <$0.000001 | 59,336,524.6332 | $13.64 | |
BSC | <0.01% | $0.001471 | 9,260.0793 | $13.63 | |
BSC | <0.01% | $0.076406 | 177.4102 | $13.56 | |
BSC | <0.01% | $0.001086 | 12,485.2436 | $13.55 | |
BSC | <0.01% | $0.017386 | 774.3808 | $13.46 | |
BSC | <0.01% | $0.087299 | 153.7928 | $13.43 | |
BSC | <0.01% | $0.047641 | 280.1116 | $13.34 | |
BSC | <0.01% | $0.001495 | 8,870.4276 | $13.26 | |
BSC | <0.01% | $1.07 | 12.3092 | $13.17 | |
BSC | <0.01% | $0.020508 | 636.2579 | $13.05 | |
BSC | <0.01% | $0.086029 | 151.2404 | $13.01 | |
BSC | <0.01% | $0.004424 | 2,925.6358 | $12.94 | |
BSC | <0.01% | $0.001832 | 7,024.2967 | $12.87 | |
BSC | <0.01% | $0.632415 | 20.2595 | $12.81 | |
BSC | <0.01% | $0.000388 | 32,916.3466 | $12.77 | |
BSC | <0.01% | $0.031467 | 404.6699 | $12.73 | |
BSC | <0.01% | $0.008696 | 1,459.8291 | $12.7 | |
BSC | <0.01% | <$0.000001 | 12,660,137,395,676,246,000 | $12.66 | |
BSC | <0.01% | $0.000619 | 20,410.5075 | $12.64 | |
BSC | <0.01% | $0.000609 | 20,730.0625 | $12.63 | |
BSC | <0.01% | $0.041103 | 303.5037 | $12.47 | |
BSC | <0.01% | <$0.000001 | 7,147,658,662.5497 | $12.27 | |
BSC | <0.01% | <$0.000001 | 38,796,325,871.4071 | $12.08 | |
BSC | <0.01% | $0.027535 | 436.7728 | $12.03 | |
BSC | <0.01% | <$0.000001 | 20,409,081,492.2871 | $12 | |
BSC | <0.01% | $5.35 | 2.242 | $11.99 | |
BSC | <0.01% | $432.3 | 0.0277 | $11.97 | |
BSC | <0.01% | $0.000875 | 13,442.3116 | $11.77 | |
BSC | <0.01% | $0.009396 | 1,241.5936 | $11.67 | |
BSC | <0.01% | $0.33808 | 34.4279 | $11.64 | |
BSC | <0.01% | $0.000098 | 118,685.7418 | $11.63 | |
BSC | <0.01% | $0.007905 | 1,463.7034 | $11.57 | |
BSC | <0.01% | $0.010059 | 1,150.1004 | $11.57 | |
BSC | <0.01% | $0.140114 | 82.1999 | $11.52 | |
BSC | <0.01% | $0.002451 | 4,632.4695 | $11.35 | |
BSC | <0.01% | $0.002799 | 3,990.9996 | $11.17 | |
BSC | <0.01% | $17.29 | 0.6459 | $11.17 | |
BSC | <0.01% | $0.000153 | 72,420.0061 | $11.06 | |
BSC | <0.01% | $0.000086 | 125,826.0833 | $10.81 | |
BSC | <0.01% | $3.24 | 3.319 | $10.74 | |
BSC | <0.01% | $0.000021 | 498,879.9147 | $10.68 | |
BSC | <0.01% | $0.110608 | 93.6196 | $10.36 | |
BSC | <0.01% | $0.000704 | 14,714.0641 | $10.35 | |
BSC | <0.01% | $0.000477 | 21,639.8496 | $10.33 | |
BSC | <0.01% | $0.000002 | 5,581,896.5011 | $10.27 | |
BSC | <0.01% | $0.021726 | 468.1334 | $10.17 | |
BSC | <0.01% | $0.028905 | 351.1828 | $10.15 | |
BSC | <0.01% | $0.031117 | 324.7946 | $10.11 | |
BSC | <0.01% | $40.88 | 0.2462 | $10.06 | |
BSC | <0.01% | $0.030777 | 325.9064 | $10.03 | |
BSC | <0.01% | $0.073527 | 136.2963 | $10.02 | |
BSC | <0.01% | $0.001651 | 6,061.0024 | $10.01 | |
BSC | <0.01% | $0.001496 | 6,662.8567 | $9.97 | |
BSC | <0.01% | $0.000028 | 354,595.9141 | $9.94 | |
BSC | <0.01% | $3.33 | 2.9798 | $9.92 | |
BSC | <0.01% | $1.76 | 5.5861 | $9.86 | |
BSC | <0.01% | $0.00403 | 2,441.0596 | $9.84 | |
BSC | <0.01% | $0.025565 | 379.7199 | $9.71 | |
BSC | <0.01% | $0.005712 | 1,695.812 | $9.69 | |
BSC | <0.01% | $0.001048 | 9,196.673 | $9.63 | |
BSC | <0.01% | <$0.000001 | 3,632,540,440.7759 | $9.5 | |
BSC | <0.01% | $0.003281 | 2,882.2072 | $9.46 | |
BSC | <0.01% | $47.8 | 0.1927 | $9.21 | |
BSC | <0.01% | $0.010871 | 846.5587 | $9.2 | |
BSC | <0.01% | $0.012096 | 759.1568 | $9.18 | |
BSC | <0.01% | $0.01564 | 586.7189 | $9.18 | |
BSC | <0.01% | <$0.000001 | 2,471,330,302.717 | $9.11 | |
BSC | <0.01% | $0.000876 | 10,384.0395 | $9.1 | |
BSC | <0.01% | $2.52 | 3.6025 | $9.08 | |
BSC | <0.01% | $0.007147 | 1,269.1706 | $9.07 | |
BSC | <0.01% | $0.000151 | 59,103.2986 | $8.91 | |
BSC | <0.01% | $3,286.54 | 0.00269232 | $8.85 | |
BSC | <0.01% | $0.000096 | 91,247.3122 | $8.74 | |
BSC | <0.01% | $0.012885 | 669.9118 | $8.63 | |
BSC | <0.01% | $0.000386 | 22,267.6734 | $8.59 | |
BSC | <0.01% | $0.015477 | 550.6424 | $8.52 | |
BSC | <0.01% | $0.058918 | 141.2055 | $8.32 | |
BSC | <0.01% | $0.150861 | 54.1698 | $8.17 | |
BSC | <0.01% | $0.0001 | 81,274.8755 | $8.16 | |
BSC | <0.01% | $0.062772 | 124.7467 | $7.83 | |
BSC | <0.01% | $6.32 | 1.2384 | $7.82 | |
BSC | <0.01% | $0.039725 | 195.5777 | $7.77 | |
BSC | <0.01% | $0.000003 | 2,728,134.8657 | $7.61 | |
BSC | <0.01% | $0.002329 | 3,235.4165 | $7.53 | |
BSC | <0.01% | $0.152561 | 49.3418 | $7.53 | |
BSC | <0.01% | <$0.000001 | 8,699,058,800,124.8867 | $7.53 | |
BSC | <0.01% | $0.022443 | 334.4557 | $7.51 | |
BSC | <0.01% | $0.000479 | 15,486.7872 | $7.41 | |
BSC | <0.01% | $0.045653 | 161.7363 | $7.38 | |
BSC | <0.01% | $0.005928 | 1,241.6494 | $7.36 | |
BSC | <0.01% | $0.194153 | 37.878 | $7.35 | |
BSC | <0.01% | $0.000098 | 74,104.9299 | $7.28 | |
BSC | <0.01% | $0.0002 | 36,288.1792 | $7.24 | |
BSC | <0.01% | $0.00159 | 4,534.3735 | $7.21 | |
BSC | <0.01% | <$0.000001 | 142,539,558.5011 | $7.16 | |
BSC | <0.01% | $0.026564 | 267.4862 | $7.11 | |
BSC | <0.01% | $0.003711 | 1,852.7227 | $6.88 | |
BSC | <0.01% | $0.011985 | 571.8318 | $6.85 | |
BSC | <0.01% | $0.133304 | 51.2538 | $6.83 | |
BSC | <0.01% | $0.002112 | 3,233.9876 | $6.83 | |
BSC | <0.01% | $8.03 | 0.8382 | $6.73 | |
BSC | <0.01% | $0.007403 | 909.1535 | $6.73 | |
BSC | <0.01% | $0.000716 | 9,372.8067 | $6.71 | |
BSC | <0.01% | $0.003998 | 1,675.9889 | $6.7 | |
BSC | <0.01% | $0.001213 | 5,502.3766 | $6.67 | |
BSC | <0.01% | $0.303707 | 21.878 | $6.64 | |
BSC | <0.01% | $17.17 | 0.3864 | $6.63 | |
BSC | <0.01% | $0.048278 | 136.9572 | $6.61 | |
BSC | <0.01% | $0.000019 | 346,642.9164 | $6.5 | |
BSC | <0.01% | $0.019368 | 335.5413 | $6.5 | |
BSC | <0.01% | $0.158119 | 41.0428 | $6.49 | |
BSC | <0.01% | $0.000377 | 17,184.0967 | $6.48 | |
BSC | <0.01% | $0.000006 | 1,092,568.2083 | $6.36 | |
BSC | <0.01% | $9.15 | 0.6941 | $6.35 | |
BSC | <0.01% | $0.000473 | 13,407.2978 | $6.34 | |
BSC | <0.01% | $0.00008 | 78,941.9074 | $6.29 | |
BSC | <0.01% | $13.41 | 0.4656 | $6.24 | |
BSC | <0.01% | $0.359408 | 17.3241 | $6.23 | |
BSC | <0.01% | $0.003529 | 1,754.4063 | $6.19 | |
BSC | <0.01% | $0.002013 | 3,069.9542 | $6.18 | |
BSC | <0.01% | $0.000312 | 19,700.6908 | $6.15 | |
BSC | <0.01% | <$0.000001 | 7,590,126,566.7278 | $6.14 | |
BSC | <0.01% | $0.000313 | 19,524.9373 | $6.11 | |
BSC | <0.01% | $0.005104 | 1,185.4753 | $6.05 | |
BSC | <0.01% | $0.022074 | 273.9641 | $6.05 | |
BSC | <0.01% | $1.01 | 5.9416 | $5.97 | |
BSC | <0.01% | $0.002573 | 2,293.729 | $5.9 | |
BSC | <0.01% | $0.018029 | 327.0513 | $5.9 | |
BSC | <0.01% | $0.000614 | 9,606.4513 | $5.89 | |
BSC | <0.01% | $0.000018 | 329,959.5078 | $5.83 | |
BSC | <0.01% | $0.001841 | 3,138.7223 | $5.78 | |
BSC | <0.01% | $0.001834 | 3,144.1711 | $5.77 | |
BSC | <0.01% | $0.00008 | 70,160.192 | $5.64 | |
BSC | <0.01% | $0.133389 | 42.0935 | $5.61 | |
BSC | <0.01% | $0.005392 | 1,039.1489 | $5.6 | |
BSC | <0.01% | $0.000625 | 8,935.0506 | $5.59 | |
BSC | <0.01% | $0.004735 | 1,177.0066 | $5.57 | |
BSC | <0.01% | $0.000003 | 2,083,010.643 | $5.56 | |
BSC | <0.01% | $5.83 | 0.9537 | $5.56 | |
BSC | <0.01% | $0.282603 | 19.656 | $5.55 | |
BSC | <0.01% | $0.000285 | 19,193.0744 | $5.48 | |
BSC | <0.01% | $0.000016 | 341,252.3225 | $5.43 | |
BSC | <0.01% | $0.000531 | 10,147.8763 | $5.39 | |
BSC | <0.01% | $0.00007 | 76,099.2842 | $5.35 | |
BSC | <0.01% | $0.222578 | 23.9668 | $5.33 | |
BSC | <0.01% | $0.002343 | 2,220.4256 | $5.2 | |
BSC | <0.01% | $0.004731 | 1,074.1206 | $5.08 | |
BSC | <0.01% | $0.008703 | 583.2764 | $5.08 | |
BSC | <0.01% | $0.009988 | 502.0467 | $5.01 | |
BSC | <0.01% | $0.000078 | 63,937.9605 | $4.99 | |
BSC | <0.01% | $68.19 | 0.0725 | $4.94 | |
BSC | <0.01% | $0.969838 | 5.0824 | $4.93 | |
BSC | <0.01% | $2.2 | 2.2103 | $4.86 | |
BSC | <0.01% | $0.002522 | 1,925.0465 | $4.85 | |
BSC | <0.01% | $0.238738 | 19.906 | $4.75 | |
BSC | <0.01% | $0.000612 | 7,675.6864 | $4.7 | |
BSC | <0.01% | $102,401 | 0.00004532 | $4.64 | |
BSC | <0.01% | $0.000185 | 24,858.7214 | $4.61 | |
BSC | <0.01% | $0.000369 | 12,406.5966 | $4.58 | |
BSC | <0.01% | $0.002579 | 1,774.778 | $4.58 | |
BSC | <0.01% | $0.000281 | 16,110.0814 | $4.53 | |
BSC | <0.01% | $0.011023 | 407.5806 | $4.49 | |
BSC | <0.01% | $0.005 | 886.8123 | $4.43 | |
BSC | <0.01% | $1.89 | 2.3361 | $4.42 | |
BSC | <0.01% | $0.001232 | 3,550.5598 | $4.37 | |
BSC | <0.01% | $0.002347 | 1,856.6863 | $4.36 | |
BSC | <0.01% | $0.000268 | 16,210.976 | $4.35 | |
BSC | <0.01% | $0.00465 | 933.5647 | $4.34 | |
BSC | <0.01% | $0.006118 | 702.9469 | $4.3 | |
BSC | <0.01% | $0.117665 | 36.101 | $4.25 | |
BSC | <0.01% | <$0.000001 | 31,513,429.5586 | $4.2 | |
BSC | <0.01% | $0.027169 | 154.5987 | $4.2 | |
BSC | <0.01% | <$0.000001 | 704,857,972.7684 | $4.15 | |
BSC | <0.01% | $0.001625 | 2,540.9019 | $4.13 | |
BSC | <0.01% | $0.000052 | 78,997.7397 | $4.13 | |
BSC | <0.01% | $0.000424 | 9,665.315 | $4.1 | |
BSC | <0.01% | $0.026434 | 154.5706 | $4.09 | |
BSC | <0.01% | $0.000154 | 26,279.2742 | $4.05 | |
BSC | <0.01% | $0.0013 | 3,112.4456 | $4.05 | |
BSC | <0.01% | $0.006953 | 580.8632 | $4.04 | |
BSC | <0.01% | $7.77 | 0.5182 | $4.03 | |
BSC | <0.01% | <$0.000001 | 4,170,410,877.0991 | $3.96 | |
BSC | <0.01% | $28.23 | 0.1391 | $3.93 | |
BSC | <0.01% | $0.007102 | 549.2601 | $3.9 | |
BSC | <0.01% | $0.002122 | 1,834.1861 | $3.89 | |
BSC | <0.01% | <$0.000001 | 41,130,825.8254 | $3.88 | |
BSC | <0.01% | $0.131629 | 29.3 | $3.86 | |
BSC | <0.01% | $0.003601 | 1,063.3779 | $3.83 | |
BSC | <0.01% | $0.015021 | 254.9324 | $3.83 | |
BSC | <0.01% | $0.352719 | 10.692 | $3.77 | |
BSC | <0.01% | $0.000166 | 22,665.6444 | $3.76 | |
BSC | <0.01% | $0.008882 | 420.5871 | $3.74 | |
BSC | <0.01% | $1.12 | 3.3166 | $3.71 | |
BSC | <0.01% | $0.001019 | 3,610.2386 | $3.68 | |
BSC | <0.01% | $0.000013 | 279,908.321 | $3.67 | |
BSC | <0.01% | $0.086606 | 42.3731 | $3.67 | |
BSC | <0.01% | $0.000881 | 4,149.7841 | $3.66 | |
BSC | <0.01% | $0.006117 | 590.4256 | $3.61 | |
BSC | <0.01% | <$0.000001 | 10,000,000 | $3.55 | |
BSC | <0.01% | $0.000067 | 53,256.7978 | $3.54 | |
BSC | <0.01% | $0.54071 | 6.3835 | $3.45 | |
BSC | <0.01% | $0.00179 | 1,921.1093 | $3.44 | |
BSC | <0.01% | $1.38 | 2.4844 | $3.43 | |
BSC | <0.01% | <$0.000001 | 3,986,544,934.7682 | $3.42 | |
BSC | <0.01% | $0.002598 | 1,315.3851 | $3.42 | |
BSC | <0.01% | $0.4956 | 6.8884 | $3.41 | |
BSC | <0.01% | $0.000239 | 14,255.7438 | $3.41 | |
BSC | <0.01% | $0.34914 | 9.7278 | $3.4 | |
BSC | <0.01% | $0.006023 | 563.5332 | $3.39 | |
BSC | <0.01% | <$0.000001 | 30,774,899.7886 | $3.37 | |
BSC | <0.01% | $0.011595 | 287.8216 | $3.34 | |
BSC | <0.01% | $0.012775 | 260.6361 | $3.33 | |
BSC | <0.01% | $0.003595 | 915.7545 | $3.29 | |
BSC | <0.01% | $0.000821 | 3,982.5811 | $3.27 | |
BSC | <0.01% | $0.006677 | 489.3431 | $3.27 | |
BSC | <0.01% | $0.983988 | 3.2942 | $3.24 | |
BSC | <0.01% | $0.012892 | 251.2191 | $3.24 | |
BSC | <0.01% | $0.007222 | 447.7042 | $3.23 | |
BSC | <0.01% | $0.000002 | 1,636,077.0699 | $3.21 | |
BSC | <0.01% | $0.003454 | 923.5343 | $3.19 | |
BSC | <0.01% | $0.003765 | 844.8305 | $3.18 | |
BSC | <0.01% | $0.018153 | 174.7383 | $3.17 | |
BSC | <0.01% | <$0.000001 | 7,039,319.3812 | $3.15 | |
BSC | <0.01% | $0.069107 | 45.1287 | $3.12 | |
BSC | <0.01% | $0.004799 | 645.9092 | $3.1 | |
BSC | <0.01% | $0.0021 | 1,474.1464 | $3.1 | |
BSC | <0.01% | $0.000054 | 57,117.1406 | $3.09 | |
BSC | <0.01% | $0.089311 | 33.1842 | $2.96 | |
BSC | <0.01% | $0.00375 | 788.644 | $2.96 | |
BSC | <0.01% | $0.01188 | 247.8142 | $2.94 | |
BSC | <0.01% | $0.000012 | 242,120.6562 | $2.92 | |
BSC | <0.01% | $0.000001 | 3,249,228.8463 | $2.92 | |
BSC | <0.01% | $0.000045 | 64,938.7795 | $2.9 | |
BSC | <0.01% | $0.013695 | 212 | $2.9 | |
BSC | <0.01% | $0.32947 | 8.8101 | $2.9 | |
BSC | <0.01% | <$0.000001 | 42,621,937.4132 | $2.89 | |
BSC | <0.01% | $0.002325 | 1,239.8643 | $2.88 | |
BSC | <0.01% | $0.040145 | 69.9186 | $2.81 | |
BSC | <0.01% | $0.000003 | 897,926.3581 | $2.77 | |
BSC | <0.01% | $0.000878 | 3,135.1285 | $2.75 | |
BSC | <0.01% | $0.000855 | 3,216.9024 | $2.75 | |
BSC | <0.01% | $0.000117 | 23,369.403 | $2.73 | |
BSC | <0.01% | $0.00046 | 5,932.7356 | $2.73 | |
BSC | <0.01% | $0.000531 | 5,103.7104 | $2.71 | |
BSC | <0.01% | <$0.000001 | 13,786,461,496.477 | $2.69 | |
BSC | <0.01% | $0.000089 | 30,276.8437 | $2.69 | |
BSC | <0.01% | $0.01594 | 166.8185 | $2.66 | |
BSC | <0.01% | <$0.000001 | 7,961,661.07 | $2.64 | |
BSC | <0.01% | $0.999898 | 2.6332 | $2.63 | |
BSC | <0.01% | <$0.000001 | 3,260,461,474.3296 | $2.61 | |
BSC | <0.01% | $0.000002 | 1,230,555.0276 | $2.61 | |
BSC | <0.01% | $0.009268 | 279.0303 | $2.59 | |
BSC | <0.01% | $0.007189 | 357.2673 | $2.57 | |
BSC | <0.01% | $2.39 | 1.0734 | $2.57 | |
BSC | <0.01% | $0.026987 | 94.8325 | $2.56 | |
BSC | <0.01% | $0.003078 | 829.161 | $2.55 | |
BSC | <0.01% | $0.000004 | 605,521.8448 | $2.53 | |
BSC | <0.01% | <$0.000001 | 1,523,266,163.1627 | $2.51 | |
BSC | <0.01% | $0.05345 | 46.3497 | $2.48 | |
BSC | <0.01% | <$0.000001 | 2,627,402,346,198.9878 | $2.47 | |
BSC | <0.01% | $5.18 | 0.4764 | $2.47 | |
BSC | <0.01% | $0.000989 | 2,483.856 | $2.46 | |
BSC | <0.01% | $0.025847 | 94.8461 | $2.45 | |
BSC | <0.01% | $0.000176 | 13,849.5907 | $2.44 | |
BSC | <0.01% | $0.003845 | 626.2675 | $2.41 | |
BSC | <0.01% | $0.000859 | 2,787.934 | $2.39 | |
BSC | <0.01% | $0.163164 | 14.6205 | $2.39 | |
BSC | <0.01% | $8.96 | 0.2655 | $2.38 | |
BSC | <0.01% | $0.001591 | 1,494.593 | $2.38 | |
BSC | <0.01% | <$0.000001 | 2,540,407,806.1878 | $2.38 | |
BSC | <0.01% | <$0.000001 | 20,368,523,205.3694 | $2.37 | |
BSC | <0.01% | $0.015694 | 149.9262 | $2.35 | |
BSC | <0.01% | $40.72 | 0.0572 | $2.33 | |
BSC | <0.01% | $0.001574 | 1,470.1495 | $2.31 | |
BSC | <0.01% | $0.000418 | 5,518.0399 | $2.31 | |
BSC | <0.01% | $754.21 | 0.00305349 | $2.3 | |
BSC | <0.01% | $0.000475 | 4,837.7095 | $2.3 | |
BSC | <0.01% | $0.0003 | 7,559.8207 | $2.27 | |
BSC | <0.01% | $0.00043 | 5,238.2793 | $2.25 | |
BSC | <0.01% | $0.660367 | 3.4062 | $2.25 | |
BSC | <0.01% | <$0.000001 | 7,861,461,828.2313 | $2.24 | |
BSC | <0.01% | $0.00006 | 37,289.3584 | $2.22 | |
BSC | <0.01% | $314.21 | 0.007059 | $2.22 | |
BSC | <0.01% | $0.011042 | 199.8582 | $2.21 | |
BSC | <0.01% | $0.000496 | 4,441.9075 | $2.2 | |
BSC | <0.01% | $1.6 | 1.3721 | $2.2 | |
BSC | <0.01% | $3.93 | 0.5576 | $2.19 | |
BSC | <0.01% | $0.006034 | 362.845 | $2.19 | |
BSC | <0.01% | $0.008387 | 260.3532 | $2.18 | |
BSC | <0.01% | $0.001621 | 1,343.2254 | $2.18 | |
BSC | <0.01% | <$0.000001 | 1,936,466,461.8462 | $2.16 | |
BSC | <0.01% | $0.000075 | 28,720.6492 | $2.16 | |
BSC | <0.01% | $0.300702 | 7.1602 | $2.15 | |
BSC | <0.01% | $0.018639 | 113.6911 | $2.12 | |
BSC | <0.01% | $0.000136 | 15,550.8412 | $2.12 | |
BSC | <0.01% | $0.002218 | 951.7064 | $2.11 | |
BSC | <0.01% | $0.00011 | 19,124.7383 | $2.11 | |
BSC | <0.01% | $0.410228 | 5.1247 | $2.1 | |
BSC | <0.01% | $0.005894 | 344.6342 | $2.03 | |
BSC | <0.01% | $0.000099 | 20,557.3684 | $2.03 | |
BSC | <0.01% | $0.165033 | 12.2754 | $2.03 | |
BSC | <0.01% | <$0.000001 | 314,177,182.871 | $2.03 | |
BSC | <0.01% | $0.000007 | 293,930.651 | $2.02 | |
BSC | <0.01% | $0.00012 | 16,726.3443 | $2.01 | |
BSC | <0.01% | $0.014715 | 136.3562 | $2.01 | |
BSC | <0.01% | $0.138744 | 14.4412 | $2 | |
BSC | <0.01% | $0.0003 | 6,684.7167 | $2 | |
BSC | <0.01% | $0.1756 | 11.2708 | $1.98 | |
BSC | <0.01% | $0.00189 | 1,044.3545 | $1.97 | |
BSC | <0.01% | $0.000044 | 44,669.2009 | $1.97 | |
BSC | <0.01% | <$0.000001 | 1,510,737,338.077 | $1.96 | |
BSC | <0.01% | $0.000038 | 50,831.3319 | $1.94 | |
BSC | <0.01% | $0.001314 | 1,459.1336 | $1.92 | |
BSC | <0.01% | <$0.000001 | 148,832,787,862.1189 | $1.9 | |
BSC | <0.01% | $0.000293 | 6,481.9407 | $1.9 | |
BSC | <0.01% | $0.243984 | 7.7457 | $1.89 | |
BSC | <0.01% | $0.003914 | 482.1727 | $1.89 | |
BSC | <0.01% | $1.09 | 1.7284 | $1.88 | |
BSC | <0.01% | $0.006863 | 272.4605 | $1.87 | |
BSC | <0.01% | $0.000002 | 1,130,600.4949 | $1.85 | |
BSC | <0.01% | $0.000048 | 38,376.7802 | $1.84 | |
BSC | <0.01% | $115,628 | 0.00001565 | $1.81 | |
BSC | <0.01% | $0.004287 | 421.1496 | $1.81 | |
BSC | <0.01% | $0.002903 | 621.5093 | $1.8 | |
BSC | <0.01% | $0.00002 | 87,649.298 | $1.78 | |
BSC | <0.01% | $0.003433 | 515.6673 | $1.77 | |
BSC | <0.01% | $0.000064 | 27,654.5462 | $1.76 | |
BSC | <0.01% | $92,941.16 | 0.00001882 | $1.75 | |
BSC | <0.01% | <$0.000001 | 55,641,352,331.806 | $1.74 | |
BSC | <0.01% | <$0.000001 | 226,945,442.9073 | $1.74 | |
BSC | <0.01% | $0.01414 | 122.7158 | $1.74 | |
BSC | <0.01% | $0.150423 | 11.3856 | $1.71 | |
BSC | <0.01% | $0.00492 | 344.0016 | $1.69 | |
BSC | <0.01% | $0.058625 | 28.5025 | $1.67 | |
BSC | <0.01% | $0.00004 | 41,402.293 | $1.66 | |
BSC | <0.01% | $0.000061 | 27,069.7866 | $1.66 | |
BSC | <0.01% | $0.003275 | 504.7252 | $1.65 | |
BSC | <0.01% | $0.003282 | 503.5687 | $1.65 | |
BSC | <0.01% | $726.98 | 0.00226788 | $1.65 | |
BSC | <0.01% | $0.032317 | 50.9154 | $1.65 | |
BSC | <0.01% | <$0.000001 | 11,610,921,239.7508 | $1.64 | |
BSC | <0.01% | $0.000001 | 2,361,313.7679 | $1.63 | |
BSC | <0.01% | $0.994766 | 1.6384 | $1.63 | |
BSC | <0.01% | $0.004521 | 358.0739 | $1.62 | |
BSC | <0.01% | $0.000395 | 4,089.1611 | $1.61 | |
BSC | <0.01% | $0.005864 | 272.8669 | $1.6 | |
BSC | <0.01% | $0.005919 | 270.1674 | $1.6 | |
BSC | <0.01% | <$0.000001 | 3,361,709.8719 | $1.6 | |
BSC | <0.01% | $0.000836 | 1,903.0694 | $1.59 | |
BSC | <0.01% | $0.001192 | 1,319.406 | $1.57 | |
BSC | <0.01% | $0.139066 | 11.231 | $1.56 | |
BSC | <0.01% | $0.061071 | 25.5295 | $1.56 | |
BSC | <0.01% | $0.00367 | 420.0741 | $1.54 | |
BSC | <0.01% | $0.044089 | 34.6312 | $1.53 | |
BSC | <0.01% | $0.000528 | 2,873.446 | $1.52 | |
BSC | <0.01% | $0.079549 | 19.0365 | $1.51 | |
BSC | <0.01% | $0.002589 | 576.5025 | $1.49 | |
BSC | <0.01% | $2.81 | 0.5297 | $1.49 | |
BSC | <0.01% | $0.055959 | 26.55 | $1.49 | |
BSC | <0.01% | $0.000066 | 22,472.5058 | $1.48 | |
BSC | <0.01% | $0.000493 | 2,998.6187 | $1.48 | |
BSC | <0.01% | $0.00152 | 965.4556 | $1.47 | |
BSC | <0.01% | $0.010782 | 134.8655 | $1.45 | |
BSC | <0.01% | $0.003403 | 415.2223 | $1.41 | |
BSC | <0.01% | $0.000381 | 3,643.8035 | $1.39 | |
BSC | <0.01% | $0.007179 | 192.6091 | $1.38 | |
BSC | <0.01% | $0.000019 | 71,925.8398 | $1.35 | |
BSC | <0.01% | $0.000097 | 13,812.5198 | $1.34 | |
BSC | <0.01% | $0.003187 | 416.2404 | $1.33 | |
BSC | <0.01% | $0.006983 | 189.7452 | $1.32 | |
BSC | <0.01% | $0.020516 | 64.2356 | $1.32 | |
BSC | <0.01% | $0.035389 | 37.2339 | $1.32 | |
BSC | <0.01% | $0.057329 | 22.8622 | $1.31 | |
BSC | <0.01% | $0.000509 | 2,551.9246 | $1.3 | |
BSC | <0.01% | $1.14 | 1.1355 | $1.29 | |
BSC | <0.01% | $0.000862 | 1,487.5702 | $1.28 | |
BSC | <0.01% | $0.000001 | 1,165,129.6444 | $1.28 | |
BSC | <0.01% | $87.36 | 0.0146 | $1.28 | |
BSC | <0.01% | $0.000148 | 8,516.9049 | $1.26 | |
BSC | <0.01% | $0.001546 | 795.0574 | $1.23 | |
BSC | <0.01% | $0.000012 | 101,972.3095 | $1.23 | |
BSC | <0.01% | $0.003093 | 388.447 | $1.2 | |
BSC | <0.01% | $0.000346 | 3,470.1878 | $1.2 | |
BSC | <0.01% | <$0.000001 | 728,500,591,212.9489 | $1.2 | |
BSC | <0.01% | $0.118143 | 10.0374 | $1.19 | |
BSC | <0.01% | <$0.000001 | 31,853,706.547 | $1.17 | |
BSC | <0.01% | $0.000688 | 1,689.763 | $1.16 | |
BSC | <0.01% | $2.16 | 0.5381 | $1.16 | |
BSC | <0.01% | $0.000002 | 598,931.1387 | $1.14 | |
BSC | <0.01% | $0.000627 | 1,791.3755 | $1.12 | |
BSC | <0.01% | $0.000068 | 16,619.2467 | $1.12 | |
BSC | <0.01% | $0.011332 | 98.5722 | $1.12 | |
BSC | <0.01% | $0.000001 | 1,281,124.5947 | $1.12 | |
BSC | <0.01% | $0.009425 | 117.9407 | $1.11 | |
BSC | <0.01% | <$0.000001 | 75,780,728,793.6681 | $1.11 | |
BSC | <0.01% | <$0.000001 | 54,223,787.6961 | $1.1 | |
BSC | <0.01% | $0.001281 | 860.5772 | $1.1 | |
BSC | <0.01% | $0.000002 | 593,462.1563 | $1.1 | |
BSC | <0.01% | $0.00025 | 4,390.9511 | $1.1 | |
BSC | <0.01% | $0.109024 | 9.8902 | $1.08 | |
BSC | <0.01% | $0.019727 | 54.6354 | $1.08 | |
BSC | <0.01% | <$0.000001 | 21,883,037,825.6828 | $1.08 | |
BSC | <0.01% | <$0.000001 | 304,228,186.0348 | $1.06 | |
BSC | <0.01% | $0.02379 | 44.5905 | $1.06 | |
BSC | <0.01% | $0.009082 | 115.975 | $1.05 | |
BSC | <0.01% | $102,289 | 0.00001027 | $1.05 | |
BSC | <0.01% | <$0.000001 | 912,198,331.3941 | $1.05 | |
BSC | <0.01% | $0.194882 | 5.3597 | $1.04 | |
BSC | <0.01% | $2.44 | 0.424 | $1.03 | |
BSC | <0.01% | $0.996606 | 1.0348 | $1.03 | |
BSC | <0.01% | $0.01549 | 66.1547 | $1.02 | |
BSC | <0.01% | $0.014109 | 72.575 | $1.02 | |
BSC | <0.01% | $0.002013 | 504.5887 | $1.02 | |
BSC | <0.01% | $0.002516 | 401.1538 | $1.01 | |
BSC | <0.01% | $0.002899 | 341.5378 | $0.99 | |
BSC | <0.01% | $0.001149 | 856.7387 | $0.9845 | |
BSC | <0.01% | $0.001421 | 686.0453 | $0.975 | |
BSC | <0.01% | $0.209363 | 4.5674 | $0.9562 | |
BSC | <0.01% | $2.4 | 0.3965 | $0.9515 | |
BSC | <0.01% | $0.00007 | 13,389.0583 | $0.9412 | |
BSC | <0.01% | $0.136397 | 6.8172 | $0.9298 | |
BSC | <0.01% | $0.000021 | 44,762.9428 | $0.9274 | |
BSC | <0.01% | $0.000003 | 296,960.0534 | $0.9146 | |
BSC | <0.01% | $0.000001 | 1,709,231.4456 | $0.913 | |
BSC | <0.01% | $0.014166 | 64.3186 | $0.9111 | |
BSC | <0.01% | $0.005153 | 175.9293 | $0.9065 | |
BSC | <0.01% | <$0.000001 | 504,023,214.4766 | $0.9021 | |
BSC | <0.01% | <$0.000001 | 991,886,473,577.864 | $0.8861 | |
BSC | <0.01% | $0.000789 | 1,112.0886 | $0.8773 | |
BSC | <0.01% | $0.343542 | 2.5285 | $0.8686 | |
BSC | <0.01% | <$0.000001 | 7,753,737.8511 | $0.8624 | |
BSC | <0.01% | $0.001943 | 443.7209 | $0.862 | |
BSC | <0.01% | $0.000008 | 112,377.9199 | $0.8585 | |
BSC | <0.01% | $0.000307 | 2,775.9912 | $0.8523 | |
BSC | <0.01% | $3,842.77 | 0.0002201 | $0.8457 | |
BSC | <0.01% | $0.001157 | 724.8562 | $0.8383 | |
BSC | <0.01% | $0.049715 | 16.8277 | $0.8365 | |
BSC | <0.01% | $0.102068 | 8.0274 | $0.8193 | |
BSC | <0.01% | $0.464518 | 1.7601 | $0.8175 | |
BSC | <0.01% | $0.004568 | 178.1549 | $0.8137 | |
BSC | <0.01% | $0.027169 | 29.4841 | $0.801 | |
BSC | <0.01% | $0.00031 | 2,571.6119 | $0.7964 | |
BSC | <0.01% | <$0.000001 | 6,358,857,625.1679 | $0.7961 | |
BSC | <0.01% | $0.002437 | 315.75 | $0.7694 | |
BSC | <0.01% | $0.004608 | 166.7776 | $0.7685 | |
BSC | <0.01% | <$0.000001 | 12,982,012.5199 | $0.7642 | |
BSC | <0.01% | <$0.000001 | 5,668,924.4623 | $0.7632 | |
BSC | <0.01% | <$0.000001 | 6,103,720.9528 | $0.7624 | |
BSC | <0.01% | <$0.000001 | 794,646,192.9268 | $0.7526 | |
BSC | <0.01% | $0.000128 | 5,881.2239 | $0.7516 | |
BSC | <0.01% | $0.000833 | 896.3202 | $0.7468 | |
BSC | <0.01% | <$0.000001 | 309,976,152.5182 | $0.7401 | |
BSC | <0.01% | <$0.000001 | 6,616,087,876,459.0137 | $0.7306 | |
BSC | <0.01% | $0.150297 | 4.7098 | $0.7078 | |
BSC | <0.01% | $0.001842 | 383.6093 | $0.7064 | |
BSC | <0.01% | <$0.000001 | 8,640,732,968.9683 | $0.7033 | |
BSC | <0.01% | $0.000004 | 157,879.7742 | $0.6954 | |
BSC | <0.01% | <$0.000001 | 577,954,645.8501 | $0.6935 | |
BSC | <0.01% | $0.000315 | 2,192.3667 | $0.6911 | |
BSC | <0.01% | $0.002482 | 278.1568 | $0.6904 | |
BSC | <0.01% | $0.000152 | 4,428.2542 | $0.6732 | |
BSC | <0.01% | $0.001312 | 509.1492 | $0.6678 | |
BSC | <0.01% | $0.008023 | 83.0899 | $0.6666 | |
BSC | <0.01% | $0.001814 | 366.5431 | $0.6647 | |
BSC | <0.01% | $0.01128 | 58.9127 | $0.6645 | |
BSC | <0.01% | $0.00004 | 16,749.2261 | $0.6624 | |
BSC | <0.01% | $0.000038 | 17,084.2403 | $0.6557 | |
BSC | <0.01% | $0.000016 | 41,457.5707 | $0.6554 | |
BSC | <0.01% | <$0.000001 | 794,353,906.9678 | $0.654 | |
BSC | <0.01% | $0.003057 | 212.9293 | $0.6509 | |
BSC | <0.01% | $0.00276 | 235.5753 | $0.6501 | |
BSC | <0.01% | <$0.000001 | 161,107,430,368,180.66 | $0.6458 | |
BSC | <0.01% | $0.020021 | 31.9109 | $0.6388 | |
BSC | <0.01% | $0.003508 | 178.4929 | $0.6261 | |
BSC | <0.01% | $0.00201 | 309.7575 | $0.6224 | |
BSC | <0.01% | $0.000152 | 4,088.1823 | $0.6217 | |
BSC | <0.01% | <$0.000001 | 1,420,931,648,526.9609 | $0.6175 | |
BSC | <0.01% | $7.99 | 0.077 | $0.6148 | |
BSC | <0.01% | $0.002936 | 207.5323 | $0.6092 | |
BSC | <0.01% | <$0.000001 | 1,219,597,220,416.01 | $0.6079 | |
BSC | <0.01% | <$0.000001 | 10,713,579,225.4988 | $0.6053 | |
BSC | <0.01% | $0.012101 | 49.849 | $0.6032 | |
BSC | <0.01% | $0.000165 | 3,608.832 | $0.5953 | |
BSC | <0.01% | $0.377318 | 1.5763 | $0.5947 | |
BSC | <0.01% | $0.000019 | 31,485.4507 | $0.5938 | |
BSC | <0.01% | <$0.000001 | 504,165,227.9965 | $0.5888 | |
BSC | <0.01% | $0.003022 | 191.0293 | $0.5773 | |
BSC | <0.01% | $0.188451 | 3.0608 | $0.5768 | |
BSC | <0.01% | $0.000094 | 6,101.4258 | $0.5748 | |
BSC | <0.01% | $0.877184 | 0.6351 | $0.557 | |
BSC | <0.01% | <$0.000001 | 1,763,299.5911 | $0.5556 | |
BSC | <0.01% | $0.001801 | 306.6815 | $0.5522 | |
BSC | <0.01% | $0.1092 | 4.9633 | $0.5419 | |
BSC | <0.01% | $0.006787 | 79.8321 | $0.5418 | |
BSC | <0.01% | $1.13 | 0.4789 | $0.5411 | |
BSC | <0.01% | $0.000004 | 125,999.8072 | $0.5367 | |
BSC | <0.01% | $1.03 | 0.5163 | $0.5312 | |
BSC | <0.01% | $0.004474 | 117.1825 | $0.5242 | |
BSC | <0.01% | $0.000515 | 1,010.0029 | $0.5197 | |
BSC | <0.01% | <$0.000001 | 1,451,871.0048 | $0.5095 | |
BSC | <0.01% | <$0.000001 | 846,954,952.6861 | $0.5081 | |
BSC | <0.01% | $0.001515 | 333.3638 | $0.5048 | |
BSC | <0.01% | <$0.000001 | 179,933,340.1324 | $0.5038 | |
BSC | <0.01% | $0.014893 | 33.3309 | $0.4964 | |
BSC | <0.01% | $0.000711 | 689.1546 | $0.4899 | |
BSC | <0.01% | $0.06787 | 7.2181 | $0.4898 | |
BSC | <0.01% | $0.001281 | 372.7 | $0.4774 | |
BSC | <0.01% | $0.000049 | 9,655.4093 | $0.475 | |
BSC | <0.01% | $0.002236 | 211.4511 | $0.4727 | |
BSC | <0.01% | $0.012375 | 38.1688 | $0.4723 | |
BSC | <0.01% | $0.00001 | 46,617.108 | $0.4717 | |
BSC | <0.01% | $0.997772 | 0.4704 | $0.4693 | |
BSC | <0.01% | $3.11 | 0.1484 | $0.4616 | |
BSC | <0.01% | $0.0002 | 2,295.5423 | $0.4582 | |
BSC | <0.01% | $0.002116 | 209.0207 | $0.4423 | |
BSC | <0.01% | $2,080.88 | 0.00021228 | $0.4417 | |
BSC | <0.01% | $0.003289 | 133.5527 | $0.4392 | |
BSC | <0.01% | $0.001639 | 266.9126 | $0.4374 | |
BSC | <0.01% | <$0.000001 | 16,579,911.1173 | $0.4295 | |
BSC | <0.01% | $0.002269 | 189.184 | $0.4292 | |
BSC | <0.01% | $0.000246 | 1,731.8416 | $0.4268 | |
BSC | <0.01% | $0.04708 | 8.9461 | $0.4211 | |
BSC | <0.01% | $0.068972 | 6.0495 | $0.4172 | |
BSC | <0.01% | $0.446291 | 0.933 | $0.4163 | |
BSC | <0.01% | $0.000449 | 923.7257 | $0.4146 | |
BSC | <0.01% | $0.001559 | 265.0419 | $0.4131 | |
BSC | <0.01% | $0.000643 | 640.8247 | $0.4122 | |
BSC | <0.01% | $0.003994 | 102.8707 | $0.4108 | |
BSC | <0.01% | $0.000078 | 5,181.4989 | $0.4063 | |
BSC | <0.01% | $4.9 | 0.0825 | $0.4044 | |
BSC | <0.01% | $0.001193 | 338.8344 | $0.404 | |
BSC | <0.01% | $0.002637 | 151.2054 | $0.3987 | |
BSC | <0.01% | $0.002813 | 141.6686 | $0.3985 | |
BSC | <0.01% | $0.000002 | 200,030.2244 | $0.3962 | |
BSC | <0.01% | $0.024774 | 15.8976 | $0.3938 | |
BSC | <0.01% | $0.00184 | 212.7933 | $0.3915 | |
BSC | <0.01% | $0.005976 | 64.2147 | $0.3837 | |
BSC | <0.01% | $0.135483 | 2.8293 | $0.3833 | |
BSC | <0.01% | $0.000053 | 7,227.0054 | $0.3802 | |
BSC | <0.01% | <$0.000001 | 787,858,329.5082 | $0.3752 | |
BSC | <0.01% | $1 | 0.3729 | $0.373 | |
BSC | <0.01% | $0.000065 | 5,491.7625 | $0.3563 | |
BSC | <0.01% | $0.000271 | 1,299.2548 | $0.3526 | |
BSC | <0.01% | <$0.000001 | 2,778,485.6495 | $0.3518 | |
BSC | <0.01% | $0.375207 | 0.9342 | $0.3505 | |
BSC | <0.01% | $15.91 | 0.0218 | $0.3475 | |
BSC | <0.01% | $0.000263 | 1,286.3791 | $0.3384 | |
BSC | <0.01% | $0.000051 | 6,641.6394 | $0.3379 | |
BSC | <0.01% | $0.00112 | 301.2458 | $0.3374 | |
BSC | <0.01% | $0.004234 | 76.7247 | $0.3248 | |
BSC | <0.01% | $0.000264 | 1,221.6822 | $0.3222 | |
BSC | <0.01% | $0.001566 | 203.4665 | $0.3186 | |
BSC | <0.01% | <$0.000001 | 147,470,620,952.9207 | $0.3133 | |
BSC | <0.01% | $0.000001 | 261,257.149 | $0.3079 | |
BSC | <0.01% | $0.012031 | 25.0545 | $0.3014 | |
BSC | <0.01% | $0.0078 | 38.2595 | $0.2984 | |
BSC | <0.01% | $0.018559 | 15.9843 | $0.2966 | |
BSC | <0.01% | $0.017781 | 16.5076 | $0.2935 | |
BSC | <0.01% | $0.002116 | 138.3243 | $0.2927 | |
BSC | <0.01% | $0.000424 | 688.9062 | $0.2922 | |
BSC | <0.01% | <$0.000001 | 8,834,520,443.2051 | $0.2918 | |
BSC | <0.01% | <$0.000001 | 2,739,906.0641 | $0.2868 | |
BSC | <0.01% | $0.091848 | 3.1204 | $0.2865 | |
BSC | <0.01% | $0.00001 | 27,338.4449 | $0.2862 | |
BSC | <0.01% | $0.000146 | 1,954.9199 | $0.2859 | |
BSC | <0.01% | <$0.000001 | 90,735,729,468.888 | $0.2854 | |
BSC | <0.01% | $0.001021 | 277.4599 | $0.2833 | |
BSC | <0.01% | $19.96 | 0.014 | $0.2798 | |
BSC | <0.01% | $0.048921 | 5.5973 | $0.2738 | |
BSC | <0.01% | $0.000503 | 539.7334 | $0.2715 | |
BSC | <0.01% | <$0.000001 | 139,069,012,552.6143 | $0.2672 | |
BSC | <0.01% | $0.026124 | 10.2302 | $0.2672 | |
BSC | <0.01% | $0.001563 | 169.7951 | $0.2654 | |
BSC | <0.01% | $1 | 0.2626 | $0.2638 | |
BSC | <0.01% | $0.000364 | 717.1716 | $0.2613 | |
BSC | <0.01% | $0.000085 | 3,081.7101 | $0.2605 | |
BSC | <0.01% | $0.001451 | 177.5199 | $0.2576 | |
BSC | <0.01% | $0.101468 | 2.5235 | $0.256 | |
BSC | <0.01% | $0.006317 | 40.5029 | $0.2558 | |
BSC | <0.01% | $0.003534 | 72.3366 | $0.2556 | |
BSC | <0.01% | <$0.000001 | 750,657.2963 | $0.2543 | |
BSC | <0.01% | $0.00147 | 172.6884 | $0.2537 | |
BSC | <0.01% | $0.000033 | 7,519.6713 | $0.2507 | |
BSC | <0.01% | $0.001171 | 210.0506 | $0.2459 | |
BSC | <0.01% | $0.001295 | 189.1455 | $0.2449 | |
BSC | <0.01% | $0.000128 | 1,866.2371 | $0.2385 | |
BSC | <0.01% | $0.001995 | 119.4951 | $0.2383 | |
BSC | <0.01% | $0.000089 | 2,610.291 | $0.2321 | |
BSC | <0.01% | $0.080482 | 2.8508 | $0.2294 | |
BSC | <0.01% | $0.000001 | 208,535.6728 | $0.2293 | |
BSC | <0.01% | <$0.000001 | 1,937,298,289.2181 | $0.2254 | |
BSC | <0.01% | $0.044361 | 5.0477 | $0.2239 | |
BSC | <0.01% | $0.000059 | 3,705.1435 | $0.2186 | |
BSC | <0.01% | $0.000748 | 289.3983 | $0.2163 | |
BSC | <0.01% | $0.013185 | 16.1906 | $0.2134 | |
BSC | <0.01% | <$0.000001 | 6,623,214,499.3628 | $0.2119 | |
BSC | <0.01% | $0.003885 | 54.3944 | $0.2113 | |
BSC | <0.01% | <$0.000001 | 363,917,074.5761 | $0.21 | |
BSC | <0.01% | $0.046434 | 4.5029 | $0.209 | |
BSC | <0.01% | $0.505826 | 0.4129 | $0.2088 | |
BSC | <0.01% | $0.003887 | 53.3193 | $0.2072 | |
BSC | <0.01% | $0.000314 | 651.1108 | $0.2047 | |
BSC | <0.01% | $0.000545 | 373.8742 | $0.2037 | |
BSC | <0.01% | $0.125981 | 1.589 | $0.2001 | |
BSC | <0.01% | $0.288681 | 0.6922 | $0.1998 | |
BSC | <0.01% | $0.000669 | 296.4082 | $0.1982 | |
BSC | <0.01% | <$0.000001 | 61,546,122,092.1425 | $0.1956 | |
BSC | <0.01% | $0.002312 | 84.6527 | $0.1956 | |
BSC | <0.01% | $0.003465 | 56.2119 | $0.1947 | |
BSC | <0.01% | $0.000591 | 327.2916 | $0.1935 | |
BSC | <0.01% | $0.494659 | 0.3838 | $0.1898 | |
BSC | <0.01% | $0.000081 | 2,306.3974 | $0.1863 | |
BSC | <0.01% | $0.000045 | 4,134.4026 | $0.1852 | |
BSC | <0.01% | <$0.000001 | 29,349,705,860,397.902 | $0.1844 | |
BSC | <0.01% | $0.011513 | 15.8132 | $0.182 | |
BSC | <0.01% | $0.000837 | 217.1666 | $0.1817 | |
BSC | <0.01% | <$0.000001 | 107,108,695.8563 | $0.1809 | |
BSC | <0.01% | $0.010445 | 17.2811 | $0.1805 | |
BSC | <0.01% | $0.000056 | 3,184.5254 | $0.1792 | |
BSC | <0.01% | $0.363885 | 0.482 | $0.1753 | |
BSC | <0.01% | <$0.000001 | 143,001,346,034.947 | $0.1718 | |
BSC | <0.01% | $0.010445 | 16.3341 | $0.1706 | |
BSC | <0.01% | $0.000043 | 3,969.612 | $0.1705 | |
BSC | <0.01% | $0.000572 | 294.7965 | $0.1685 | |
BSC | <0.01% | $0.008759 | 19.2239 | $0.1683 | |
BSC | <0.01% | $0.000816 | 205.81 | $0.1678 | |
BSC | <0.01% | $0.103977 | 1.5945 | $0.1657 | |
BSC | <0.01% | $0.004571 | 35.6259 | $0.1628 | |
BSC | <0.01% | $0.000014 | 11,565.985 | $0.1625 | |
BSC | <0.01% | $1.24 | 0.13 | $0.1612 | |
BSC | <0.01% | $0.000038 | 4,211.8046 | $0.1595 | |
BSC | <0.01% | $0.000048 | 3,320.4332 | $0.159 | |
BSC | <0.01% | $0.021946 | 7.1673 | $0.1572 | |
BSC | <0.01% | <$0.000001 | 1,570,562.5498 | $0.1567 | |
BSC | <0.01% | $0.000456 | 336.7205 | $0.1535 | |
BSC | <0.01% | $0.000094 | 1,634.4796 | $0.1528 | |
BSC | <0.01% | $0.000002 | 88,079.59 | $0.1523 | |
BSC | <0.01% | $0.011406 | 13.1203 | $0.1496 | |
BSC | <0.01% | $0.00076 | 195.6052 | $0.1486 | |
BSC | <0.01% | $0.056794 | 2.5973 | $0.1475 | |
BSC | <0.01% | <$0.000001 | 2,044,046.4128 | $0.1463 | |
BSC | <0.01% | $0.004408 | 32.9388 | $0.1452 | |
BSC | <0.01% | $0.003767 | 37.9365 | $0.1428 | |
BSC | <0.01% | $0.044716 | 3.1807 | $0.1422 | |
BSC | <0.01% | $0.005103 | 27.83 | $0.142 | |
BSC | <0.01% | $0.00001 | 13,460.9559 | $0.1399 | |
BSC | <0.01% | $0.000499 | 276.4242 | $0.1379 | |
BSC | <0.01% | $0.001051 | 128.9337 | $0.1355 | |
BSC | <0.01% | $0.000093 | 1,434.8571 | $0.1328 | |
BSC | <0.01% | $0.00055 | 241.8 | $0.1328 | |
BSC | <0.01% | $0.000014 | 9,192.7171 | $0.1315 | |
BSC | <0.01% | $0.004919 | 26.706 | $0.1313 | |
BSC | <0.01% | $0.069097 | 1.8513 | $0.1279 | |
BSC | <0.01% | $0.250838 | 0.5062 | $0.1269 | |
BSC | <0.01% | $0.00364 | 34.6144 | $0.1259 | |
BSC | <0.01% | $0.00498 | 25.2431 | $0.1257 | |
BSC | <0.01% | $0.000114 | 1,099.669 | $0.1255 | |
BSC | <0.01% | <$0.000001 | 4,992,842,843.6957 | $0.1251 | |
BSC | <0.01% | $0.001667 | 73.9206 | $0.1231 | |
BSC | <0.01% | $0.000558 | 220.3353 | $0.123 | |
BSC | <0.01% | $0.008089 | 15.2063 | $0.123 | |
BSC | <0.01% | $15,053.43 | 0.00000814 | $0.1224 | |
BSC | <0.01% | $0.000281 | 432.5832 | $0.1214 | |
BSC | <0.01% | $0.000072 | 1,671.9062 | $0.1197 | |
BSC | <0.01% | $0.000673 | 173.4258 | $0.1167 | |
BSC | <0.01% | $0.688494 | 0.1696 | $0.1167 | |
BSC | <0.01% | $0.001167 | 96.8674 | $0.113 | |
BSC | <0.01% | $0.000079 | 1,402.4085 | $0.1105 | |
BSC | <0.01% | $0.004238 | 25.9002 | $0.1097 | |
BSC | <0.01% | $2.74 | 0.04 | $0.1095 | |
BSC | <0.01% | $0.000329 | 332.2276 | $0.1093 | |
BSC | <0.01% | $0.000002 | 67,773.5898 | $0.1082 | |
BSC | <0.01% | $0.014079 | 7.6089 | $0.1071 | |
BSC | <0.01% | $0.004002 | 26.7266 | $0.1069 | |
BSC | <0.01% | $0.000002 | 56,106.5784 | $0.1058 | |
BSC | <0.01% | $0.002796 | 36.8529 | $0.103 | |
BSC | <0.01% | $3,383.11 | 0.0000304 | $0.1028 | |
BSC | <0.01% | $0.020007 | 5.0928 | $0.1018 | |
BSC | <0.01% | $0.000043 | 2,329.5762 | $0.1006 | |
BSC | <0.01% | <$0.000001 | 32,829,079.8017 | $0.1005 | |
BSC | <0.01% | $688.19 | 0.00000119 | $0.000821 | |
ETH | <0.01% | $0.998941 | 213,637.6089 | $213,411.37 | |
ETH | <0.01% | $3,281.76 | 52.0251 | $170,733.58 | |
ETH | <0.01% | $1 | 35,678.3307 | $35,678.33 | |
ETH | <0.01% | $247.73 | 77.0938 | $19,098.45 | |
ETH | <0.01% | $1.38 | 7,328.8129 | $10,113.76 | |
ETH | <0.01% | $0.300605 | 13,237.4661 | $3,979.25 | |
ETH | <0.01% | $1 | 3,303.7376 | $3,303.74 | |
ETH | <0.01% | $688.93 | 4.3157 | $2,973.23 | |
ETH | <0.01% | <$0.000001 | 6,766,121,220.3207 | $2,385.16 | |
ETH | <0.01% | $1.38 | 1,687.5191 | $2,328.78 | |
ETH | <0.01% | $0.000016 | 119,014,984.313 | $1,874.49 | |
ETH | <0.01% | $0.02494 | 67,740.3897 | $1,689.47 | |
ETH | <0.01% | $1.78 | 879.9365 | $1,566.29 | |
ETH | <0.01% | $0.002147 | 728,875.5977 | $1,565.01 | |
ETH | <0.01% | $2,700.06 | 0.5694 | $1,537.39 | |
ETH | <0.01% | $0.094184 | 16,115.4887 | $1,517.81 | |
ETH | <0.01% | $0.176809 | 8,436.8422 | $1,491.71 | |
ETH | <0.01% | $0.134691 | 11,051.3376 | $1,488.52 | |
ETH | <0.01% | $1.33 | 977.5836 | $1,300.19 | |
ETH | <0.01% | $0.32666 | 3,715.1901 | $1,213.6 | |
ETH | <0.01% | $2.62 | 368.7217 | $965.01 | |
ETH | <0.01% | $2,694.23 | 0.3454 | $930.7 | |
ETH | <0.01% | $1 | 917.5066 | $917.51 | |
ETH | <0.01% | $0.043017 | 21,234.3954 | $913.44 | |
ETH | <0.01% | $0.032737 | 27,669.5012 | $905.82 | |
ETH | <0.01% | $318.16 | 2.8196 | $897.07 | |
ETH | <0.01% | $0.022336 | 39,587.7355 | $884.23 | |
ETH | <0.01% | $20.66 | 42.4052 | $875.97 | |
ETH | <0.01% | $101,894 | 0.00804065 | $819.29 | |
ETH | <0.01% | <$0.000001 | 13,809,606,769.5793 | $785.18 | |
ETH | <0.01% | $0.000021 | 37,766,990.4091 | $779.13 | |
ETH | <0.01% | $0.015885 | 48,985.6182 | $778.14 | |
ETH | <0.01% | $0.999244 | 761.099 | $760.52 | |
ETH | <0.01% | $24.36 | 30.3607 | $739.59 | |
ETH | <0.01% | $0.000116 | 6,271,613.7472 | $727.7 | |
ETH | <0.01% | $0.010394 | 69,599.4369 | $723.43 | |
ETH | <0.01% | $1.03 | 696.4547 | $717.35 | |
ETH | <0.01% | $0.341876 | 2,089.4422 | $714.33 | |
ETH | <0.01% | $0.000038 | 18,783,499.9474 | $713.04 | |
ETH | <0.01% | $13.42 | 51.9985 | $697.82 | |
ETH | <0.01% | $0.060569 | 11,480.0193 | $695.34 | |
ETH | <0.01% | $0.002509 | 272,922.6844 | $684.73 | |
ETH | <0.01% | $0.455785 | 1,500.7529 | $684.02 | |
ETH | <0.01% | <$0.000001 | 1,932,484,521.1782 | $678.28 | |
ETH | <0.01% | $107.68 | 6.1749 | $664.92 | |
ETH | <0.01% | $0.10394 | 6,346.2625 | $659.63 | |
ETH | <0.01% | $2.72 | 241.0409 | $655.63 | |
ETH | <0.01% | $0.678562 | 947.3715 | $642.85 | |
ETH | <0.01% | $0.19889 | 3,169.4799 | $630.38 | |
ETH | <0.01% | <$0.000001 | 13,291,498,831.1158 | $625.07 | |
ETH | <0.01% | $5.47 | 114.1932 | $624.64 | |
ETH | <0.01% | $0.016486 | 37,843.8813 | $623.88 | |
ETH | <0.01% | $0.059802 | 10,389.6652 | $621.32 | |
ETH | <0.01% | $0.003101 | 198,132.53 | $614.33 | |
ETH | <0.01% | $0.451373 | 1,353.502 | $610.93 | |
ETH | <0.01% | $1 | 600.5666 | $601.17 | |
ETH | <0.01% | $0.000687 | 869,245.4293 | $596.97 | |
ETH | <0.01% | $0.000006 | 91,362,334.1942 | $592.94 | |
ETH | <0.01% | $0.402966 | 1,463.3932 | $589.7 | |
ETH | <0.01% | $0.056126 | 10,423.5731 | $585.03 | |
ETH | <0.01% | <$0.000001 | 38,042,127,343.9528 | $584.14 | |
ETH | <0.01% | $0.37878 | 1,539.9842 | $583.32 | |
ETH | <0.01% | $13.13 | 44.0949 | $578.97 | |
ETH | <0.01% | $0.290835 | 1,982.929 | $576.71 | |
ETH | <0.01% | $1.74 | 329.1458 | $574.22 | |
ETH | <0.01% | $3.96 | 144.6172 | $572.75 | |
ETH | <0.01% | $1.2 | 462.3323 | $556.28 | |
ETH | <0.01% | $0.030936 | 17,841.3066 | $551.93 | |
ETH | <0.01% | $0.206382 | 2,621.7672 | $541.09 | |
ETH | <0.01% | $0.505376 | 1,068.6658 | $540.08 | |
ETH | <0.01% | $0.002567 | 210,106.3797 | $539.41 | |
ETH | <0.01% | <$0.000001 | 2,842,733,730,633.5747 | $538.59 | |
ETH | <0.01% | <$0.000001 | 5,914,158,952.7973 | $537.38 | |
ETH | <0.01% | $0.523314 | 1,025.8969 | $536.87 | |
ETH | <0.01% | $1.36 | 393.186 | $534.73 | |
ETH | <0.01% | $0.835086 | 633.6586 | $529.16 | |
ETH | <0.01% | $0.830669 | 614.235 | $510.23 | |
ETH | <0.01% | $0.133946 | 3,783.489 | $506.78 | |
ETH | <0.01% | $1.14 | 443.201 | $505.25 | |
ETH | <0.01% | $2.2 | 228.0515 | $501.71 | |
ETH | <0.01% | $0.000017 | 28,870,573.508 | $496.82 | |
ETH | <0.01% | $0.256224 | 1,927.3203 | $493.83 | |
ETH | <0.01% | $35.48 | 13.8929 | $492.92 | |
ETH | <0.01% | $0.000001 | 459,323,929.4928 | $488.59 | |
ETH | <0.01% | $2.79 | 174.1939 | $486 | |
ETH | <0.01% | $0.003526 | 137,569.993 | $485.06 | |
ETH | <0.01% | $0.218906 | 2,209.1428 | $483.59 | |
ETH | <0.01% | $0.430917 | 1,090.554 | $469.94 | |
ETH | <0.01% | <$0.000001 | 59,811,963,467.8825 | $464.74 | |
ETH | <0.01% | $0.000002 | 286,716,132.1649 | $462.04 | |
ETH | <0.01% | $0.015747 | 29,192.4307 | $459.69 | |
ETH | <0.01% | $9.39 | 48.5908 | $456.27 | |
ETH | <0.01% | $2.38 | 190.3844 | $453.11 | |
ETH | <0.01% | $0.274903 | 1,643.1908 | $451.72 | |
ETH | <0.01% | $0.001637 | 270,229.7615 | $442.47 | |
ETH | <0.01% | $0.028356 | 15,541.6612 | $440.7 | |
ETH | <0.01% | $0.228951 | 1,921.3829 | $439.9 | |
ETH | <0.01% | $35.63 | 12.3458 | $439.88 | |
ETH | <0.01% | <$0.000001 | 6,631,794,213.7851 | $437.15 | |
ETH | <0.01% | $0.100109 | 4,354.3245 | $435.91 | |
ETH | <0.01% | $1.32 | 328.8334 | $434.06 | |
ETH | <0.01% | $1.12 | 386.5448 | $432.93 | |
ETH | <0.01% | $0.000052 | 8,221,671.1975 | $430.82 | |
ETH | <0.01% | $0.003659 | 117,059.3883 | $428.32 | |
ETH | <0.01% | $0.182385 | 2,332.1614 | $425.35 | |
ETH | <0.01% | $57.67 | 7.3657 | $424.78 | |
ETH | <0.01% | $0.003063 | 138,649.5735 | $424.73 | |
ETH | <0.01% | $0.000914 | 462,198.1523 | $422.39 | |
ETH | <0.01% | <$0.000001 | 852,477,488.6814 | $421.42 | |
ETH | <0.01% | $2.03 | 206.8641 | $419.93 | |
ETH | <0.01% | $0.000031 | 13,709,294.6752 | $418.27 | |
ETH | <0.01% | $0.029486 | 14,099.8506 | $415.75 | |
ETH | <0.01% | $0.262579 | 1,578.7302 | $414.54 | |
ETH | <0.01% | $0.046017 | 8,838.7382 | $406.73 | |
ETH | <0.01% | $0.169 | 2,405.2369 | $406.49 | |
ETH | <0.01% | $0.518929 | 779.0113 | $404.25 | |
ETH | <0.01% | $0.00091 | 444,066.7659 | $404.16 | |
ETH | <0.01% | $35.74 | 11.2537 | $402.21 | |
ETH | <0.01% | $0.02629 | 15,239.5601 | $400.65 | |
ETH | <0.01% | $0.029485 | 13,404.4971 | $395.23 | |
ETH | <0.01% | <$0.000001 | 33,786,275,457.8479 | $392.8 | |
ETH | <0.01% | $1.08 | 362.4149 | $392.5 | |
ETH | <0.01% | $36.64 | 10.7037 | $392.18 | |
ETH | <0.01% | $426.01 | 0.9143 | $389.5 | |
ETH | <0.01% | $7,727.33 | 0.0504 | $389.09 | |
ETH | <0.01% | $1.92 | 202.1176 | $388.07 | |
ETH | <0.01% | <$0.000001 | 1,251,752,061.2075 | $387 | |
ETH | <0.01% | $0.000479 | 804,443.1976 | $385.57 | |
ETH | <0.01% | $4.19 | 90.8519 | $380.81 | |
ETH | <0.01% | $0.496074 | 758.1867 | $376.12 | |
ETH | <0.01% | $0.990392 | 376.1015 | $372.49 | |
ETH | <0.01% | $0.002134 | 173,970.2284 | $371.25 | |
ETH | <0.01% | $0.072584 | 5,068.2185 | $367.87 | |
ETH | <0.01% | $0.000966 | 379,913.1234 | $366.93 | |
ETH | <0.01% | $2.38 | 154.2491 | $366.53 | |
ETH | <0.01% | $0.894436 | 407.7961 | $364.75 | |
ETH | <0.01% | $0.006785 | 53,357.27 | $362.03 | |
ETH | <0.01% | $0.246583 | 1,451.7085 | $357.97 | |
ETH | <0.01% | $0.797255 | 446.6654 | $356.11 | |
ETH | <0.01% | $0.172314 | 2,058.3546 | $354.68 | |
ETH | <0.01% | $0.12383 | 2,863.9347 | $354.64 | |
ETH | <0.01% | $0.331468 | 1,066.6828 | $353.57 | |
ETH | <0.01% | $0.131971 | 2,663.9038 | $351.56 | |
ETH | <0.01% | $0.0004 | 878,622.5314 | $351.39 | |
ETH | <0.01% | $0.007147 | 49,152.4869 | $351.31 | |
ETH | <0.01% | $0.05078 | 6,906.9551 | $350.73 | |
ETH | <0.01% | $0.008845 | 39,409.9908 | $348.6 | |
ETH | <0.01% | $1.78 | 195.07 | $347.21 | |
ETH | <0.01% | $687.84 | 0.5041 | $346.74 | |
ETH | <0.01% | $0.00025 | 1,386,468.9545 | $346.05 | |
ETH | <0.01% | $0.000056 | 6,207,090.4479 | $345.61 | |
ETH | <0.01% | $0.051653 | 6,667.6634 | $344.4 | |
ETH | <0.01% | $0.559596 | 607.373 | $339.88 | |
ETH | <0.01% | $0.461707 | 733.6137 | $338.71 | |
ETH | <0.01% | $0.004076 | 83,006.0729 | $338.33 | |
ETH | <0.01% | $0.016655 | 19,870.9614 | $330.94 | |
ETH | <0.01% | $0.528413 | 624.6754 | $330.09 | |
ETH | <0.01% | $0.024717 | 13,287.51 | $328.43 | |
ETH | <0.01% | $0.077457 | 4,219.7446 | $326.85 | |
ETH | <0.01% | $3.72 | 87.4946 | $325.48 | |
ETH | <0.01% | $12.94 | 24.9951 | $323.44 | |
ETH | <0.01% | $1.3 | 246.3679 | $320.28 | |
ETH | <0.01% | $228.89 | 1.3986 | $320.14 | |
ETH | <0.01% | $0.016412 | 19,504.8604 | $320.11 | |
ETH | <0.01% | $0.159236 | 2,003.3493 | $319.01 | |
ETH | <0.01% | $0.194857 | 1,636.0238 | $318.79 | |
ETH | <0.01% | $1.12 | 284.3779 | $318.5 | |
ETH | <0.01% | $0.702922 | 451.3982 | $317.3 | |
ETH | <0.01% | $0.000307 | 1,022,219.9615 | $314.18 | |
ETH | <0.01% | $0.000101 | 3,092,205.9222 | $313.77 | |
ETH | <0.01% | $0.002899 | 106,209.1756 | $307.87 | |
ETH | <0.01% | $0.450122 | 678.3323 | $305.33 | |
ETH | <0.01% | $4.56 | 66.8512 | $304.84 | |
ETH | <0.01% | $0.386044 | 785.684 | $303.31 | |
ETH | <0.01% | $0.010835 | 27,778.7154 | $300.98 | |
ETH | <0.01% | $0.281006 | 1,070.2785 | $300.75 | |
ETH | <0.01% | $0.001026 | 291,571.6687 | $299.11 | |
ETH | <0.01% | $1.2 | 248.2433 | $297.89 | |
ETH | <0.01% | $1.12 | 264.6875 | $296.45 | |
ETH | <0.01% | $0.364374 | 812.3506 | $296 | |
ETH | <0.01% | $3,270.81 | 0.0902 | $294.91 | |
ETH | <0.01% | $0.186292 | 1,582.6157 | $294.83 | |
ETH | <0.01% | $0.038714 | 7,595.346 | $294.05 | |
ETH | <0.01% | $0.001758 | 166,478.4721 | $292.69 | |
ETH | <0.01% | $0.007515 | 38,907.8355 | $292.41 | |
ETH | <0.01% | $4.17 | 69.8331 | $291.2 | |
ETH | <0.01% | $0.004181 | 69,072.298 | $288.79 | |
ETH | <0.01% | $1.58 | 182.2772 | $287.32 | |
ETH | <0.01% | $0.169245 | 1,689.2462 | $285.9 | |
ETH | <0.01% | $0.001902 | 149,989.8916 | $285.29 | |
ETH | <0.01% | $0.030276 | 9,409.2819 | $284.87 | |
ETH | <0.01% | $0.000002 | 161,530,328.3707 | $279.45 | |
ETH | <0.01% | $0.004408 | 63,385.594 | $279.4 | |
ETH | <0.01% | $0.000001 | 440,857,800.6827 | $277.33 | |
ETH | <0.01% | $0.008338 | 32,988.8997 | $275.06 | |
ETH | <0.01% | $14.3 | 19.2058 | $274.64 | |
ETH | <0.01% | $0.085125 | 3,212.3626 | $273.45 | |
ETH | <0.01% | $0.001268 | 215,656.0978 | $273.44 | |
ETH | <0.01% | $0.000009 | 31,439,929.274 | $272.01 | |
ETH | <0.01% | $0.909163 | 297.8666 | $270.81 | |
ETH | <0.01% | $0.000203 | 1,326,791.2589 | $269.93 | |
ETH | <0.01% | $82 | 3.2903 | $269.8 | |
ETH | <0.01% | <$0.000001 | 2,721,625,144.799 | $265.22 | |
ETH | <0.01% | $0.084066 | 3,135.5198 | $263.59 | |
ETH | <0.01% | $2.59 | 101.1735 | $262.04 | |
ETH | <0.01% | $34.05 | 7.6456 | $260.33 | |
ETH | <0.01% | $0.000016 | 16,073,268.4784 | $259.26 | |
ETH | <0.01% | $0.081637 | 3,159.494 | $257.93 | |
ETH | <0.01% | $0.202198 | 1,273.7231 | $257.54 | |
ETH | <0.01% | $0.59031 | 429.698 | $253.66 | |
ETH | <0.01% | $0.004997 | 50,686.6882 | $253.26 | |
ETH | <0.01% | $0.00012 | 2,096,963.499 | $252.1 | |
ETH | <0.01% | $5.83 | 43.1512 | $251.57 | |
ETH | <0.01% | $1.2 | 208.6846 | $250.42 | |
ETH | <0.01% | $0.038866 | 6,439.6117 | $250.28 | |
ETH | <0.01% | $0.031507 | 7,940.083 | $250.17 | |
ETH | <0.01% | $0.101581 | 2,457.5519 | $249.64 | |
ETH | <0.01% | $18.1 | 13.7683 | $249.21 | |
ETH | <0.01% | $0.468084 | 525.825 | $246.13 | |
ETH | <0.01% | $0.002193 | 110,823.9676 | $243.02 | |
ETH | <0.01% | $0.066318 | 3,628.5478 | $240.64 | |
ETH | <0.01% | $0.026279 | 9,111.8609 | $239.45 | |
ETH | <0.01% | $0.000005 | 51,911,359.0015 | $238.79 | |
ETH | <0.01% | <$0.000001 | 18,537,635,420.8027 | $238.46 | |
ETH | <0.01% | $0.179626 | 1,323.2549 | $237.69 | |
ETH | <0.01% | $0.338951 | 697.1724 | $236.31 | |
ETH | <0.01% | $0.000014 | 16,503,444.3129 | $235.3 | |
ETH | <0.01% | $1.7 | 138.3665 | $235.22 | |
ETH | <0.01% | $0.022649 | 10,379.1209 | $235.08 | |
ETH | <0.01% | $0.038636 | 6,080.3607 | $234.92 | |
ETH | <0.01% | $0.347774 | 673.8398 | $234.34 | |
ETH | <0.01% | $0.000012 | 20,199,166.2056 | $233.89 | |
ETH | <0.01% | $0.019155 | 12,163.9267 | $233 | |
ETH | <0.01% | $3.37 | 69.0955 | $232.85 | |
ETH | <0.01% | $0.969838 | 239.4306 | $232.21 | |
ETH | <0.01% | <$0.000001 | 1,748,937,498,574.2847 | $231.88 | |
ETH | <0.01% | $0.89279 | 257.4562 | $229.85 | |
ETH | <0.01% | $0.738385 | 310.047 | $228.93 | |
ETH | <0.01% | $0.000012 | 18,801,120.4921 | $226.89 | |
ETH | <0.01% | $0.060838 | 3,722.8631 | $226.49 | |
ETH | <0.01% | $0.127942 | 1,768.7034 | $226.29 | |
ETH | <0.01% | <$0.000001 | 5,326,755,164.5666 | $225.51 | |
ETH | <0.01% | $0.004035 | 55,636.3965 | $224.47 | |
ETH | <0.01% | $6.74 | 33.302 | $224.46 | |
ETH | <0.01% | <$0.000001 | 3,793,220,195.2891 | $224.38 | |
ETH | <0.01% | $0.008307 | 26,988.6921 | $224.18 | |
ETH | <0.01% | $0.346749 | 641.8641 | $222.57 | |
ETH | <0.01% | $0.026131 | 8,511.2825 | $222.41 | |
ETH | <0.01% | $2.23 | 99.6635 | $222.25 | |
ETH | <0.01% | $0.780912 | 282.9627 | $220.97 | |
ETH | <0.01% | $0.487031 | 452.1865 | $220.23 | |
ETH | <0.01% | $0.015458 | 14,245.9524 | $220.21 | |
ETH | <0.01% | $2.58 | 83.9069 | $216.78 | |
ETH | <0.01% | $0.199049 | 1,089.0499 | $216.77 | |
ETH | <0.01% | <$0.000001 | 8,661,168,218,549,159 | $214.07 | |
ETH | <0.01% | $7.77 | 27.5267 | $213.88 | |
ETH | <0.01% | $0.37512 | 552.9967 | $207.44 | |
ETH | <0.01% | $0.023313 | 8,894.6289 | $207.36 | |
ETH | <0.01% | $1.22 | 169.5517 | $206.85 | |
ETH | <0.01% | $0.000032 | 6,368,827.4447 | $205.84 | |
ETH | <0.01% | $0.110608 | 1,856.5377 | $205.35 | |
ETH | <0.01% | $1.31 | 154.7962 | $202.78 | |
ETH | <0.01% | $0.20204 | 998.962 | $201.83 | |
ETH | <0.01% | $7.77 | 25.9469 | $201.61 | |
ETH | <0.01% | $0.000061 | 3,285,415.6298 | $200.25 | |
ETH | <0.01% | $0.000612 | 326,805.0238 | $200.16 | |
ETH | <0.01% | $0.000003 | 67,364,313.1945 | $199.4 | |
ETH | <0.01% | $0.020945 | 9,511.9871 | $199.23 | |
ETH | <0.01% | $0.084954 | 2,336.1572 | $198.46 | |
ETH | <0.01% | $0.005656 | 34,763.7743 | $196.63 | |
ETH | <0.01% | $1.78 | 109.0039 | $194.25 | |
ETH | <0.01% | $0.449184 | 431.9261 | $194.01 | |
ETH | <0.01% | $0.328363 | 579.5932 | $190.32 | |
ETH | <0.01% | $0.091002 | 2,084.0433 | $189.65 | |
ETH | <0.01% | $1.08 | 174.9639 | $189.49 | |
ETH | <0.01% | $0.178134 | 1,063.5025 | $189.45 | |
ETH | <0.01% | $0.228735 | 823.5576 | $188.38 | |
ETH | <0.01% | $0.022128 | 8,498.3367 | $188.05 | |
ETH | <0.01% | $0.007512 | 24,915.1404 | $187.17 | |
ETH | <0.01% | <$0.000001 | 1,597,675,248,525.2288 | $186.02 | |
ETH | <0.01% | $0.196607 | 940.3132 | $184.87 | |
ETH | <0.01% | $0.013222 | 13,931.2532 | $184.2 | |
ETH | <0.01% | $0.479831 | 383.4887 | $184.01 | |
ETH | <0.01% | $0.093647 | 1,940.5958 | $181.73 | |
ETH | <0.01% | <$0.000001 | 927,753,360.3726 | $178.79 | |
ETH | <0.01% | $1.04 | 171.6177 | $178.31 | |
ETH | <0.01% | <$0.000001 | 111,681,888,411.7217 | $178 | |
ETH | <0.01% | $0.952842 | 185.962 | $177.19 | |
ETH | <0.01% | $0.000003 | 53,873,554.6334 | $174.61 | |
ETH | <0.01% | $0.000005 | 31,906,349.3533 | $174.53 | |
ETH | <0.01% | $0.000209 | 825,822.7099 | $172.4 | |
ETH | <0.01% | $0.188479 | 904.9115 | $170.56 | |
ETH | <0.01% | $57.25 | 2.9509 | $168.95 | |
ETH | <0.01% | <$0.000001 | 23,435,348,699.3106 | $167.23 | |
ETH | <0.01% | $1 | 166.58 | $166.75 | |
ETH | <0.01% | $34.98 | 4.7102 | $164.76 | |
ETH | <0.01% | $0.65047 | 251.3274 | $163.48 | |
ETH | <0.01% | $10.5 | 15.4643 | $162.38 | |
ETH | <0.01% | $0.020379 | 7,911.9038 | $161.23 | |
ETH | <0.01% | $3.71 | 43.3418 | $160.8 | |
ETH | <0.01% | $0.06085 | 2,617.2803 | $159.26 | |
ETH | <0.01% | $0.006285 | 25,228.7784 | $158.57 | |
ETH | <0.01% | $0.228512 | 682.9053 | $156.05 | |
ETH | <0.01% | $1.85 | 84.2904 | $155.94 | |
ETH | <0.01% | $0.00215 | 71,501.0052 | $153.76 | |
ETH | <0.01% | $0.033761 | 4,530.2255 | $152.95 | |
ETH | <0.01% | $0.351634 | 434.576 | $152.81 | |
ETH | <0.01% | $0.033059 | 4,590.4796 | $151.76 | |
ETH | <0.01% | $0.000139 | 1,076,099.7733 | $149.05 | |
ETH | <0.01% | $1.91 | 77.7846 | $148.57 | |
ETH | <0.01% | $0.152844 | 971.9733 | $148.56 | |
ETH | <0.01% | <$0.000001 | 45,685,382,745.6775 | $148.29 | |
ETH | <0.01% | $0.00412 | 35,770.5723 | $147.38 | |
ETH | <0.01% | $0.007051 | 20,853.2927 | $147.04 | |
ETH | <0.01% | $0.070088 | 2,089.5468 | $146.45 | |
ETH | <0.01% | $0.021523 | 6,690.498 | $144 | |
ETH | <0.01% | <$0.000001 | 1,828,249,221.8103 | $141.29 | |
ETH | <0.01% | $12.28 | 11.5036 | $141.26 | |
ETH | <0.01% | $0.317505 | 444.5506 | $141.15 | |
ETH | <0.01% | $0.025522 | 5,510.706 | $140.64 | |
ETH | <0.01% | $0.140191 | 1,000.0347 | $140.2 | |
ETH | <0.01% | $0.004488 | 31,229.743 | $140.16 | |
ETH | <0.01% | $16.91 | 8.2474 | $139.46 | |
ETH | <0.01% | $0.001296 | 107,550.2122 | $139.39 | |
ETH | <0.01% | $0.03542 | 3,934.899 | $139.37 | |
ETH | <0.01% | $0.000545 | 255,071.8864 | $139.07 | |
ETH | <0.01% | $0.000002 | 66,322,453.0637 | $138.99 | |
ETH | <0.01% | $0.035755 | 3,881.2245 | $138.77 | |
ETH | <0.01% | $0.00008 | 1,729,469.3155 | $138.24 | |
ETH | <0.01% | $51.88 | 2.6623 | $138.12 | |
ETH | <0.01% | $0.010773 | 12,549.7593 | $135.2 | |
ETH | <0.01% | $0.000001 | 161,066,381.5572 | $134.6 | |
ETH | <0.01% | $0.796776 | 168.8962 | $134.57 | |
ETH | <0.01% | $0.281561 | 476.7069 | $134.22 | |
ETH | <0.01% | <$0.000001 | 11,587,952,152.428 | $134.11 | |
ETH | <0.01% | $0.00168 | 79,687.4283 | $133.89 | |
ETH | <0.01% | $0.000369 | 361,822.7887 | $133.53 | |
ETH | <0.01% | $0.058946 | 2,264.4807 | $133.48 | |
ETH | <0.01% | <$0.000001 | 415,786,011.6099 | $132.16 | |
ETH | <0.01% | $0.006705 | 19,619.6045 | $131.56 | |
ETH | <0.01% | $0.002045 | 63,880.8783 | $130.66 | |
ETH | <0.01% | $0.000054 | 2,398,758.6813 | $130.56 | |
ETH | <0.01% | $0.005712 | 22,603.5516 | $129.11 | |
ETH | <0.01% | $1.13 | 113.9569 | $128.77 | |
ETH | <0.01% | $0.691195 | 186.1832 | $128.69 | |
ETH | <0.01% | $0.102868 | 1,249.9114 | $128.58 | |
ETH | <0.01% | $0.088842 | 1,435.9401 | $127.57 | |
ETH | <0.01% | $0.001584 | 80,106.283 | $126.91 | |
ETH | <0.01% | $0.027628 | 4,582.4713 | $126.61 | |
ETH | <0.01% | $0.232405 | 543.216 | $126.25 | |
ETH | <0.01% | $0.005896 | 21,368.726 | $126 | |
ETH | <0.01% | $0.035383 | 3,560.795 | $125.99 | |
ETH | <0.01% | $59.33 | 2.0961 | $124.36 | |
ETH | <0.01% | <$0.000001 | 5,825,017,311.4648 | $124.31 | |
ETH | <0.01% | $0.002995 | 41,405.5512 | $124 | |
ETH | <0.01% | <$0.000001 | 15,612,998,750.824 | $123.94 | |
ETH | <0.01% | $0.003418 | 36,107.2702 | $123.41 | |
ETH | <0.01% | $0.642546 | 190.8936 | $122.66 | |
ETH | <0.01% | $9 | 13.5535 | $121.98 | |
ETH | <0.01% | $0.282603 | 431.5256 | $121.95 | |
ETH | <0.01% | $3.33 | 36.5594 | $121.74 | |
ETH | <0.01% | $2.74 | 44.0596 | $120.72 | |
ETH | <0.01% | $2.97 | 40.3932 | $119.97 | |
ETH | <0.01% | $0.198105 | 605.1924 | $119.89 | |
ETH | <0.01% | $0.02714 | 4,386.9562 | $119.06 | |
ETH | <0.01% | $0.000004 | 28,508,196.9833 | $118 | |
ETH | <0.01% | $0.000004 | 26,333,360.5395 | $117.97 | |
ETH | <0.01% | $0.182505 | 646.1908 | $117.93 | |
ETH | <0.01% | $0.000561 | 209,750.119 | $117.75 | |
ETH | <0.01% | $0.152784 | 770.0126 | $117.65 | |
ETH | <0.01% | <$0.000001 | 15,529,374,113.1886 | $117.08 | |
ETH | <0.01% | $0.041497 | 2,818.3836 | $116.95 | |
ETH | <0.01% | $0.012303 | 9,481.6002 | $116.65 | |
ETH | <0.01% | $0.020836 | 5,584.3264 | $116.36 | |
ETH | <0.01% | $0.000089 | 1,292,991.2303 | $115.65 | |
ETH | <0.01% | $0.010099 | 11,358.5023 | $114.71 | |
ETH | <0.01% | $0.716713 | 158.6 | $113.67 | |
ETH | <0.01% | <$0.000001 | 42,055,979,041.8675 | $113.67 | |
ETH | <0.01% | $2.52 | 45.0368 | $113.49 | |
ETH | <0.01% | $0.016306 | 6,938.2023 | $113.14 | |
ETH | <0.01% | $0.052418 | 2,146.2574 | $112.5 | |
ETH | <0.01% | $12.58 | 8.9208 | $112.22 | |
ETH | <0.01% | $0.011558 | 9,690.3351 | $112 | |
ETH | <0.01% | $0.000008 | 14,904,870.098 | $111.82 | |
ETH | <0.01% | $0.026618 | 4,192.7363 | $111.6 | |
ETH | <0.01% | $25.92 | 4.2701 | $110.68 | |
ETH | <0.01% | $0.219491 | 503.9492 | $110.61 | |
ETH | <0.01% | $0.253332 | 430.4417 | $109.04 | |
ETH | <0.01% | $3,458.82 | 0.0311 | $107.57 | |
ETH | <0.01% | $0.000787 | 136,573.3688 | $107.45 | |
ETH | <0.01% | $0.596939 | 178.8551 | $106.77 | |
ETH | <0.01% | $0.0582 | 1,833.8061 | $106.73 | |
ETH | <0.01% | $0.002954 | 36,001.0752 | $106.33 | |
ETH | <0.01% | $0.082817 | 1,276.5189 | $105.72 | |
ETH | <0.01% | $1.58 | 66.6884 | $105.37 | |
ETH | <0.01% | $0.038709 | 2,717.2591 | $105.18 | |
ETH | <0.01% | $0.000882 | 118,748.5849 | $104.78 | |
ETH | <0.01% | $0.165033 | 631.0289 | $104.14 | |
ETH | <0.01% | $0.257698 | 401.3073 | $103.42 | |
ETH | <0.01% | $0.133052 | 766.1282 | $101.94 | |
ETH | <0.01% | $1.09 | 92.8501 | $101.56 | |
ETH | <0.01% | $0.029584 | 3,420.7438 | $101.2 | |
ETH | <0.01% | $0.047448 | 2,123.5061 | $100.76 | |
ETH | <0.01% | $1.25 | 80.3907 | $100.49 | |
ETH | <0.01% | $247.11 | 0.4046 | $99.98 | |
ETH | <0.01% | $0.017334 | 5,750.9018 | $99.69 | |
ETH | <0.01% | $0.177474 | 560.7032 | $99.51 | |
ETH | <0.01% | $0.583878 | 170.311 | $99.44 | |
ETH | <0.01% | $5.19 | 19.0821 | $99.09 | |
ETH | <0.01% | $0.000412 | 240,610.3987 | $99.06 | |
ETH | <0.01% | $0.176845 | 556.4778 | $98.41 | |
ETH | <0.01% | <$0.000001 | 1,602,026,266.0403 | $98.35 | |
ETH | <0.01% | $5.69 | 17.0857 | $97.17 | |
ETH | <0.01% | $0.000007 | 13,747,046.0708 | $96.92 | |
ETH | <0.01% | $0.004339 | 22,261.0333 | $96.58 | |
ETH | <0.01% | $0.843826 | 113.7151 | $95.96 | |
ETH | <0.01% | $0.006242 | 15,289.2688 | $95.43 | |
ETH | <0.01% | $0.958093 | 98.454 | $94.33 | |
ETH | <0.01% | $0.030898 | 3,048.7391 | $94.2 | |
ETH | <0.01% | <$0.000001 | 23,867,066,083.1596 | $94.18 | |
ETH | <0.01% | $0.004434 | 21,229.4325 | $94.13 | |
ETH | <0.01% | $0.000011 | 8,419,953.0628 | $93.79 | |
ETH | <0.01% | $0.025926 | 3,583.9598 | $92.92 | |
ETH | <0.01% | $0.613854 | 149.9671 | $92.06 | |
ETH | <0.01% | $0.000014 | 6,428,874.3466 | $92 | |
ETH | <0.01% | $0.000001 | 138,309,892.6422 | $91.5 | |
ETH | <0.01% | $521.79 | 0.1745 | $91.06 | |
ETH | <0.01% | $0.391842 | 232.1315 | $90.96 | |
ETH | <0.01% | $0.016044 | 5,655.4926 | $90.74 | |
ETH | <0.01% | $0.07607 | 1,191.8848 | $90.67 | |
ETH | <0.01% | $0.05316 | 1,703.0511 | $90.53 | |
ETH | <0.01% | $0.000161 | 558,998.981 | $89.98 | |
ETH | <0.01% | $0.040238 | 2,219.1572 | $89.29 | |
ETH | <0.01% | $0.096629 | 912.6047 | $88.18 | |
ETH | <0.01% | $0.000387 | 225,282.5824 | $87.29 | |
ETH | <0.01% | $0.250116 | 348.2069 | $87.09 | |
ETH | <0.01% | $1.15 | 75.4234 | $86.74 | |
ETH | <0.01% | $0.008105 | 10,692.3225 | $86.66 | |
ETH | <0.01% | $0.000374 | 230,242.1867 | $86.15 | |
ETH | <0.01% | $0.11872 | 721.6608 | $85.68 | |
ETH | <0.01% | $0.099118 | 863.8477 | $85.62 | |
ETH | <0.01% | $0.023531 | 3,634.9597 | $85.53 | |
ETH | <0.01% | $0.000029 | 2,927,616.2483 | $85.31 | |
ETH | <0.01% | $9.54 | 8.9363 | $85.25 | |
ETH | <0.01% | $0.090382 | 938.7417 | $84.84 | |
ETH | <0.01% | $2.5 | 33.9069 | $84.77 | |
ETH | <0.01% | $0.139396 | 605.9183 | $84.46 | |
ETH | <0.01% | $5.01 | 16.8511 | $84.42 | |
ETH | <0.01% | $0.109826 | 765.8059 | $84.11 | |
ETH | <0.01% | $0.277827 | 300.0182 | $83.35 | |
ETH | <0.01% | $16.21 | 5.1288 | $83.12 | |
ETH | <0.01% | <$0.000001 | 7,185,152,838.3903 | $83.05 | |
ETH | <0.01% | $0.546371 | 151.9343 | $83.01 | |
ETH | <0.01% | $4.94 | 16.8002 | $82.99 | |
ETH | <0.01% | $0.670497 | 123.7132 | $82.95 | |
ETH | <0.01% | $0.102482 | 802.5252 | $82.24 | |
ETH | <0.01% | $0.030624 | 2,666.8692 | $81.67 | |
ETH | <0.01% | $0.000044 | 1,849,955.7764 | $81.66 | |
ETH | <0.01% | $0.001773 | 45,923.4803 | $81.43 | |
ETH | <0.01% | $0.391206 | 207.572 | $81.2 | |
ETH | <0.01% | $0.226045 | 357.5718 | $80.83 | |
ETH | <0.01% | $0.009066 | 8,876.211 | $80.47 | |
ETH | <0.01% | $0.000003 | 27,900,604.4399 | $80.07 | |
ETH | <0.01% | $0.001086 | 73,644.2032 | $79.95 | |
ETH | <0.01% | $0.021771 | 3,635.4477 | $79.15 | |
ETH | <0.01% | $0.073799 | 1,068.3146 | $78.84 | |
ETH | <0.01% | $0.052213 | 1,508.4031 | $78.76 | |
ETH | <0.01% | $2.01 | 39.1283 | $78.65 | |
ETH | <0.01% | $0.000009 | 8,606,590.7876 | $78.15 | |
ETH | <0.01% | $0.0125 | 6,239.0919 | $77.99 | |
ETH | <0.01% | $0.00074 | 105,190.309 | $77.81 | |
ETH | <0.01% | $0.120973 | 636.6961 | $77.02 | |
ETH | <0.01% | $0.036394 | 2,093.8289 | $76.2 | |
ETH | <0.01% | $0.000001 | 73,890,331.8598 | $76.06 | |
ETH | <0.01% | $0.00038 | 199,897.1224 | $76.02 | |
ETH | <0.01% | $0.000003 | 22,693,997.2042 | $75.65 | |
ETH | <0.01% | $0.66308 | 113.7692 | $75.44 | |
ETH | <0.01% | $0.001291 | 58,359.6735 | $75.32 | |
ETH | <0.01% | $0.000007 | 11,042,619.5395 | $74.98 | |
ETH | <0.01% | $0.37893 | 197.7449 | $74.93 | |
ETH | <0.01% | $0.044533 | 1,678.6998 | $74.76 | |
ETH | <0.01% | $0.076295 | 978.6095 | $74.66 | |
ETH | <0.01% | $1.34 | 55.4597 | $74.51 | |
ETH | <0.01% | $0.317636 | 234.2623 | $74.41 | |
ETH | <0.01% | $0.030945 | 2,385.536 | $73.82 | |
ETH | <0.01% | $0.00839 | 8,781.4524 | $73.68 | |
ETH | <0.01% | $1.16 | 62.8839 | $73.26 | |
ETH | <0.01% | $0.007563 | 9,679.6358 | $73.21 | |
ETH | <0.01% | $0.291574 | 251.064 | $73.2 | |
ETH | <0.01% | $0.016444 | 4,444.3329 | $73.08 | |
ETH | <0.01% | $0.015107 | 4,831.4385 | $72.99 | |
ETH | <0.01% | $0.000123 | 590,765.2086 | $72.92 | |
ETH | <0.01% | $0.000021 | 3,507,015.7858 | $72.83 | |
ETH | <0.01% | $0.002175 | 33,442.8843 | $72.74 | |
ETH | <0.01% | $1.17 | 62.0215 | $72.3 | |
ETH | <0.01% | $7.21 | 10.0219 | $72.26 | |
ETH | <0.01% | $2.67 | 27.0823 | $72.26 | |
ETH | <0.01% | <$0.000001 | 3,035,905,597.139 | $72.21 | |
ETH | <0.01% | $1.96 | 36.7031 | $71.94 | |
ETH | <0.01% | <$0.000001 | 493,038,207.9845 | $71.57 | |
ETH | <0.01% | $0.009663 | 7,384.0953 | $71.35 | |
ETH | <0.01% | <$0.000001 | 7,092,444,419.2538 | $71.2 | |
ETH | <0.01% | $0.025174 | 2,817.6583 | $70.93 | |
ETH | <0.01% | $0.04471 | 1,570.4562 | $70.22 | |
ETH | <0.01% | $0.000208 | 338,070.4972 | $70.17 | |
ETH | <0.01% | $0.64545 | 108.1869 | $69.83 | |
ETH | <0.01% | $314.27 | 0.2207 | $69.37 | |
ETH | <0.01% | $0.027317 | 2,535.4458 | $69.26 | |
ETH | <0.01% | $0.018594 | 3,687.351 | $68.56 | |
ETH | <0.01% | $0.051239 | 1,333.9795 | $68.35 | |
ETH | <0.01% | $0.001033 | 65,522.8796 | $67.66 | |
ETH | <0.01% | $0.342781 | 197.0898 | $67.56 | |
ETH | <0.01% | $0.000008 | 8,635,024.9065 | $67.4 | |
ETH | <0.01% | $0.099888 | 670.121 | $66.94 | |
ETH | <0.01% | $0.010438 | 6,384.9989 | $66.65 | |
ETH | <0.01% | $1.78 | 37.2886 | $66.37 | |
ETH | <0.01% | $0.000003 | 23,088,056.0004 | $66.26 | |
ETH | <0.01% | $0.003012 | 21,969.511 | $66.18 | |
ETH | <0.01% | $0.000116 | 568,452.2908 | $66.04 | |
ETH | <0.01% | $0.060715 | 1,082.1353 | $65.7 | |
ETH | <0.01% | $0.122595 | 533.2148 | $65.37 | |
ETH | <0.01% | $0.022074 | 2,952.2485 | $65.17 | |
ETH | <0.01% | $0.001657 | 39,271.8755 | $65.09 | |
ETH | <0.01% | <$0.000001 | 94,806,241,201.907 | $64.31 | |
ETH | <0.01% | $0.041637 | 1,537.6136 | $64.02 | |
ETH | <0.01% | $0.997774 | 63.2079 | $63.07 | |
ETH | <0.01% | $0.001191 | 52,874.0703 | $62.97 | |
ETH | <0.01% | $0.000077 | 812,889.3178 | $62.89 | |
ETH | <0.01% | $0.004489 | 13,923.6564 | $62.51 | |
ETH | <0.01% | $0.238738 | 260.9844 | $62.31 | |
ETH | <0.01% | $0.000537 | 115,540.9157 | $61.99 | |
ETH | <0.01% | <$0.000001 | 498,255,610.0965 | $61.49 | |
ETH | <0.01% | $0.871471 | 70.5228 | $61.46 | |
ETH | <0.01% | $0.885651 | 69.2098 | $61.3 | |
ETH | <0.01% | $0.010952 | 5,567.643 | $60.98 | |
ETH | <0.01% | $0.016419 | 3,680.7769 | $60.43 | |
ETH | <0.01% | <$0.000001 | 909,727,757.4304 | $60.27 | |
ETH | <0.01% | $3,383.11 | 0.0178 | $60.26 | |
ETH | <0.01% | $0.034778 | 1,713.4308 | $59.59 | |
ETH | <0.01% | <$0.000001 | 147,372,854,670.7382 | $59.48 | |
ETH | <0.01% | $0.000753 | 78,980.0782 | $59.45 | |
ETH | <0.01% | $0.003677 | 16,152.9158 | $59.39 | |
ETH | <0.01% | $0.023745 | 2,498.7791 | $59.33 | |
ETH | <0.01% | <$0.000001 | 13,300,324,547.4442 | $59.12 | |
ETH | <0.01% | $0.000001 | 59,082,374.2523 | $59.08 | |
ETH | <0.01% | $0.000109 | 544,203.5844 | $59.08 | |
ETH | <0.01% | $0.000001 | 51,704,258.1147 | $59.06 | |
ETH | <0.01% | $0.000395 | 147,466.8843 | $58.27 | |
ETH | <0.01% | $0.000006 | 10,169,492.366 | $58.07 | |
ETH | <0.01% | <$0.000001 | 553,661,840.4168 | $57.96 | |
ETH | <0.01% | $0.000748 | 76,001.0358 | $56.81 | |
ETH | <0.01% | $0.010405 | 5,411.8954 | $56.31 | |
ETH | <0.01% | $0.000518 | 108,511.7435 | $56.24 | |
ETH | <0.01% | $1.18 | 47.5998 | $56.17 | |
ETH | <0.01% | <$0.000001 | 2,854,532,505.3716 | $56.08 | |
ETH | <0.01% | $0.279004 | 200.9476 | $56.07 | |
ETH | <0.01% | $0.277658 | 200.2072 | $55.59 | |
ETH | <0.01% | $1 | 55.1366 | $55.15 | |
ETH | <0.01% | $2.74 | 20.0726 | $55 | |
ETH | <0.01% | $0.64963 | 84.4649 | $54.87 | |
ETH | <0.01% | $0.001006 | 54,114.1825 | $54.46 | |
ETH | <0.01% | $0.000002 | 25,612,149.9274 | $54.35 | |
ETH | <0.01% | $0.013524 | 4,009.0103 | $54.22 | |
ETH | <0.01% | $28.87 | 1.8698 | $53.98 | |
ETH | <0.01% | $5.14 | 10.4277 | $53.57 | |
ETH | <0.01% | $0.015337 | 3,491.4436 | $53.55 | |
ETH | <0.01% | $0.775772 | 68.9897 | $53.52 | |
ETH | <0.01% | $0.000656 | 81,121.1658 | $53.25 | |
ETH | <0.01% | $3.57 | 14.8233 | $52.92 | |
ETH | <0.01% | $0.084954 | 622.4607 | $52.88 | |
ETH | <0.01% | $0.220626 | 239.4923 | $52.84 | |
ETH | <0.01% | $0.000255 | 206,277.8172 | $52.69 | |
ETH | <0.01% | <$0.000001 | 200,379,016.6901 | $52.64 | |
ETH | <0.01% | $0.966217 | 53.7089 | $51.89 | |
ETH | <0.01% | $0.00339 | 15,301.7301 | $51.87 | |
ETH | <0.01% | $0.005679 | 9,006.9585 | $51.15 | |
ETH | <0.01% | $0.001229 | 41,545.7889 | $51.05 | |
ETH | <0.01% | $0.118258 | 430.2528 | $50.88 | |
ETH | <0.01% | $0.015864 | 3,191.4233 | $50.63 | |
ETH | <0.01% | $0.000056 | 897,539.4626 | $50.58 | |
ETH | <0.01% | <$0.000001 | 1,055,211,177.2191 | $50.02 | |
ETH | <0.01% | $0.000882 | 56,415.3606 | $49.73 | |
ETH | <0.01% | $0.000001 | 70,234,550.4061 | $49.34 | |
ETH | <0.01% | $0.050872 | 968.5497 | $49.27 | |
ETH | <0.01% | <$0.000001 | 30,776,218,971.1456 | $48.96 | |
ETH | <0.01% | <$0.000001 | 12,486,710,735.5663 | $48.9 | |
ETH | <0.01% | $0.000215 | 226,584.3903 | $48.79 | |
ETH | <0.01% | $0.004851 | 10,040.678 | $48.7 | |
ETH | <0.01% | $0.002652 | 18,365.5726 | $48.7 | |
ETH | <0.01% | $0.002305 | 21,052.309 | $48.53 | |
ETH | <0.01% | $0.003654 | 13,223.1024 | $48.31 | |
ETH | <0.01% | $0.727178 | 65.8774 | $47.9 | |
ETH | <0.01% | $0.0039 | 12,240.8645 | $47.74 | |
ETH | <0.01% | $0.000075 | 635,579.5621 | $47.74 | |
ETH | <0.01% | $0.000022 | 2,178,699.4902 | $47.72 | |
ETH | <0.01% | $0.035519 | 1,332.5282 | $47.33 | |
ETH | <0.01% | $0.000179 | 263,391.4056 | $47.25 | |
ETH | <0.01% | $0.001232 | 38,314.4171 | $47.19 | |
ETH | <0.01% | <$0.000001 | 102,967,545.4035 | $46.93 | |
ETH | <0.01% | $10.66 | 4.3812 | $46.72 | |
ETH | <0.01% | $0.021584 | 2,159.7701 | $46.62 | |
ETH | <0.01% | $3.7 | 12.5672 | $46.5 | |
ETH | <0.01% | $4.1 | 11.24 | $46.08 | |
ETH | <0.01% | $0.000327 | 140,162.4313 | $45.89 | |
ETH | <0.01% | <$0.000001 | 27,370,391,034.4728 | $45.79 | |
ETH | <0.01% | $0.000377 | 121,323.7158 | $45.75 | |
ETH | <0.01% | $0.049778 | 915.9299 | $45.59 | |
ETH | <0.01% | $0.059528 | 760.8115 | $45.29 | |
ETH | <0.01% | $0.000764 | 59,244.3855 | $45.25 | |
ETH | <0.01% | $0.086846 | 514.7467 | $44.7 | |
ETH | <0.01% | $1.14 | 39.0418 | $44.51 | |
ETH | <0.01% | $0.031956 | 1,385.7378 | $44.28 | |
ETH | <0.01% | $0.00038 | 115,930.7583 | $44.07 | |
ETH | <0.01% | $0.374326 | 117.0182 | $43.8 | |
ETH | <0.01% | $1 | 43.6555 | $43.74 | |
ETH | <0.01% | $0.624057 | 69.2852 | $43.24 | |
ETH | <0.01% | <$0.000001 | 206,767,444.3311 | $43.17 | |
ETH | <0.01% | <$0.000001 | 118,501,912.8329 | $42.92 | |
ETH | <0.01% | $0.000001 | 34,933,602.6882 | $42.62 | |
ETH | <0.01% | $21.07 | 2.0153 | $42.46 | |
ETH | <0.01% | $0.000021 | 2,047,415.696 | $42.24 | |
ETH | <0.01% | $0.010132 | 4,142.0135 | $41.97 | |
ETH | <0.01% | $0.007179 | 5,838.481 | $41.91 | |
ETH | <0.01% | <$0.000001 | 307,434,771.4193 | $41.51 | |
ETH | <0.01% | $0.000001 | 38,238,528.6212 | $41.25 | |
ETH | <0.01% | <$0.000001 | 104,037,152.9912 | $41.06 | |
ETH | <0.01% | $2.75 | 14.8844 | $40.93 | |
ETH | <0.01% | $0.051892 | 787.3313 | $40.86 | |
ETH | <0.01% | $0.006023 | 6,781.0758 | $40.85 | |
ETH | <0.01% | $0.022193 | 1,821.0497 | $40.41 | |
ETH | <0.01% | $0.039841 | 1,005.1856 | $40.05 | |
ETH | <0.01% | $0.00339 | 11,764.0725 | $39.88 | |
ETH | <0.01% | $3.03 | 13.1445 | $39.83 | |
ETH | <0.01% | <$0.000001 | 5,849,586,512.8109 | $39.56 | |
ETH | <0.01% | $0.119141 | 331.5219 | $39.5 | |
ETH | <0.01% | $0.16065 | 245.4866 | $39.44 | |
ETH | <0.01% | $0.000072 | 548,475.7485 | $39.39 | |
ETH | <0.01% | <$0.000001 | 30,465,276,053.513 | $39.21 | |
ETH | <0.01% | $0.039093 | 1,000.508 | $39.11 | |
ETH | <0.01% | <$0.000001 | 4,461,504,916.3198 | $38.9 | |
ETH | <0.01% | $0.098363 | 395.2576 | $38.88 | |
ETH | <0.01% | $0.001313 | 29,595.533 | $38.87 | |
ETH | <0.01% | $0.026491 | 1,465.069 | $38.81 | |
ETH | <0.01% | $0.095844 | 404.5331 | $38.77 | |
ETH | <0.01% | $0.000009 | 4,275,171.0004 | $38.69 | |
ETH | <0.01% | $0.013984 | 2,760.2383 | $38.6 | |
ETH | <0.01% | $0.010484 | 3,671.5773 | $38.49 | |
ETH | <0.01% | $0.182498 | 209.4844 | $38.23 | |
ETH | <0.01% | $1,314.29 | 0.029 | $38.16 | |
ETH | <0.01% | $0.001383 | 27,329.9005 | $37.79 | |
ETH | <0.01% | $0.00469 | 8,035.5877 | $37.69 | |
ETH | <0.01% | $0.047828 | 783.8013 | $37.49 | |
ETH | <0.01% | $0.033152 | 1,125.5815 | $37.32 | |
ETH | <0.01% | $0.966768 | 38.5559 | $37.27 | |
ETH | <0.01% | <$0.000001 | 35,459,521,531.3278 | $37.22 | |
ETH | <0.01% | $0.003961 | 9,291.241 | $36.8 | |
ETH | <0.01% | $0.195185 | 188.3016 | $36.75 | |
ETH | <0.01% | $55.47 | 0.6546 | $36.31 | |
ETH | <0.01% | <$0.000001 | 22,190,344,859.8181 | $36.24 | |
ETH | <0.01% | $0.120273 | 300.2197 | $36.11 | |
ETH | <0.01% | $32.57 | 1.1075 | $36.06 | |
ETH | <0.01% | $0.129747 | 277.7866 | $36.04 | |
ETH | <0.01% | $0.005907 | 6,069.7792 | $35.85 | |
ETH | <0.01% | $0.045861 | 779.5074 | $35.75 | |
ETH | <0.01% | $0.018521 | 1,929.5405 | $35.74 | |
ETH | <0.01% | $0.522958 | 68.323 | $35.73 | |
ETH | <0.01% | $0.008648 | 4,093.9022 | $35.4 | |
ETH | <0.01% | $0.181265 | 193.4805 | $35.07 | |
ETH | <0.01% | $0.010491 | 3,338.269 | $35.02 | |
ETH | <0.01% | <$0.000001 | 9,040,711,496.5842 | $34.9 | |
ETH | <0.01% | $0.078338 | 445.2557 | $34.88 | |
ETH | <0.01% | $102,289 | 0.00033939 | $34.72 | |
ETH | <0.01% | $0.393687 | 87.9864 | $34.64 | |
ETH | <0.01% | $0.058114 | 587.3617 | $34.13 | |
ETH | <0.01% | $0.048588 | 697.6469 | $33.9 | |
ETH | <0.01% | $0.066904 | 506.2897 | $33.87 | |
ETH | <0.01% | $0.374826 | 89.2256 | $33.44 | |
ETH | <0.01% | $0.000001 | 48,868,503.8268 | $33.44 | |
ETH | <0.01% | $0.008712 | 3,828.4176 | $33.35 | |
ETH | <0.01% | $1.89 | 17.5917 | $33.27 | |
ETH | <0.01% | $0.003239 | 10,255.8638 | $33.22 | |
ETH | <0.01% | $0.018676 | 1,771.6014 | $33.09 | |
ETH | <0.01% | <$0.000001 | 22,402,128,121.2144 | $32.93 | |
ETH | <0.01% | $124.56 | 0.264 | $32.88 | |
ETH | <0.01% | $0.383204 | 85.5516 | $32.78 | |
ETH | <0.01% | $0.000638 | 51,078.8926 | $32.6 | |
ETH | <0.01% | $0.001364 | 23,816.6062 | $32.48 | |
ETH | <0.01% | $0.993601 | 32.6232 | $32.41 | |
ETH | <0.01% | $0.001016 | 31,877.7333 | $32.4 | |
ETH | <0.01% | $0.051221 | 631.8677 | $32.36 | |
ETH | <0.01% | $0.007162 | 4,490.353 | $32.16 | |
ETH | <0.01% | $1.39 | 23.1754 | $32.12 | |
ETH | <0.01% | $0.5488 | 58.3164 | $32 | |
ETH | <0.01% | $2.76 | 11.5113 | $31.77 | |
ETH | <0.01% | $0.033387 | 951.5833 | $31.77 | |
ETH | <0.01% | $696.25 | 0.0456 | $31.73 | |
ETH | <0.01% | $0.001689 | 18,776.8886 | $31.72 | |
ETH | <0.01% | $0.011886 | 2,668.4405 | $31.72 | |
ETH | <0.01% | <$0.000001 | 12,117,585,524,628.906 | $31.65 | |
ETH | <0.01% | $40.72 | 0.7755 | $31.58 | |
ETH | <0.01% | $0.078308 | 403.1636 | $31.57 | |
ETH | <0.01% | $1.11 | 28.41 | $31.54 | |
ETH | <0.01% | $0.175825 | 178.9952 | $31.47 | |
ETH | <0.01% | $0.016451 | 1,901.5816 | $31.28 | |
ETH | <0.01% | $0.010464 | 2,985.6669 | $31.24 | |
ETH | <0.01% | $0.004688 | 6,651.8647 | $31.18 | |
ETH | <0.01% | $0.000063 | 490,457.8783 | $31.12 | |
ETH | <0.01% | $21.1 | 1.4725 | $31.07 | |
ETH | <0.01% | $0.013093 | 2,371.1973 | $31.05 | |
ETH | <0.01% | $0.000247 | 125,257.3215 | $30.98 | |
ETH | <0.01% | <$0.000001 | 112,352,537,219.4951 | $30.97 | |
ETH | <0.01% | $246.61 | 0.1255 | $30.95 | |
ETH | <0.01% | $0.000001 | 36,515,571.5553 | $30.93 | |
ETH | <0.01% | $9.04 | 3.42 | $30.92 | |
ETH | <0.01% | $0.023042 | 1,321.0229 | $30.44 | |
ETH | <0.01% | $0.00022 | 138,544.8901 | $30.43 | |
ETH | <0.01% | <$0.000001 | 228,219,082,037.9459 | $30.4 | |
ETH | <0.01% | $0.00184 | 16,485.0895 | $30.33 | |
ETH | <0.01% | $0.00061 | 49,713.2526 | $30.33 | |
ETH | <0.01% | <$0.000001 | 5,661,163,995.807 | $30.21 | |
ETH | <0.01% | $0.190144 | 158.8562 | $30.21 | |
ETH | <0.01% | $7.99 | 3.7714 | $30.13 | |
ETH | <0.01% | $0.00427 | 7,033.5647 | $30.04 | |
ETH | <0.01% | $0.000177 | 169,041.4852 | $29.97 | |
ETH | <0.01% | $0.000001 | 43,290,483.5319 | $29.94 | |
ETH | <0.01% | <$0.000001 | 28,184,902,711.4112 | $29.93 | |
ETH | <0.01% | $0.000415 | 71,940.8943 | $29.84 | |
ETH | <0.01% | $0.001466 | 20,223.0844 | $29.64 | |
ETH | <0.01% | $0.000422 | 69,878.3233 | $29.52 | |
ETH | <0.01% | $0.000287 | 102,980.0365 | $29.51 | |
ETH | <0.01% | $1.32 | 22.2983 | $29.43 | |
ETH | <0.01% | $0.021827 | 1,343.256 | $29.32 | |
ETH | <0.01% | $102,381 | 0.00028617 | $29.3 | |
ETH | <0.01% | $0.047974 | 610.2017 | $29.27 | |
ETH | <0.01% | $0.000002 | 15,790,072.2766 | $29.08 | |
ETH | <0.01% | $0.000057 | 511,509.9443 | $28.98 | |
ETH | <0.01% | $1.28 | 22.5566 | $28.87 | |
ETH | <0.01% | $0.055652 | 518.0339 | $28.83 | |
ETH | <0.01% | <$0.000001 | 73,608,670,180.6333 | $28.73 | |
ETH | <0.01% | $0.000005 | 5,265,446.1993 | $28.54 | |
ETH | <0.01% | $0.002278 | 12,506.4544 | $28.49 | |
ETH | <0.01% | $0.118199 | 239.5881 | $28.32 | |
ETH | <0.01% | $0.362771 | 78.0081 | $28.3 | |
ETH | <0.01% | $0.121654 | 231.9831 | $28.22 | |
ETH | <0.01% | $0.000004 | 6,536,779.3944 | $27.98 | |
ETH | <0.01% | $0.021381 | 1,308.4503 | $27.98 | |
ETH | <0.01% | $0.000158 | 176,976.1936 | $27.95 | |
ETH | <0.01% | $0.000001 | 28,362,582.9011 | $27.89 | |
ETH | <0.01% | $0.000001 | 45,712,887.1382 | $27.85 | |
ETH | <0.01% | $0.008023 | 3,468.344 | $27.83 | |
ETH | <0.01% | $0.000623 | 44,644.4289 | $27.8 | |
ETH | <0.01% | $0.003132 | 8,866.6712 | $27.77 | |
ETH | <0.01% | $0.190187 | 145.7021 | $27.71 | |
ETH | <0.01% | $0.068827 | 401.742 | $27.65 | |
ETH | <0.01% | $0.000173 | 159,809.0014 | $27.63 | |
ETH | <0.01% | <$0.000001 | 170,813,956,869.3902 | $27.62 | |
ETH | <0.01% | $0.098888 | 275.59 | $27.25 | |
ETH | <0.01% | <$0.000001 | 73,530,040.0045 | $27.17 | |
ETH | <0.01% | $0.001142 | 23,758.6947 | $27.13 | |
ETH | <0.01% | $0.006983 | 3,884.757 | $27.13 | |
ETH | <0.01% | $3,385.21 | 0.0080034 | $27.09 | |
ETH | <0.01% | <$0.000001 | 799,273,728.2303 | $27.01 | |
ETH | <0.01% | $0.662386 | 40.7767 | $27.01 | |
ETH | <0.01% | $0.024917 | 1,083.0924 | $26.99 | |
ETH | <0.01% | $0.011337 | 2,366.733 | $26.83 | |
ETH | <0.01% | $0.152713 | 175.3005 | $26.77 | |
ETH | <0.01% | $0.048921 | 545.6358 | $26.69 | |
ETH | <0.01% | $6.16 | 4.3006 | $26.49 | |
ETH | <0.01% | <$0.000001 | 99,410,249.326 | $26.33 | |
ETH | <0.01% | $0.682585 | 38.336 | $26.17 | |
ETH | <0.01% | $0.176409 | 148.0339 | $26.11 | |
ETH | <0.01% | <$0.000001 | 53,135,623.0464 | $26.1 | |
ETH | <0.01% | $0.000013 | 1,950,883.7738 | $26.06 | |
ETH | <0.01% | $0.108828 | 237.1399 | $25.81 | |
ETH | <0.01% | $0.00114 | 22,604.3941 | $25.76 | |
ETH | <0.01% | <$0.000001 | 71,745,171.6716 | $25.75 | |
ETH | <0.01% | $0.000173 | 148,844.0932 | $25.69 | |
ETH | <0.01% | <$0.000001 | 7,740,136,782.1294 | $25.57 | |
ETH | <0.01% | $3,477.98 | 0.00734882 | $25.56 | |
ETH | <0.01% | $0.997548 | 25.5899 | $25.53 | |
ETH | <0.01% | $0.000005 | 5,230,285.2164 | $25.52 | |
ETH | <0.01% | $0.001445 | 17,433.5938 | $25.19 | |
ETH | <0.01% | $0.000003 | 9,006,476.7915 | $25.13 | |
ETH | <0.01% | $0.266942 | 94.0695 | $25.11 | |
ETH | <0.01% | $0.758759 | 32.9847 | $25.03 | |
ETH | <0.01% | $0.111533 | 223.9145 | $24.97 | |
ETH | <0.01% | <$0.000001 | 16,099,628,889.3292 | $24.86 | |
ETH | <0.01% | <$0.000001 | 17,109,025,140.9805 | $24.67 | |
ETH | <0.01% | $0.00344 | 7,169.0052 | $24.66 | |
ETH | <0.01% | $0.096217 | 255.783 | $24.61 | |
ETH | <0.01% | $0.027436 | 892.9965 | $24.5 | |
ETH | <0.01% | $0.071149 | 344.3351 | $24.5 | |
ETH | <0.01% | $0.076159 | 320.8386 | $24.43 | |
ETH | <0.01% | $0.001305 | 18,669.8362 | $24.37 | |
ETH | <0.01% | <$0.000001 | 154,860,634.9405 | $24.35 | |
ETH | <0.01% | <$0.000001 | 158,920,341,908.3818 | $24.26 | |
ETH | <0.01% | <$0.000001 | 60,718,899.1381 | $24.17 | |
ETH | <0.01% | $0.52611 | 45.6628 | $24.02 | |
ETH | <0.01% | $1.31 | 18.2461 | $23.9 | |
ETH | <0.01% | $0.378048 | 63.2199 | $23.9 | |
ETH | <0.01% | $0.002077 | 11,496.6928 | $23.88 | |
ETH | <0.01% | $0.54071 | 43.8642 | $23.72 | |
ETH | <0.01% | $0.265018 | 89.353 | $23.68 | |
ETH | <0.01% | $0.004654 | 5,086.729 | $23.68 | |
ETH | <0.01% | $0.131198 | 178.3153 | $23.39 | |
ETH | <0.01% | $0.001399 | 16,649.836 | $23.29 | |
ETH | <0.01% | $1.13 | 20.5737 | $23.25 | |
ETH | <0.01% | $0.005004 | 4,616.5578 | $23.1 | |
ETH | <0.01% | $32.81 | 0.7014 | $23.01 | |
ETH | <0.01% | $0.194266 | 118.2305 | $22.97 | |
ETH | <0.01% | $0.154566 | 148.4342 | $22.94 | |
ETH | <0.01% | <$0.000001 | 41,131,215,859.7929 | $22.76 | |
ETH | <0.01% | $0.000829 | 27,421.9128 | $22.74 | |
ETH | <0.01% | $0.000086 | 264,117.0561 | $22.7 | |
ETH | <0.01% | $0.976702 | 23.1814 | $22.64 | |
ETH | <0.01% | $0.015694 | 1,442.2726 | $22.63 | |
ETH | <0.01% | $0.003919 | 5,761.956 | $22.58 | |
ETH | <0.01% | $0.004151 | 5,439.8488 | $22.58 | |
ETH | <0.01% | $0.00105 | 21,499.2078 | $22.57 | |
ETH | <0.01% | $0.000012 | 1,933,795.557 | $22.47 | |
ETH | <0.01% | $0.000006 | 3,702,954.2531 | $22.4 | |
ETH | <0.01% | $0.000039 | 575,758.7471 | $22.36 | |
ETH | <0.01% | $0.061702 | 361.3314 | $22.29 | |
ETH | <0.01% | <$0.000001 | 6,381,811,204.5974 | $22.21 | |
ETH | <0.01% | <$0.000001 | 45,388,988,286.6733 | $22.16 | |
ETH | <0.01% | $0.998408 | 22.1275 | $22.09 | |
ETH | <0.01% | $0.685998 | 32.1161 | $22.03 | |
ETH | <0.01% | $0.000006 | 3,691,150.7815 | $21.92 | |
ETH | <0.01% | $1.26 | 17.4047 | $21.91 | |
ETH | <0.01% | $17.27 | 1.2638 | $21.83 | |
ETH | <0.01% | $0.152561 | 142.8131 | $21.79 | |
ETH | <0.01% | <$0.000001 | 17,525,448,016.215 | $21.73 | |
ETH | <0.01% | $1.78 | 12.1097 | $21.56 | |
ETH | <0.01% | $0.061576 | 347.9009 | $21.42 | |
ETH | <0.01% | $0.050357 | 424.7393 | $21.39 | |
ETH | <0.01% | $0.031575 | 674.6931 | $21.3 | |
ETH | <0.01% | $0.99516 | 21.3204 | $21.22 | |
ETH | <0.01% | $0.006026 | 3,500.0987 | $21.09 | |
ETH | <0.01% | $0.006023 | 3,499.7254 | $21.08 | |
ETH | <0.01% | <$0.000001 | 31,220,735,237.966 | $21.04 | |
ETH | <0.01% | $0.010745 | 1,952.1532 | $20.98 | |
ETH | <0.01% | $0.000588 | 35,589.4982 | $20.94 | |
ETH | <0.01% | $0.002103 | 9,869.8309 | $20.76 | |
ETH | <0.01% | $16.93 | 1.2259 | $20.75 | |
ETH | <0.01% | $0.000072 | 285,630.8133 | $20.5 | |
ETH | <0.01% | $0.000001 | 14,628,880.3912 | $20.35 | |
ETH | <0.01% | $0.000002 | 10,820,107.9621 | $20.23 | |
ETH | <0.01% | $0.05297 | 380.9282 | $20.18 | |
ETH | <0.01% | $0.026565 | 756.0939 | $20.09 | |
ETH | <0.01% | $14,404.35 | 0.00139079 | $20.03 | |
ETH | <0.01% | $0.000003 | 5,997,117.5088 | $19.99 | |
ETH | <0.01% | $0.000068 | 291,743.0446 | $19.82 | |
ETH | <0.01% | <$0.000001 | 2,534,345,051.4134 | $19.74 | |
ETH | <0.01% | $0.016486 | 1,189.1291 | $19.6 | |
ETH | <0.01% | $0.570221 | 34.2589 | $19.54 | |
ETH | <0.01% | $0.095435 | 204.4095 | $19.51 | |
ETH | <0.01% | $1.73 | 11.19 | $19.36 | |
ETH | <0.01% | $134.06 | 0.1439 | $19.29 | |
ETH | <0.01% | $0.066294 | 289.8077 | $19.21 | |
ETH | <0.01% | $0.135068 | 141.984 | $19.18 | |
ETH | <0.01% | $0.063244 | 302.2288 | $19.11 | |
ETH | <0.01% | <$0.000001 | 36,853,170,108.0196 | $19.09 | |
ETH | <0.01% | $0.051226 | 372.1544 | $19.06 | |
ETH | <0.01% | $0.002718 | 6,933.4584 | $18.84 | |
ETH | <0.01% | <$0.000001 | 187,419,660.8342 | $18.74 | |
ETH | <0.01% | $0.169419 | 110.4471 | $18.71 | |
ETH | <0.01% | $0.018639 | 999.7768 | $18.64 | |
ETH | <0.01% | <$0.000001 | 222,916,045.4886 | $18.53 | |
ETH | <0.01% | $0.271034 | 68.3487 | $18.52 | |
ETH | <0.01% | $0.032439 | 567.6252 | $18.41 | |
ETH | <0.01% | <$0.000001 | 82,549,943,354.9099 | $18.18 | |
ETH | <0.01% | $0.052516 | 345.2237 | $18.13 | |
ETH | <0.01% | $0.166295 | 108.9819 | $18.12 | |
ETH | <0.01% | $0.00615 | 2,942.5619 | $18.1 | |
ETH | <0.01% | <$0.000001 | 103,452,224.7594 | $18.01 | |
ETH | <0.01% | $0.001689 | 10,562.7168 | $17.84 | |
ETH | <0.01% | $0.006732 | 2,645.9562 | $17.81 | |
ETH | <0.01% | $0.000601 | 29,623.2916 | $17.79 | |
ETH | <0.01% | <$0.000001 | 113,215,523.0795 | $17.73 | |
ETH | <0.01% | $0.004312 | 4,109.9578 | $17.72 | |
ETH | <0.01% | $0.002526 | 7,003.0677 | $17.69 | |
ETH | <0.01% | $0.004424 | 3,956.2731 | $17.5 | |
ETH | <0.01% | <$0.000001 | 34,054,172,387,628.4 | $17.46 | |
ETH | <0.01% | $0.000002 | 9,795,050.8002 | $17.44 | |
ETH | <0.01% | $0.029509 | 589.7431 | $17.4 | |
ETH | <0.01% | $0.004271 | 4,036.0661 | $17.24 | |
ETH | <0.01% | $2.14 | 8.0438 | $17.21 | |
ETH | <0.01% | $0.027319 | 626.6838 | $17.12 | |
ETH | <0.01% | $0.000448 | 38,141.4697 | $17.1 | |
ETH | <0.01% | $0.023417 | 727.3706 | $17.03 | |
ETH | <0.01% | $0.000002 | 8,225,338.4482 | $17.03 | |
ETH | <0.01% | $0.004887 | 3,477.8773 | $17 | |
ETH | <0.01% | $0.968892 | 17.4311 | $16.89 | |
ETH | <0.01% | <$0.000001 | 40,486,044.5401 | $16.77 | |
ETH | <0.01% | <$0.000001 | 8,773,953,919,526.8115 | $16.73 | |
ETH | <0.01% | $0.001591 | 10,427.3191 | $16.59 | |
ETH | <0.01% | $0.002634 | 6,293.5451 | $16.58 | |
ETH | <0.01% | <$0.000001 | 53,557,686,295.2756 | $16.54 | |
ETH | <0.01% | $0.000918 | 17,964.742 | $16.48 | |
ETH | <0.01% | $3.74 | 4.3202 | $16.15 | |
ETH | <0.01% | $0.000007 | 2,306,306.6913 | $16.1 | |
ETH | <0.01% | $0.356381 | 44.9707 | $16.03 | |
ETH | <0.01% | $0.00023 | 69,388.7242 | $15.99 | |
ETH | <0.01% | $0.548873 | 29.11 | $15.98 | |
ETH | <0.01% | <$0.000001 | 26,802,378,478.804 | $15.84 | |
ETH | <0.01% | $0.210782 | 74.793 | $15.77 | |
ETH | <0.01% | $0.183197 | 85.6147 | $15.68 | |
ETH | <0.01% | $0.01109 | 1,408.0247 | $15.61 | |
ETH | <0.01% | $0.000235 | 66,062.5034 | $15.55 | |
ETH | <0.01% | $2.51 | 6.1773 | $15.5 | |
ETH | <0.01% | $0.044532 | 347.8754 | $15.49 | |
ETH | <0.01% | $0.32947 | 46.9643 | $15.47 | |
ETH | <0.01% | $0.059368 | 260.1138 | $15.44 | |
ETH | <0.01% | $0.000136 | 113,407.6754 | $15.43 | |
ETH | <0.01% | $0.03105 | 496.4969 | $15.42 | |
ETH | <0.01% | $0.044319 | 346.2191 | $15.34 | |
ETH | <0.01% | $0.000005 | 3,064,283.0156 | $15.27 | |
ETH | <0.01% | $0.036459 | 412.0481 | $15.02 | |
ETH | <0.01% | $0.003913 | 3,830.1424 | $14.99 | |
ETH | <0.01% | <$0.000001 | 18,389,320,958.6063 | $14.97 | |
ETH | <0.01% | $0.000149 | 99,080.3426 | $14.78 | |
ETH | <0.01% | $3,281.19 | 0.00450216 | $14.77 | |
ETH | <0.01% | $3.19 | 4.6171 | $14.73 | |
ETH | <0.01% | $1.72 | 8.5515 | $14.72 | |
ETH | <0.01% | $0.005203 | 2,826.5248 | $14.71 | |
ETH | <0.01% | $0.002478 | 5,902.4449 | $14.63 | |
ETH | <0.01% | $0.000187 | 77,596.5686 | $14.53 | |
ETH | <0.01% | $0.000097 | 149,669.9017 | $14.48 | |
ETH | <0.01% | $0.011108 | 1,302.3321 | $14.47 | |
ETH | <0.01% | $0.325384 | 44.1717 | $14.37 | |
ETH | <0.01% | $0.038402 | 373.703 | $14.35 | |
ETH | <0.01% | $8.12 | 1.7502 | $14.21 | |
ETH | <0.01% | <$0.000001 | 2,686,556,773,963.4805 | $14.14 | |
ETH | <0.01% | $0.007581 | 1,864.4114 | $14.13 | |
ETH | <0.01% | $2.12 | 6.6487 | $14.1 | |
ETH | <0.01% | $0.005123 | 2,748.954 | $14.08 | |
ETH | <0.01% | $4.69 | 2.9809 | $13.98 | |
ETH | <0.01% | $0.001551 | 8,983.9179 | $13.94 | |
ETH | <0.01% | $0.0002 | 69,674.3588 | $13.93 | |
ETH | <0.01% | $0.050287 | 276.9262 | $13.93 | |
ETH | <0.01% | $0.015402 | 901.1854 | $13.88 | |
ETH | <0.01% | $0.009172 | 1,507.1668 | $13.82 | |
ETH | <0.01% | $0.211648 | 65.1502 | $13.79 | |
ETH | <0.01% | $1.1 | 12.4867 | $13.72 | |
ETH | <0.01% | $0.000003 | 4,454,527.1718 | $13.69 | |
ETH | <0.01% | $0.000003 | 4,208,942.7793 | $13.68 | |
ETH | <0.01% | $0.000269 | 50,696.8597 | $13.66 | |
ETH | <0.01% | $0.001021 | 13,349.0927 | $13.63 | |
ETH | <0.01% | <$0.000001 | 77,361,472,189.4883 | $13.62 | |
ETH | <0.01% | $0.004181 | 3,229.9132 | $13.5 | |
ETH | <0.01% | $0.000663 | 20,267.6982 | $13.43 | |
ETH | <0.01% | $0.028482 | 469.3314 | $13.37 | |
ETH | <0.01% | <$0.000001 | 704,182,663.3223 | $13.28 | |
ETH | <0.01% | $0.051871 | 255.1312 | $13.23 | |
ETH | <0.01% | $0.007538 | 1,754.1976 | $13.22 | |
ETH | <0.01% | <$0.000001 | 61,522,477.0165 | $13.22 | |
ETH | <0.01% | $0.074401 | 177.1686 | $13.18 | |
ETH | <0.01% | $0.000002 | 7,927,775.0185 | $13.16 | |
ETH | <0.01% | $0.029834 | 440.4053 | $13.14 | |
ETH | <0.01% | $0.01488 | 882.8745 | $13.14 | |
ETH | <0.01% | $0.00005 | 262,335.7435 | $13.11 | |
ETH | <0.01% | $0.016227 | 807.1655 | $13.1 | |
ETH | <0.01% | $0.468189 | 27.9156 | $13.07 | |
ETH | <0.01% | $0.031767 | 408.4609 | $12.98 | |
ETH | <0.01% | $0.101222 | 128.1089 | $12.97 | |
ETH | <0.01% | <$0.000001 | 56,592,340,403.7263 | $12.92 | |
ETH | <0.01% | $3,914 | 0.00329559 | $12.9 | |
ETH | <0.01% | $0.050451 | 255.431 | $12.89 | |
ETH | <0.01% | $0.000002 | 7,097,610.2522 | $12.85 | |
ETH | <0.01% | $0.025152 | 510.7494 | $12.85 | |
ETH | <0.01% | <$0.000001 | 48,534,547.3943 | $12.83 | |
ETH | <0.01% | $0.366851 | 34.773 | $12.76 | |
ETH | <0.01% | $0.401711 | 31.6802 | $12.73 | |
ETH | <0.01% | $0.100047 | 127.1869 | $12.72 | |
ETH | <0.01% | $0.000002 | 5,757,333.749 | $12.64 | |
ETH | <0.01% | $0.463932 | 27.0674 | $12.56 | |
ETH | <0.01% | <$0.000001 | 26,682,663.2792 | $12.53 | |
ETH | <0.01% | $0.001666 | 7,519.8825 | $12.53 | |
ETH | <0.01% | $0.000001 | 11,687,618.9122 | $12.51 | |
ETH | <0.01% | <$0.000001 | 37,642,236.3282 | $12.5 | |
ETH | <0.01% | $0.26317 | 47.2447 | $12.43 | |
ETH | <0.01% | $0.00559 | 2,220.9431 | $12.41 | |
ETH | <0.01% | $0.029256 | 420.9074 | $12.31 | |
ETH | <0.01% | $0.02713 | 453.6213 | $12.31 | |
ETH | <0.01% | $0.005422 | 2,267.7232 | $12.3 | |
ETH | <0.01% | <$0.000001 | 255,166,173.0976 | $12.2 | |
ETH | <0.01% | $0.000209 | 58,423.6686 | $12.2 | |
ETH | <0.01% | $0.001504 | 8,106.3794 | $12.19 | |
ETH | <0.01% | $0.002721 | 4,471.6655 | $12.17 | |
ETH | <0.01% | <$0.000001 | 109,065,687.6926 | $12.02 | |
ETH | <0.01% | $0.000601 | 19,921.6489 | $11.98 | |
ETH | <0.01% | $0.117665 | 101.7067 | $11.97 | |
ETH | <0.01% | $0.053215 | 224.8418 | $11.96 | |
ETH | <0.01% | <$0.000001 | 24,657,950.9225 | $11.91 | |
ETH | <0.01% | $0.000922 | 12,891.2438 | $11.89 | |
ETH | <0.01% | $10.36 | 1.1393 | $11.8 | |
ETH | <0.01% | $0.996606 | 11.7435 | $11.7 | |
ETH | <0.01% | <$0.000001 | 10,253,967,227.1252 | $11.68 | |
ETH | <0.01% | $0.033739 | 346.1176 | $11.68 | |
ETH | <0.01% | <$0.000001 | 34,544,682,900.1905 | $11.61 | |
ETH | <0.01% | $0.001115 | 10,381.9094 | $11.58 | |
ETH | <0.01% | $0.0058 | 1,990.0928 | $11.54 | |
ETH | <0.01% | <$0.000001 | 36,735,667.2864 | $11.53 | |
ETH | <0.01% | $6.71 | 1.7065 | $11.45 | |
ETH | <0.01% | $0.003222 | 3,553.7186 | $11.45 | |
ETH | <0.01% | $0.127117 | 89.8451 | $11.42 | |
ETH | <0.01% | $0.004971 | 2,297.156 | $11.42 | |
ETH | <0.01% | $0.018717 | 609.5148 | $11.41 | |
ETH | <0.01% | $0.026953 | 419.4154 | $11.3 | |
ETH | <0.01% | $0.000006 | 1,926,216.7363 | $11.29 | |
ETH | <0.01% | $0.17976 | 62.6951 | $11.27 | |
ETH | <0.01% | $0.021724 | 516.1351 | $11.21 | |
ETH | <0.01% | <$0.000001 | 8,029,733,634.2022 | $11.2 | |
ETH | <0.01% | $0.005997 | 1,864.9546 | $11.18 | |
ETH | <0.01% | $1.69 | 6.5965 | $11.15 | |
ETH | <0.01% | $0.000212 | 52,288.4402 | $11.09 | |
ETH | <0.01% | $0.090382 | 121.8864 | $11.02 | |
ETH | <0.01% | $3,842.77 | 0.00284637 | $10.94 | |
ETH | <0.01% | $0.027169 | 402.499 | $10.94 | |
ETH | <0.01% | $0.000001 | 9,412,124.2731 | $10.92 | |
ETH | <0.01% | $0.000406 | 26,866.6598 | $10.92 | |
ETH | <0.01% | $0.016051 | 678.0191 | $10.88 | |
ETH | <0.01% | <$0.000001 | 4,086,993,967.8984 | $10.87 | |
ETH | <0.01% | <$0.000001 | 37,644,907,692.3882 | $10.87 | |
ETH | <0.01% | $2.35 | 4.5851 | $10.77 | |
ETH | <0.01% | $0.037897 | 283.8725 | $10.76 | |
ETH | <0.01% | $0.03028 | 354.1818 | $10.72 | |
ETH | <0.01% | $0.082263 | 129.917 | $10.69 | |
ETH | <0.01% | $0.006306 | 1,691.1434 | $10.66 | |
ETH | <0.01% | $0.000351 | 30,305.2328 | $10.65 | |
ETH | <0.01% | $0.000961 | 11,039.1705 | $10.61 | |
ETH | <0.01% | $3,539.02 | 0.0029893 | $10.58 | |
ETH | <0.01% | $0.002126 | 4,911.6427 | $10.44 | |
ETH | <0.01% | $0.541011 | 19.2877 | $10.43 | |
ETH | <0.01% | $0.074702 | 139.4517 | $10.42 | |
ETH | <0.01% | $0.006187 | 1,683.3128 | $10.41 | |
ETH | <0.01% | $0.348259 | 29.8963 | $10.41 | |
ETH | <0.01% | $0.202097 | 51.345 | $10.38 | |
ETH | <0.01% | $0.000409 | 25,203.7356 | $10.3 | |
ETH | <0.01% | $9.82 | 1.038 | $10.19 | |
ETH | <0.01% | <$0.000001 | 35,530,136,065.296 | $10.19 | |
ETH | <0.01% | $0.406218 | 25.0742 | $10.19 | |
ETH | <0.01% | <$0.000001 | 7,947,114,477.3619 | $10.15 | |
ETH | <0.01% | $0.44307 | 22.8562 | $10.13 | |
ETH | <0.01% | $0.000438 | 23,088.3669 | $10.12 | |
ETH | <0.01% | $0.000253 | 39,689.4026 | $10.05 | |
ETH | <0.01% | $0.112663 | 88.9345 | $10.02 | |
ETH | <0.01% | $0.000512 | 19,531.7487 | $10.01 | |
ETH | <0.01% | $1.65 | 6.0416 | $9.97 | |
ETH | <0.01% | <$0.000001 | 57,052,966,455.7282 | $9.82 | |
ETH | <0.01% | $0.00242 | 4,049.3742 | $9.8 | |
ETH | <0.01% | $0.167701 | 57.7224 | $9.68 | |
ETH | <0.01% | $8.12 | 1.1874 | $9.64 | |
ETH | <0.01% | $0.000919 | 10,465.6345 | $9.62 | |
ETH | <0.01% | $0.000001 | 14,959,624.8348 | $9.59 | |
ETH | <0.01% | $0.000332 | 28,863.9394 | $9.59 | |
ETH | <0.01% | $0.000106 | 90,545.4093 | $9.59 | |
ETH | <0.01% | $233.28 | 0.0411 | $9.58 | |
ETH | <0.01% | <$0.000001 | 22,195,316,861.2459 | $9.57 | |
ETH | <0.01% | $0.0019 | 5,014.3742 | $9.53 | |
ETH | <0.01% | $1.56 | 6.0845 | $9.52 | |
ETH | <0.01% | $0.002622 | 3,610.2013 | $9.47 | |
ETH | <0.01% | <$0.000001 | 24,136,092.7416 | $9.46 | |
ETH | <0.01% | $0.000844 | 11,174.7283 | $9.43 | |
ETH | <0.01% | <$0.000001 | 30,517,439,299.5976 | $9.39 | |
ETH | <0.01% | $0.000428 | 21,761.6507 | $9.32 | |
ETH | <0.01% | $0.000575 | 15,967.5696 | $9.18 | |
ETH | <0.01% | <$0.000001 | 88,896,086.5032 | $9.18 | |
ETH | <0.01% | $0.000002 | 4,891,594.7777 | $9.15 | |
ETH | <0.01% | $57,671.17 | 0.00015856 | $9.14 | |
ETH | <0.01% | $0.001243 | 7,354.5147 | $9.14 | |
ETH | <0.01% | $0.002602 | 3,497.2825 | $9.1 | |
ETH | <0.01% | $0.098875 | 92.0083 | $9.1 | |
ETH | <0.01% | $0.000142 | 64,122.7503 | $9.1 | |
ETH | <0.01% | $0.000875 | 10,323.9403 | $9.03 | |
ETH | <0.01% | $0.02301 | 390.2298 | $8.98 | |
ETH | <0.01% | $0.000449 | 19,956.9106 | $8.97 | |
ETH | <0.01% | $0.352139 | 25.4029 | $8.95 | |
ETH | <0.01% | $0.217405 | 41.1445 | $8.95 | |
ETH | <0.01% | $0.01744 | 509.7477 | $8.89 | |
ETH | <0.01% | $0.000193 | 45,601.0802 | $8.81 | |
ETH | <0.01% | $0.000179 | 48,830.8426 | $8.72 | |
ETH | <0.01% | <$0.000001 | 628,596,072.8452 | $8.72 | |
ETH | <0.01% | $0.006184 | 1,405.9192 | $8.69 | |
ETH | <0.01% | <$0.000001 | 19,803,996.8034 | $8.67 | |
ETH | <0.01% | $0.012093 | 713.1984 | $8.62 | |
ETH | <0.01% | $0.795153 | 10.8431 | $8.62 | |
ETH | <0.01% | $0.000168 | 51,230.8464 | $8.61 | |
ETH | <0.01% | <$0.000001 | 8,955,949,385.2966 | $8.6 | |
ETH | <0.01% | $238.04 | 0.0361 | $8.59 | |
ETH | <0.01% | <$0.000001 | 2,479,111,587.7816 | $8.59 | |
ETH | <0.01% | $0.009768 | 876.1976 | $8.56 | |
ETH | <0.01% | $0.011086 | 765.5513 | $8.49 | |
ETH | <0.01% | $0.101906 | 82.6262 | $8.42 | |
ETH | <0.01% | $0.99999 | 8.4058 | $8.41 | |
ETH | <0.01% | <$0.000001 | 29,356,586.4606 | $8.4 | |
ETH | <0.01% | $0.32947 | 25.3131 | $8.34 | |
ETH | <0.01% | $0.071149 | 116.6528 | $8.3 | |
ETH | <0.01% | $0.89977 | 9.1674 | $8.25 | |
ETH | <0.01% | $0.217672 | 37.8731 | $8.24 | |
ETH | <0.01% | $0.060374 | 135.9201 | $8.21 | |
ETH | <0.01% | $0.359143 | 22.7202 | $8.16 | |
ETH | <0.01% | $0.000026 | 308,212.142 | $8.12 | |
ETH | <0.01% | $0.214242 | 37.7256 | $8.08 | |
ETH | <0.01% | $0.002035 | 3,962.3528 | $8.06 | |
ETH | <0.01% | $0.325384 | 24.7607 | $8.06 | |
ETH | <0.01% | <$0.000001 | 20,962,060.3974 | $8.05 | |
ETH | <0.01% | $0.782276 | 10.2183 | $7.99 | |
ETH | <0.01% | $9.48 | 0.8414 | $7.98 | |
ETH | <0.01% | $0.000121 | 65,716.4061 | $7.94 | |
ETH | <0.01% | $0.000855 | 9,226.0533 | $7.89 | |
ETH | <0.01% | <$0.000001 | 115,255,319,242.4855 | $7.82 | |
ETH | <0.01% | $0.041898 | 186.0432 | $7.79 | |
ETH | <0.01% | $0.000003 | 2,354,361.8735 | $7.77 | |
ETH | <0.01% | $0.00001 | 802,275.9878 | $7.73 | |
ETH | <0.01% | $0.000094 | 81,678.975 | $7.69 | |
ETH | <0.01% | $0.009769 | 783.4668 | $7.65 | |
ETH | <0.01% | <$0.000001 | 35,195,656,483.6675 | $7.65 | |
ETH | <0.01% | $0.027702 | 275.5107 | $7.63 | |
ETH | <0.01% | $0.106144 | 71.8031 | $7.62 | |
ETH | <0.01% | $0.289487 | 26.2038 | $7.59 | |
ETH | <0.01% | $0.688494 | 10.9801 | $7.56 | |
ETH | <0.01% | $0.011289 | 664.3707 | $7.5 | |
ETH | <0.01% | <$0.000001 | 6,275,619,180.78 | $7.43 | |
ETH | <0.01% | $0.020813 | 355.4874 | $7.4 | |
ETH | <0.01% | <$0.000001 | 70,479,449.726 | $7.36 | |
ETH | <0.01% | $0.00045 | 16,305.4045 | $7.34 | |
ETH | <0.01% | $155,737.54 | 0.00004685 | $7.3 | |
ETH | <0.01% | <$0.000001 | 96,871,828.6163 | $7.29 | |
ETH | <0.01% | $0.000001 | 5,616,547.641 | $7.18 | |
ETH | <0.01% | $0.00018 | 39,657.4033 | $7.12 | |
ETH | <0.01% | $0.020815 | 342.1432 | $7.12 | |
ETH | <0.01% | $0.033356 | 212.9171 | $7.1 | |
ETH | <0.01% | $0.728853 | 9.7397 | $7.1 | |
ETH | <0.01% | $0.022572 | 314.4692 | $7.1 | |
ETH | <0.01% | $0.00025 | 28,261.9804 | $7.06 | |
ETH | <0.01% | $0.001882 | 3,752.6814 | $7.06 | |
ETH | <0.01% | $0.01181 | 593.2568 | $7.01 | |
ETH | <0.01% | $0.437818 | 15.9369 | $6.98 | |
ETH | <0.01% | $0.166729 | 41.5301 | $6.92 | |
ETH | <0.01% | $0.00026 | 26,448.5666 | $6.88 | |
ETH | <0.01% | $0.063126 | 108.1894 | $6.83 | |
ETH | <0.01% | $0.000013 | 519,519.8489 | $6.82 | |
ETH | <0.01% | $0.000568 | 11,902.7217 | $6.76 | |
ETH | <0.01% | $0.004561 | 1,482.111 | $6.76 | |
ETH | <0.01% | $0.072411 | 93.1176 | $6.74 | |
ETH | <0.01% | $0.114245 | 58.9862 | $6.74 | |
ETH | <0.01% | $0.11051 | 60.977 | $6.74 | |
ETH | <0.01% | $155.24 | 0.0433 | $6.72 | |
ETH | <0.01% | $0.444358 | 15.0335 | $6.68 | |
ETH | <0.01% | $0.007878 | 845.2824 | $6.66 | |
ETH | <0.01% | <$0.000001 | 9,819,103,551.6829 | $6.65 | |
ETH | <0.01% | $0.000503 | 13,169.2808 | $6.63 | |
ETH | <0.01% | $1.02 | 6.4715 | $6.6 | |
ETH | <0.01% | $1.93 | 3.4218 | $6.59 | |
ETH | <0.01% | <$0.000001 | 197,859,613.0156 | $6.57 | |
ETH | <0.01% | $0.012775 | 512.9285 | $6.55 | |
ETH | <0.01% | $0.000084 | 77,772.2105 | $6.51 | |
ETH | <0.01% | $65.95 | 0.0979 | $6.45 | |
ETH | <0.01% | <$0.000001 | 3,693,654,863,924.5864 | $6.45 | |
ETH | <0.01% | $0.039885 | 161.7242 | $6.45 | |
ETH | <0.01% | $0.172849 | 37.2598 | $6.44 | |
ETH | <0.01% | $0.025544 | 249.6712 | $6.38 | |
ETH | <0.01% | <$0.000001 | 36,946,806.7243 | $6.34 | |
ETH | <0.01% | $0.000152 | 41,586.2319 | $6.32 | |
ETH | <0.01% | <$0.000001 | 49,988,504.0556 | $6.32 | |
ETH | <0.01% | $0.000255 | 24,653.2588 | $6.29 | |
ETH | <0.01% | $0.000407 | 15,416.1673 | $6.27 | |
ETH | <0.01% | $0.004869 | 1,276.3901 | $6.21 | |
ETH | <0.01% | $0.000336 | 18,241.7217 | $6.13 | |
ETH | <0.01% | <$0.000001 | 12,960,046.1999 | $6.11 | |
ETH | <0.01% | $0.000256 | 23,828.7194 | $6.1 | |
ETH | <0.01% | <$0.000001 | 48,525,697.4951 | $6 | |
ETH | <0.01% | $0.114552 | 51.9746 | $5.95 | |
ETH | <0.01% | $0.000114 | 52,036.6591 | $5.92 | |
ETH | <0.01% | $0.000059 | 100,219.2008 | $5.88 | |
ETH | <0.01% | $0.079823 | 73.236 | $5.85 | |
ETH | <0.01% | $4.32 | 1.3531 | $5.84 | |
ETH | <0.01% | $0.000596 | 9,795.8575 | $5.84 | |
ETH | <0.01% | $0.000045 | 128,978.7572 | $5.81 | |
ETH | <0.01% | $0.000001 | 5,322,427.7053 | $5.8 | |
ETH | <0.01% | $0.136221 | 42.5855 | $5.8 | |
ETH | <0.01% | $0.000002 | 2,953,137.5214 | $5.77 | |
ETH | <0.01% | $0.012375 | 465.3934 | $5.76 | |
ETH | <0.01% | $0.00344 | 1,671.8821 | $5.75 | |
ETH | <0.01% | <$0.000001 | 86,745,848.961 | $5.73 | |
ETH | <0.01% | $0.544364 | 10.4871 | $5.71 | |
ETH | <0.01% | <$0.000001 | 33,578,715.4269 | $5.71 | |
ETH | <0.01% | $3,580.07 | 0.00158588 | $5.68 | |
ETH | <0.01% | $0.181192 | 31.2693 | $5.67 | |
ETH | <0.01% | $0.074868 | 75.658 | $5.66 | |
ETH | <0.01% | $0.005939 | 953.7137 | $5.66 | |
ETH | <0.01% | $1.2 | 4.6967 | $5.64 | |
ETH | <0.01% | <$0.000001 | 31,676,888,560.9041 | $5.63 | |
ETH | <0.01% | $0.404162 | 13.93 | $5.63 | |
ETH | <0.01% | <$0.000001 | 10,037,259,972.3222 | $5.62 | |
ETH | <0.01% | $0.000585 | 9,593.5494 | $5.62 | |
ETH | <0.01% | $0.022688 | 244.2063 | $5.54 | |
ETH | <0.01% | $0.000074 | 74,697.6509 | $5.53 | |
ETH | <0.01% | $0.000077 | 71,457.7999 | $5.48 | |
ETH | <0.01% | <$0.000001 | 44,110,740.7518 | $5.48 | |
ETH | <0.01% | <$0.000001 | 568,175,221.0745 | $5.39 | |
ETH | <0.01% | $0.159141 | 33.7649 | $5.37 | |
ETH | <0.01% | $0.998055 | 5.3823 | $5.37 | |
ETH | <0.01% | $0.264661 | 20.2413 | $5.36 | |
ETH | <0.01% | $0.119472 | 44.8218 | $5.35 | |
ETH | <0.01% | $0.000435 | 12,278.2761 | $5.34 | |
ETH | <0.01% | $13.02 | 0.4098 | $5.34 | |
ETH | <0.01% | $0.007414 | 715.3628 | $5.3 | |
ETH | <0.01% | $0.244001 | 21.646 | $5.28 | |
ETH | <0.01% | $9.78 | 0.5393 | $5.27 | |
ETH | <0.01% | $0.031338 | 167.6829 | $5.25 | |
ETH | <0.01% | $3,439.75 | 0.00151978 | $5.23 | |
ETH | <0.01% | $0.035707 | 145.8121 | $5.21 | |
ETH | <0.01% | <$0.000001 | 33,877,746.5193 | $5.2 | |
ETH | <0.01% | $0.000003 | 1,617,883.1853 | $5.19 | |
ETH | <0.01% | $0.802081 | 6.4746 | $5.19 | |
ETH | <0.01% | $0.001002 | 5,168.4241 | $5.18 | |
ETH | <0.01% | $0.005971 | 867.1017 | $5.18 | |
ETH | <0.01% | $0.000879 | 5,817.6659 | $5.12 | |
ETH | <0.01% | $0.011804 | 433.0441 | $5.11 | |
ETH | <0.01% | $0.00297 | 1,714.7743 | $5.09 | |
ETH | <0.01% | $0.001696 | 2,993.1918 | $5.08 | |
ETH | <0.01% | $0.051733 | 98.097 | $5.07 | |
ETH | <0.01% | $0.051065 | 99.1636 | $5.06 | |
ETH | <0.01% | <$0.000001 | 17,298,365,827.7661 | $4.98 | |
ETH | <0.01% | $0.183349 | 27.1125 | $4.97 | |
ETH | <0.01% | $0.000005 | 940,176.3051 | $4.97 | |
ETH | <0.01% | $0.040146 | 123.0456 | $4.94 | |
ETH | <0.01% | $0.03164 | 155.7517 | $4.93 | |
ETH | <0.01% | $0.233318 | 21.1108 | $4.93 | |
ETH | <0.01% | $26.05 | 0.1884 | $4.91 | |
ETH | <0.01% | <$0.000001 | 9,421,534,638.3355 | $4.9 | |
ETH | <0.01% | $0.003234 | 1,507.264 | $4.87 | |
ETH | <0.01% | <$0.000001 | 105,602,097.4593 | $4.85 | |
ETH | <0.01% | <$0.000001 | 6,208,072,616.0676 | $4.77 | |
ETH | <0.01% | <$0.000001 | 38,033,481.3173 | $4.77 | |
ETH | <0.01% | $0.049871 | 95.155 | $4.75 | |
ETH | <0.01% | $0.000404 | 11,709.8408 | $4.73 | |
ETH | <0.01% | $0.001074 | 4,404.7529 | $4.73 | |
ETH | <0.01% | $0.016025 | 295.0831 | $4.73 | |
ETH | <0.01% | $0.000001 | 6,415,642.9585 | $4.73 | |
ETH | <0.01% | $1.57 | 3.0019 | $4.71 | |
ETH | <0.01% | <$0.000001 | 19,069,761.6694 | $4.68 | |
ETH | <0.01% | $18.97 | 0.2465 | $4.68 | |
ETH | <0.01% | <$0.000001 | 237,508,159.8186 | $4.65 | |
ETH | <0.01% | $0.005058 | 919.5539 | $4.65 | |
ETH | <0.01% | $0.000672 | 6,913.2011 | $4.65 | |
ETH | <0.01% | $0.003434 | 1,347.7287 | $4.63 | |
ETH | <0.01% | $1.14 | 3.9925 | $4.55 | |
ETH | <0.01% | $0.01254 | 361.1733 | $4.53 | |
ETH | <0.01% | $0.000314 | 14,402.4083 | $4.52 | |
ETH | <0.01% | $0.000575 | 7,857.1697 | $4.51 | |
ETH | <0.01% | <$0.000001 | 60,155,219,388,212.313 | $4.51 | |
ETH | <0.01% | $0.013305 | 336.9082 | $4.48 | |
ETH | <0.01% | $0.00005 | 89,196.1373 | $4.47 | |
ETH | <0.01% | $0.001083 | 4,115.6501 | $4.46 | |
ETH | <0.01% | $1.27 | 3.4987 | $4.44 | |
ETH | <0.01% | $0.044716 | 98.6322 | $4.41 | |
ETH | <0.01% | $0.000001 | 7,564,608.3125 | $4.39 | |
ETH | <0.01% | $0.000021 | 213,138.0751 | $4.38 | |
ETH | <0.01% | $0.001605 | 2,710.7352 | $4.35 | |
ETH | <0.01% | $0.040277 | 107.6064 | $4.33 | |
ETH | <0.01% | $0.000016 | 266,627.1306 | $4.32 | |
ETH | <0.01% | $0.002283 | 1,878.9117 | $4.29 | |
ETH | <0.01% | $0.127319 | 33.5972 | $4.28 | |
ETH | <0.01% | $0.103326 | 41.3429 | $4.27 | |
ETH | <0.01% | $0.000514 | 8,181.8982 | $4.21 | |
ETH | <0.01% | $0.18653 | 22.4717 | $4.19 | |
ETH | <0.01% | $0.008609 | 484.3544 | $4.17 | |
ETH | <0.01% | $0.003257 | 1,275.2726 | $4.15 | |
ETH | <0.01% | $0.000019 | 221,172.6119 | $4.15 | |
ETH | <0.01% | $1.93 | 2.1374 | $4.13 | |
ETH | <0.01% | $0.104006 | 39.5849 | $4.12 | |
ETH | <0.01% | $0.000938 | 4,359.8488 | $4.09 | |
ETH | <0.01% | $0.057534 | 70.978 | $4.08 | |
ETH | <0.01% | $0.000155 | 26,343.2488 | $4.08 | |
ETH | <0.01% | $0.0018 | 2,236.6735 | $4.03 | |
ETH | <0.01% | $0.000001 | 7,434,795.7176 | $4.01 | |
ETH | <0.01% | $0.000428 | 9,377.552 | $4.01 | |
ETH | <0.01% | $0.00001 | 402,459.6481 | $4 | |
ETH | <0.01% | $0.042759 | 93.468 | $4 | |
ETH | <0.01% | $0.058995 | 67.627 | $3.99 | |
ETH | <0.01% | $0.000003 | 1,280,907.455 | $3.98 | |
ETH | <0.01% | $0.006238 | 638.4541 | $3.98 | |
ETH | <0.01% | $0.00047 | 8,446.0648 | $3.97 | |
ETH | <0.01% | $0.089555 | 43.9614 | $3.94 | |
ETH | <0.01% | <$0.000001 | 2,265,074,300.9608 | $3.89 | |
ETH | <0.01% | <$0.000001 | 26,017,605.5542 | $3.85 | |
ETH | <0.01% | $0.010306 | 372.476 | $3.84 | |
ETH | <0.01% | <$0.000001 | 28,448,938.8353 | $3.84 | |
ETH | <0.01% | $0.026429 | 144.0934 | $3.81 | |
ETH | <0.01% | $0.009285 | 409.2123 | $3.8 | |
ETH | <0.01% | $0.021178 | 179.3995 | $3.8 | |
ETH | <0.01% | $0.000108 | 35,129.7698 | $3.78 | |
ETH | <0.01% | $19.1 | 0.1973 | $3.77 | |
ETH | <0.01% | $0.000869 | 4,272.791 | $3.71 | |
ETH | <0.01% | $0.000073 | 50,252.4088 | $3.66 | |
ETH | <0.01% | $0.21703 | 16.793 | $3.64 | |
ETH | <0.01% | $0.000395 | 9,214.0245 | $3.64 | |
ETH | <0.01% | $0.33071 | 10.99 | $3.63 | |
ETH | <0.01% | <$0.000001 | 71,247,344.174 | $3.63 | |
ETH | <0.01% | <$0.000001 | 14,429,081,971.1618 | $3.62 | |
ETH | <0.01% | $0.001025 | 3,496.3321 | $3.58 | |
ETH | <0.01% | $0.000307 | 11,607.7573 | $3.56 | |
ETH | <0.01% | $0.000244 | 14,430.1968 | $3.52 | |
ETH | <0.01% | $0.107826 | 32.5595 | $3.51 | |
ETH | <0.01% | $0.010132 | 345.3361 | $3.5 | |
ETH | <0.01% | $2.26 | 1.5396 | $3.49 | |
ETH | <0.01% | <$0.000001 | 1,051,114,745.3281 | $3.48 | |
ETH | <0.01% | <$0.000001 | 13,375,459.4682 | $3.47 | |
ETH | <0.01% | <$0.000001 | 21,999,407.6497 | $3.46 | |
ETH | <0.01% | $0.000001 | 6,673,417.1828 | $3.42 | |
ETH | <0.01% | $0.002881 | 1,181.4039 | $3.4 | |
ETH | <0.01% | <$0.000001 | 2,453,187,450.2241 | $3.39 | |
ETH | <0.01% | $0.000001 | 6,411,833.567 | $3.38 | |
ETH | <0.01% | $0.000117 | 28,740.6382 | $3.36 | |
ETH | <0.01% | $279.26 | 0.012 | $3.36 | |
ETH | <0.01% | $0.000171 | 19,383.8993 | $3.32 | |
ETH | <0.01% | $0.000057 | 57,617.1082 | $3.31 | |
ETH | <0.01% | <$0.000001 | 58,527,974,011.2244 | $3.31 | |
ETH | <0.01% | <$0.000001 | 327,461,613,037.5703 | $3.3 | |
ETH | <0.01% | $0.007382 | 441.5128 | $3.26 | |
ETH | <0.01% | <$0.000001 | 3,667,549,733.7878 | $3.26 | |
ETH | <0.01% | $0.000001 | 5,814,999.5743 | $3.23 | |
ETH | <0.01% | $0.109024 | 29.4461 | $3.21 | |
ETH | <0.01% | $20.63 | 0.1553 | $3.2 | |
ETH | <0.01% | $0.02639 | 121.3645 | $3.2 | |
ETH | <0.01% | <$0.000001 | 18,598,603,163.6573 | $3.2 | |
ETH | <0.01% | $0.009396 | 339.0176 | $3.19 | |
ETH | <0.01% | $0.045188 | 70.287 | $3.18 | |
ETH | <0.01% | $0.000837 | 3,785.2708 | $3.17 | |
ETH | <0.01% | <$0.000001 | 234,211,409.2599 | $3.16 | |
ETH | <0.01% | $8.76 | 0.357 | $3.13 | |
ETH | <0.01% | $0.001506 | 2,073.5021 | $3.12 | |
ETH | <0.01% | $0.001367 | 2,274.5928 | $3.11 | |
ETH | <0.01% | $0.041677 | 74.2843 | $3.1 | |
ETH | <0.01% | $0.580205 | 5.333 | $3.09 | |
ETH | <0.01% | <$0.000001 | 13,768,945.516 | $3.09 | |
ETH | <0.01% | $0.002018 | 1,517.5855 | $3.06 | |
ETH | <0.01% | <$0.000001 | 6,424,363.7066 | $3.06 | |
ETH | <0.01% | $0.016748 | 181.8266 | $3.05 | |
ETH | <0.01% | $0.00386 | 786.5972 | $3.04 | |
ETH | <0.01% | $3.98 | 0.76 | $3.02 | |
ETH | <0.01% | <$0.000001 | 6,144,297,366.8298 | $3.02 | |
ETH | <0.01% | $5.92 | 0.5098 | $3.02 | |
ETH | <0.01% | <$0.000001 | 43,331,327.1174 | $3.01 | |
ETH | <0.01% | $0.001302 | 2,297.4343 | $2.99 | |
ETH | <0.01% | $17.27 | 0.1723 | $2.98 | |
ETH | <0.01% | $0.002387 | 1,235.8917 | $2.95 | |
ETH | <0.01% | <$0.000001 | 609,587,624.9014 | $2.94 | |
ETH | <0.01% | $0.128809 | 22.5944 | $2.91 | |
ETH | <0.01% | $0.000001 | 2,246,673.4678 | $2.88 | |
ETH | <0.01% | <$0.000001 | 553,528,680.9375 | $2.87 | |
ETH | <0.01% | <$0.000001 | 25,409,245.1481 | $2.86 | |
ETH | <0.01% | $6.27 | 0.4552 | $2.85 | |
ETH | <0.01% | $0.549129 | 5.1957 | $2.85 | |
ETH | <0.01% | $0.010782 | 263.9382 | $2.85 | |
ETH | <0.01% | $0.103998 | 27.3189 | $2.84 | |
ETH | <0.01% | $0.001199 | 2,368.1515 | $2.84 | |
ETH | <0.01% | <$0.000001 | 16,035,333.4151 | $2.82 | |
ETH | <0.01% | <$0.000001 | 32,488,220.1476 | $2.82 | |
ETH | <0.01% | $1.66 | 1.695 | $2.81 | |
ETH | <0.01% | $0.000131 | 21,395.8136 | $2.8 | |
ETH | <0.01% | $4.88 | 0.5697 | $2.78 | |
ETH | <0.01% | $0.998005 | 2.7826 | $2.78 | |
ETH | <0.01% | $0.000622 | 4,437.9155 | $2.76 | |
ETH | <0.01% | $0.000001 | 4,776,642.1214 | $2.74 | |
ETH | <0.01% | $0.021232 | 128.8165 | $2.73 | |
ETH | <0.01% | $0.014966 | 181.958 | $2.72 | |
ETH | <0.01% | $0.00066 | 4,081.4598 | $2.69 | |
ETH | <0.01% | $0.000756 | 3,537.6635 | $2.68 | |
ETH | <0.01% | $0.000001 | 4,319,570.8283 | $2.67 | |
ETH | <0.01% | <$0.000001 | 7,624,194.2304 | $2.67 | |
ETH | <0.01% | $0.380246 | 7.0217 | $2.67 | |
ETH | <0.01% | <$0.000001 | 359,995,947.116 | $2.66 | |
ETH | <0.01% | $0.108892 | 24.4224 | $2.66 | |
ETH | <0.01% | $0.000151 | 17,578.6226 | $2.66 | |
ETH | <0.01% | $0.049336 | 53.7793 | $2.65 | |
ETH | <0.01% | $0.020266 | 130.6539 | $2.65 | |
ETH | <0.01% | <$0.000001 | 5,261,460,968.215 | $2.65 | |
ETH | <0.01% | $0.801209 | 3.3016 | $2.65 | |
ETH | <0.01% | $0.000107 | 24,574.176 | $2.63 | |
ETH | <0.01% | <$0.000001 | 15,091,673,693.1254 | $2.63 | |
ETH | <0.01% | $1.15 | 2.2577 | $2.6 | |
ETH | <0.01% | $0.001451 | 1,788.594 | $2.6 | |
ETH | <0.01% | $0.65618 | 3.9195 | $2.57 | |
ETH | <0.01% | $0.006415 | 396.551 | $2.54 | |
ETH | <0.01% | $0.110147 | 22.9586 | $2.53 | |
ETH | <0.01% | $0.000032 | 79,135.0827 | $2.52 | |
ETH | <0.01% | $0.000003 | 838,438.7709 | $2.52 | |
ETH | <0.01% | $3,282.15 | 0.00076531 | $2.51 | |
ETH | <0.01% | $0.000055 | 45,062.6772 | $2.5 | |
ETH | <0.01% | $0.000015 | 170,793.3778 | $2.5 | |
ETH | <0.01% | $0.000152 | 16,352.0243 | $2.49 | |
ETH | <0.01% | $0.000084 | 29,598.1778 | $2.49 | |
ETH | <0.01% | $0.001563 | 1,571.5338 | $2.46 | |
ETH | <0.01% | $0.000022 | 113,092.551 | $2.45 | |
ETH | <0.01% | <$0.000001 | 74,206,743.1411 | $2.45 | |
ETH | <0.01% | $0.000353 | 6,925.2749 | $2.45 | |
ETH | <0.01% | $0.000758 | 3,216.0729 | $2.44 | |
ETH | <0.01% | $0.001698 | 1,432.473 | $2.43 | |
ETH | <0.01% | $0.004574 | 531.6471 | $2.43 | |
ETH | <0.01% | <$0.000001 | 1,478,234,334,486.8916 | $2.43 | |
ETH | <0.01% | $0.001038 | 2,340.8289 | $2.43 | |
ETH | <0.01% | $0.003652 | 664.7175 | $2.43 | |
ETH | <0.01% | $0.001312 | 1,848.1524 | $2.43 | |
ETH | <0.01% | $0.000568 | 4,267.0561 | $2.42 | |
ETH | <0.01% | $0.000091 | 26,648.7467 | $2.42 | |
ETH | <0.01% | $0.01349 | 177.5969 | $2.4 | |
ETH | <0.01% | $0.000873 | 2,741.8731 | $2.39 | |
ETH | <0.01% | <$0.000001 | 19,769,991.919 | $2.37 | |
ETH | <0.01% | $0.000002 | 1,007,449.616 | $2.36 | |
ETH | <0.01% | $0.000003 | 878,206.3977 | $2.35 | |
ETH | <0.01% | $0.000479 | 4,892.189 | $2.34 | |
ETH | <0.01% | $0.000021 | 110,100.8276 | $2.34 | |
ETH | <0.01% | $0.00002 | 115,741.0611 | $2.33 | |
ETH | <0.01% | $0.032639 | 70.9019 | $2.31 | |
ETH | <0.01% | $0.081991 | 28.192 | $2.31 | |
ETH | <0.01% | $0.000148 | 15,604.9599 | $2.31 | |
ETH | <0.01% | $0.01143 | 201.6088 | $2.3 | |
ETH | <0.01% | $0.000002 | 1,243,882.8702 | $2.3 | |
ETH | <0.01% | <$0.000001 | 37,962,284,257.0997 | $2.27 | |
ETH | <0.01% | $0.000513 | 4,408.7704 | $2.26 | |
ETH | <0.01% | $0.032333 | 69.4557 | $2.25 | |
ETH | <0.01% | $0.000005 | 458,086.6262 | $2.24 | |
ETH | <0.01% | $0.530081 | 4.1862 | $2.22 | |
ETH | <0.01% | $0.000061 | 36,504.8023 | $2.21 | |
ETH | <0.01% | $0.543156 | 4.0542 | $2.2 | |
ETH | <0.01% | $0.01026 | 213.4543 | $2.19 | |
ETH | <0.01% | $0.00592 | 367.4698 | $2.18 | |
ETH | <0.01% | <$0.000001 | 4,245,934,992.0473 | $2.16 | |
ETH | <0.01% | <$0.000001 | 11,809,471.5655 | $2.16 | |
ETH | <0.01% | $0.016457 | 129.7209 | $2.13 | |
ETH | <0.01% | $0.00109 | 1,943.1429 | $2.12 | |
ETH | <0.01% | $0.002579 | 809.0656 | $2.09 | |
ETH | <0.01% | $0.000028 | 75,562.2037 | $2.08 | |
ETH | <0.01% | $0.544364 | 3.8092 | $2.07 | |
ETH | <0.01% | $0.001294 | 1,595.9196 | $2.07 | |
ETH | <0.01% | <$0.000001 | 624,832,015.7508 | $2.06 | |
ETH | <0.01% | $5.63 | 0.3618 | $2.04 | |
ETH | <0.01% | $0.002409 | 842.7513 | $2.03 | |
ETH | <0.01% | $0.057747 | 34.8577 | $2.01 | |
ETH | <0.01% | $0.063198 | 31.7805 | $2.01 | |
ETH | <0.01% | $0.350383 | 5.7213 | $2 | |
ETH | <0.01% | $0.270777 | 7.4035 | $2 | |
ETH | <0.01% | <$0.000001 | 10,729,113,213.33 | $2 | |
ETH | <0.01% | <$0.000001 | 64,525,534.309 | $2 | |
ETH | <0.01% | $0.026339 | 75.866 | $2 | |
ETH | <0.01% | $0.000158 | 12,613.316 | $2 | |
ETH | <0.01% | $15.72 | 0.1268 | $1.99 | |
ETH | <0.01% | $0.000721 | 2,761.0118 | $1.99 | |
ETH | <0.01% | $0.000478 | 4,163.3549 | $1.99 | |
ETH | <0.01% | <$0.000001 | 12,434,446.9448 | $1.98 | |
ETH | <0.01% | $0.009236 | 212.3067 | $1.96 | |
ETH | <0.01% | $0.015515 | 126.1817 | $1.96 | |
ETH | <0.01% | $19.96 | 0.098 | $1.96 | |
ETH | <0.01% | $0.044361 | 43.9536 | $1.95 | |
ETH | <0.01% | $0.004336 | 449.4858 | $1.95 | |
ETH | <0.01% | $0.000028 | 70,154.6774 | $1.95 | |
ETH | <0.01% | $0.118307 | 16.2844 | $1.93 | |
ETH | <0.01% | $0.000005 | 354,816.0935 | $1.92 | |
ETH | <0.01% | $17.29 | 0.111 | $1.92 | |
ETH | <0.01% | $0.000734 | 2,606.159 | $1.91 | |
ETH | <0.01% | <$0.000001 | 443,715,990.8011 | $1.91 | |
ETH | <0.01% | $0.000642 | 2,970.6681 | $1.91 | |
ETH | <0.01% | $0.000062 | 30,763.4155 | $1.9 | |
ETH | <0.01% | $0.000485 | 3,896.0655 | $1.89 | |
ETH | <0.01% | $0.167966 | 11.2196 | $1.88 | |
ETH | <0.01% | $0.106598 | 17.6314 | $1.88 | |
ETH | <0.01% | $0.000183 | 10,209.7473 | $1.87 | |
ETH | <0.01% | $0.000703 | 2,629.8261 | $1.85 | |
ETH | <0.01% | $0.054397 | 33.9143 | $1.84 | |
ETH | <0.01% | $0.001248 | 1,477.7009 | $1.84 | |
ETH | <0.01% | $0.002643 | 696.4693 | $1.84 | |
ETH | <0.01% | $0.000003 | 647,788.871 | $1.84 | |
ETH | <0.01% | $0.000002 | 798,880.2268 | $1.84 | |
ETH | <0.01% | $0.001043 | 1,759.8374 | $1.84 | |
ETH | <0.01% | <$0.000001 | 5,145,095.5296 | $1.83 | |
ETH | <0.01% | $0.000757 | 2,417.2654 | $1.83 | |
ETH | <0.01% | <$0.000001 | 3,249,697,617.7775 | $1.83 | |
ETH | <0.01% | $0.000001 | 3,522,982.5465 | $1.82 | |
ETH | <0.01% | $0.000154 | 11,862.3025 | $1.82 | |
ETH | <0.01% | $0.003282 | 555.3552 | $1.82 | |
ETH | <0.01% | $0.000197 | 9,129.4219 | $1.8 | |
ETH | <0.01% | $0.001571 | 1,133.5786 | $1.78 | |
ETH | <0.01% | $0.025229 | 70.4901 | $1.78 | |
ETH | <0.01% | $0.126869 | 13.9756 | $1.77 | |
ETH | <0.01% | <$0.000001 | 176,579,335.3048 | $1.76 | |
ETH | <0.01% | $0.002907 | 601.6749 | $1.75 | |
ETH | <0.01% | $0.016974 | 102.5635 | $1.74 | |
ETH | <0.01% | $0.001856 | 932.1157 | $1.73 | |
ETH | <0.01% | <$0.000001 | 9,902,839.3755 | $1.73 | |
ETH | <0.01% | $0.000115 | 15,030.0204 | $1.72 | |
ETH | <0.01% | $0.000136 | 12,570.5328 | $1.71 | |
ETH | <0.01% | <$0.000001 | 6,603,518,467.5821 | $1.68 | |
ETH | <0.01% | $0.001889 | 888.7565 | $1.68 | |
ETH | <0.01% | $0.000014 | 116,954.7094 | $1.65 | |
ETH | <0.01% | $0.007442 | 221.3156 | $1.65 | |
ETH | <0.01% | $0.073527 | 22.3024 | $1.64 | |
ETH | <0.01% | $0.18582 | 8.7336 | $1.62 | |
ETH | <0.01% | $0.069824 | 23.0569 | $1.61 | |
ETH | <0.01% | $0.008887 | 181.0486 | $1.61 | |
ETH | <0.01% | $0.198293 | 8.1074 | $1.61 | |
ETH | <0.01% | $0.000036 | 44,251.3462 | $1.6 | |
ETH | <0.01% | $0.000774 | 2,066.2768 | $1.6 | |
ETH | <0.01% | $0.000003 | 509,058.3367 | $1.6 | |
ETH | <0.01% | $0.000182 | 8,795.4023 | $1.6 | |
ETH | <0.01% | $0.000015 | 105,136.5286 | $1.59 | |
ETH | <0.01% | $0.005033 | 313.6339 | $1.58 | |
ETH | <0.01% | $42.74 | 0.0363 | $1.55 | |
ETH | <0.01% | $0.110757 | 13.9391 | $1.54 | |
ETH | <0.01% | $0.000037 | 41,220.9533 | $1.54 | |
ETH | <0.01% | $0.000933 | 1,646.0455 | $1.54 | |
ETH | <0.01% | <$0.000001 | 31,243,189,788.6565 | $1.54 | |
ETH | <0.01% | <$0.000001 | 6,575,831,829.7018 | $1.54 | |
ETH | <0.01% | $0.000015 | 100,021.3472 | $1.53 | |
ETH | <0.01% | $0.000153 | 9,975.1668 | $1.53 | |
ETH | <0.01% | $0.002654 | 573.8037 | $1.52 | |
ETH | <0.01% | $6.52 | 0.2325 | $1.52 | |
ETH | <0.01% | $0.001212 | 1,249.1495 | $1.51 | |
ETH | <0.01% | <$0.000001 | 19,900,395,948.3776 | $1.51 | |
ETH | <0.01% | $0.000835 | 1,804.5028 | $1.51 | |
ETH | <0.01% | $0.00241 | 624.2855 | $1.5 | |
ETH | <0.01% | $0.009375 | 160.31 | $1.5 | |
ETH | <0.01% | <$0.000001 | 12,266,101.3869 | $1.5 | |
ETH | <0.01% | $0.049737 | 30.0393 | $1.49 | |
ETH | <0.01% | $0.000475 | 3,139.3652 | $1.49 | |
ETH | <0.01% | <$0.000001 | 8,403,850,478,216,195 | $1.49 | |
ETH | <0.01% | $0.022615 | 65.168 | $1.47 | |
ETH | <0.01% | <$0.000001 | 3,524,913.536 | $1.47 | |
ETH | <0.01% | $0.000074 | 19,760.2157 | $1.47 | |
ETH | <0.01% | $0.148585 | 9.8335 | $1.46 | |
ETH | <0.01% | $0.007139 | 202.3569 | $1.44 | |
ETH | <0.01% | $0.003808 | 374.3922 | $1.43 | |
ETH | <0.01% | <$0.000001 | 50,896,733,571.0823 | $1.42 | |
ETH | <0.01% | $0.004703 | 302.4338 | $1.42 | |
ETH | <0.01% | $0.157798 | 8.97 | $1.42 | |
ETH | <0.01% | $0.02883 | 49.0732 | $1.41 | |
ETH | <0.01% | $0.000689 | 2,030.6511 | $1.4 | |
ETH | <0.01% | $0.015077 | 92.7011 | $1.4 | |
ETH | <0.01% | $9.32 | 0.1498 | $1.4 | |
ETH | <0.01% | $0.115589 | 12.0445 | $1.39 | |
ETH | <0.01% | $0.016792 | 82.2272 | $1.38 | |
ETH | <0.01% | $0.000055 | 24,961.4801 | $1.38 | |
ETH | <0.01% | $0.011478 | 118.6238 | $1.36 | |
ETH | <0.01% | $0.021107 | 63.8531 | $1.35 | |
ETH | <0.01% | $0.00502 | 268.1095 | $1.35 | |
ETH | <0.01% | $0.349314 | 3.8395 | $1.34 | |
ETH | <0.01% | <$0.000001 | 220,017,222.9466 | $1.34 | |
ETH | <0.01% | $0.000009 | 152,885.0553 | $1.34 | |
ETH | <0.01% | $0.303707 | 4.3848 | $1.33 | |
ETH | <0.01% | $0.000916 | 1,452.8904 | $1.33 | |
ETH | <0.01% | $0.038177 | 34.3132 | $1.31 | |
ETH | <0.01% | $0.017968 | 72.7588 | $1.31 | |
ETH | <0.01% | $0.0356 | 36.4222 | $1.3 | |
ETH | <0.01% | $0.00004 | 32,618.2787 | $1.3 | |
ETH | <0.01% | $0.001177 | 1,085.9346 | $1.28 | |
ETH | <0.01% | $0.008324 | 153.1633 | $1.28 | |
ETH | <0.01% | <$0.000001 | 403,935,651.2698 | $1.27 | |
ETH | <0.01% | $0.011404 | 110.9454 | $1.27 | |
ETH | <0.01% | $0.000031 | 40,259.8037 | $1.25 | |
ETH | <0.01% | <$0.000001 | 20,738,159,030.3704 | $1.24 | |
ETH | <0.01% | <$0.000001 | 14,253,074.0127 | $1.23 | |
ETH | <0.01% | $0.000258 | 4,764.0169 | $1.23 | |
ETH | <0.01% | <$0.000001 | 5,311,672.2875 | $1.23 | |
ETH | <0.01% | $0.000124 | 9,818.7509 | $1.22 | |
ETH | <0.01% | $0.034305 | 35.3288 | $1.21 | |
ETH | <0.01% | $0.00109 | 1,110.2382 | $1.21 | |
ETH | <0.01% | $0.000639 | 1,888.8779 | $1.21 | |
ETH | <0.01% | $0.004688 | 256.5824 | $1.2 | |
ETH | <0.01% | $0.004239 | 282.3262 | $1.2 | |
ETH | <0.01% | $0.159669 | 7.4318 | $1.19 | |
ETH | <0.01% | $0.000189 | 6,207.6938 | $1.17 | |
ETH | <0.01% | $0.080201 | 14.5963 | $1.17 | |
ETH | <0.01% | $0.000004 | 288,226.0119 | $1.17 | |
ETH | <0.01% | $0.010255 | 113.7139 | $1.17 | |
ETH | <0.01% | $0.000161 | 7,196.9806 | $1.16 | |
ETH | <0.01% | $0.00119 | 975.8787 | $1.16 | |
ETH | <0.01% | $0.016328 | 71.0092 | $1.16 | |
ETH | <0.01% | $99,459.02 | 0.00001159 | $1.15 | |
ETH | <0.01% | $3.51 | 0.3262 | $1.15 | |
ETH | <0.01% | <$0.000001 | 389,265,287.3133 | $1.14 | |
ETH | <0.01% | $0.003005 | 378.6146 | $1.14 | |
ETH | <0.01% | $0.009861 | 115.1472 | $1.14 | |
ETH | <0.01% | <$0.000001 | 15,576,722,308.7551 | $1.13 | |
ETH | <0.01% | $0.000156 | 7,230.5614 | $1.13 | |
ETH | <0.01% | $0.003569 | 316.3304 | $1.13 | |
ETH | <0.01% | $0.017961 | 62.718 | $1.13 | |
ETH | <0.01% | $0.001802 | 623.2473 | $1.12 | |
ETH | <0.01% | $0.0006 | 1,851.2011 | $1.11 | |
ETH | <0.01% | $0.004333 | 255.9911 | $1.11 | |
ETH | <0.01% | $0.000195 | 5,633.1663 | $1.1 | |
ETH | <0.01% | $0.007644 | 143.3935 | $1.1 | |
ETH | <0.01% | $0.000953 | 1,149.3895 | $1.1 | |
ETH | <0.01% | $0.14373 | 7.6159 | $1.09 | |
ETH | <0.01% | <$0.000001 | 276,301,265.8843 | $1.09 | |
ETH | <0.01% | $0.014034 | 77.7177 | $1.09 | |
ETH | <0.01% | $1.27 | 0.8575 | $1.09 | |
ETH | <0.01% | $0.017084 | 63.5058 | $1.08 | |
ETH | <0.01% | <$0.000001 | 1,449,519,576.6019 | $1.08 | |
ETH | <0.01% | $0.000043 | 25,361.7713 | $1.08 | |
ETH | <0.01% | $3.07 | 0.3506 | $1.08 | |
ETH | <0.01% | $0.000369 | 2,914.3791 | $1.08 | |
ETH | <0.01% | $0.00372 | 288.4469 | $1.07 | |
ETH | <0.01% | $0.000084 | 12,685.1582 | $1.07 | |
ETH | <0.01% | $0.048276 | 22.1406 | $1.07 | |
ETH | <0.01% | $0.00453 | 234.6427 | $1.06 | |
ETH | <0.01% | $0.002101 | 504.9545 | $1.06 | |
ETH | <0.01% | <$0.000001 | 1,640,842,348,420.5447 | $1.05 | |
ETH | <0.01% | $0.014339 | 72.8929 | $1.05 | |
ETH | <0.01% | $0.001787 | 584.8595 | $1.05 | |
ETH | <0.01% | $0.055041 | 18.7829 | $1.03 | |
ETH | <0.01% | <$0.000001 | 3,186,151,260.1519 | $1.03 | |
ETH | <0.01% | <$0.000001 | 23,628,818,303.7844 | $1.02 | |
ETH | <0.01% | <$0.000001 | 5,336,693,935.3316 | $1.02 | |
ETH | <0.01% | <$0.000001 | 11,819,469.4678 | $1.02 | |
ETH | <0.01% | $0.00714 | 141.979 | $1.01 | |
ETH | <0.01% | $0.012101 | 83.6088 | $1.01 | |
ETH | <0.01% | $0.000025 | 40,214.1395 | $1 | |
ETH | <0.01% | $0.000117 | 8,562.1192 | $0.9975 | |
ETH | <0.01% | $0.332099 | 2.9847 | $0.9912 | |
ETH | <0.01% | $0.002129 | 459.3169 | $0.9779 | |
ETH | <0.01% | <$0.000001 | 7,055,107.8117 | $0.9777 | |
ETH | <0.01% | $0.000506 | 1,909.2244 | $0.9658 | |
ETH | <0.01% | $0.066713 | 14.4546 | $0.9643 | |
ETH | <0.01% | $0.119777 | 8.0363 | $0.9625 | |
ETH | <0.01% | $0.018144 | 52.8907 | $0.9596 | |
ETH | <0.01% | $0.158119 | 6.0603 | $0.9582 | |
ETH | <0.01% | $0.037616 | 25.4378 | $0.9568 | |
ETH | <0.01% | $0.000363 | 2,632.7181 | $0.9555 | |
ETH | <0.01% | $0.004608 | 206.9094 | $0.9534 | |
ETH | <0.01% | $0.000629 | 1,515.5228 | $0.9527 | |
ETH | <0.01% | $0.044128 | 21.5746 | $0.952 | |
ETH | <0.01% | $0.041552 | 22.8457 | $0.9492 | |
ETH | <0.01% | <$0.000001 | 4,280,326,655.3619 | $0.9406 | |
ETH | <0.01% | $0.065284 | 14.3492 | $0.9367 | |
ETH | <0.01% | $0.006762 | 137.8095 | $0.9318 | |
ETH | <0.01% | $0.000493 | 1,872.6161 | $0.9231 | |
ETH | <0.01% | $0.0001 | 9,199.1669 | $0.9195 | |
ETH | <0.01% | $0.882068 | 1.0418 | $0.9189 | |
ETH | <0.01% | <$0.000001 | 6,171,776,387.9176 | $0.9126 | |
ETH | <0.01% | $0.00006 | 15,173.1233 | $0.9087 | |
ETH | <0.01% | $0.002163 | 414.8314 | $0.8972 | |
ETH | <0.01% | $0.001041 | 857.7191 | $0.8932 | |
ETH | <0.01% | $0.000071 | 12,527.5346 | $0.887 | |
ETH | <0.01% | $0.009045 | 97.1403 | $0.8786 | |
ETH | <0.01% | $0.002513 | 348.8407 | $0.8765 | |
ETH | <0.01% | $0.00013 | 6,757.0702 | $0.8753 | |
ETH | <0.01% | <$0.000001 | 3,461,604,493.9678 | $0.8736 | |
ETH | <0.01% | $0.00006 | 14,420.2271 | $0.869 | |
ETH | <0.01% | $0.000229 | 3,775.6782 | $0.8648 | |
ETH | <0.01% | $0.001154 | 741.2429 | $0.8552 | |
ETH | <0.01% | $0.004388 | 194.7394 | $0.8544 | |
ETH | <0.01% | $0.013261 | 64.0388 | $0.8492 | |
ETH | <0.01% | $0.003082 | 273.8003 | $0.8439 | |
ETH | <0.01% | <$0.000001 | 298,591,378.9638 | $0.8374 | |
ETH | <0.01% | <$0.000001 | 2,395,666.5787 | $0.8356 | |
ETH | <0.01% | $0.000038 | 21,346.1301 | $0.8177 | |
ETH | <0.01% | $0.03834 | 21.264 | $0.8152 | |
ETH | <0.01% | $0.000017 | 47,726.2484 | $0.8104 | |
ETH | <0.01% | $0.000036 | 22,265.4126 | $0.8058 | |
ETH | <0.01% | <$0.000001 | 4,560,263.4326 | $0.8027 | |
ETH | <0.01% | $0.113468 | 7.0539 | $0.8003 | |
ETH | <0.01% | $102,105 | 0.00000778 | $0.7943 | |
ETH | <0.01% | $0.19682 | 4.0291 | $0.793 | |
ETH | <0.01% | $0.003856 | 205.5853 | $0.7928 | |
ETH | <0.01% | $0.000179 | 4,401.8258 | $0.7893 | |
ETH | <0.01% | $0.024238 | 32.5641 | $0.7892 | |
ETH | <0.01% | $0.000001 | 1,223,137.9825 | $0.7823 | |
ETH | <0.01% | $0.001736 | 450.3903 | $0.782 | |
ETH | <0.01% | $0.001737 | 448.664 | $0.7792 | |
ETH | <0.01% | $0.019563 | 39.7895 | $0.7784 | |
ETH | <0.01% | $0.000014 | 55,484.1296 | $0.7723 | |
ETH | <0.01% | $0.02623 | 29.3204 | $0.769 | |
ETH | <0.01% | $0.000172 | 4,419.8834 | $0.7583 | |
ETH | <0.01% | <$0.000001 | 266,471,968.7693 | $0.7557 | |
ETH | <0.01% | <$0.000001 | 808,823,621.5638 | $0.749 | |
ETH | <0.01% | $0.000039 | 19,161.6283 | $0.7482 | |
ETH | <0.01% | $0.002787 | 265.4719 | $0.7399 | |
ETH | <0.01% | $0.00465 | 158.4777 | $0.7368 | |
ETH | <0.01% | $8.69 | 0.0836 | $0.7263 | |
ETH | <0.01% | $24.1 | 0.0299 | $0.7209 | |
ETH | <0.01% | $0.078953 | 9.0863 | $0.7173 | |
ETH | <0.01% | $0.004907 | 145.5652 | $0.7143 | |
ETH | <0.01% | $0.015612 | 45.1178 | $0.7043 | |
ETH | <0.01% | <$0.000001 | 18,580,084.5125 | $0.7036 | |
ETH | <0.01% | $0.112812 | 6.2337 | $0.7032 | |
ETH | <0.01% | $0.000012 | 61,077.0396 | $0.7023 | |
ETH | <0.01% | $47.8 | 0.0143 | $0.6848 | |
ETH | <0.01% | $0.08478 | 8.0462 | $0.6821 | |
ETH | <0.01% | $0.005039 | 135.3154 | $0.6818 | |
ETH | <0.01% | $0.001091 | 621.6202 | $0.6781 | |
ETH | <0.01% | $0.001599 | 423.9546 | $0.6778 | |
ETH | <0.01% | <$0.000001 | 5,943,528.3941 | $0.6678 | |
ETH | <0.01% | $0.00076 | 873.5057 | $0.6634 | |
ETH | <0.01% | $0.023448 | 28.1738 | $0.6606 | |
ETH | <0.01% | <$0.000001 | 29,308,015.2271 | $0.6591 | |
ETH | <0.01% | $0.005444 | 121.0169 | $0.6588 | |
ETH | <0.01% | $1.04 | 0.6219 | $0.6488 | |
ETH | <0.01% | $0.459762 | 1.407 | $0.6468 | |
ETH | <0.01% | $0.000001 | 1,110,102.395 | $0.6459 | |
ETH | <0.01% | <$0.000001 | 120,696,921,060.7917 | $0.645 | |
ETH | <0.01% | <$0.000001 | 3,738,171,376.4149 | $0.643 | |
ETH | <0.01% | $0.013008 | 48.9071 | $0.6361 | |
ETH | <0.01% | $0.012658 | 50.1631 | $0.6349 | |
ETH | <0.01% | $0.048196 | 13.0522 | $0.629 | |
ETH | <0.01% | $0.031319 | 19.9943 | $0.6262 | |
ETH | <0.01% | $0.002812 | 222.3988 | $0.6253 | |
ETH | <0.01% | $127.16 | 0.00489666 | $0.6226 | |
ETH | <0.01% | $0.029104 | 21.0662 | $0.6131 | |
ETH | <0.01% | $18,120.38 | 0.00003377 | $0.6118 | |
ETH | <0.01% | $0.000203 | 2,986.2456 | $0.6071 | |
ETH | <0.01% | $0.001327 | 451.7252 | $0.5996 | |
ETH | <0.01% | $0.000099 | 6,041.9479 | $0.5979 | |
ETH | <0.01% | <$0.000001 | 1,727,046.9285 | $0.595 | |
ETH | <0.01% | $0.000266 | 2,218.5524 | $0.589 | |
ETH | <0.01% | $0.000063 | 9,197.8079 | $0.5762 | |
ETH | <0.01% | $0.000677 | 848.0055 | $0.5738 | |
ETH | <0.01% | <$0.000001 | 91,375,026.3828 | $0.5671 | |
ETH | <0.01% | $0.000181 | 3,120.2512 | $0.5634 | |
ETH | <0.01% | <$0.000001 | 12,794,174.6681 | $0.5601 | |
ETH | <0.01% | $0.000418 | 1,337.2306 | $0.5592 | |
ETH | <0.01% | $102,074 | 0.00000547 | $0.5583 | |
ETH | <0.01% | $0.092295 | 5.9971 | $0.5535 | |
ETH | <0.01% | $0.003087 | 175.3729 | $0.5414 | |
ETH | <0.01% | $0.000451 | 1,189.6079 | $0.5367 | |
ETH | <0.01% | $0.000008 | 68,288.2227 | $0.536 | |
ETH | <0.01% | $0.000068 | 7,800.6684 | $0.5339 | |
ETH | <0.01% | $0.003517 | 149.3967 | $0.5254 | |
ETH | <0.01% | <$0.000001 | 1,781,733.5809 | $0.517 | |
ETH | <0.01% | $0.012461 | 41.3181 | $0.5148 | |
ETH | <0.01% | $0.00644 | 78.1858 | $0.5035 | |
ETH | <0.01% | $0.000007 | 67,851.2477 | $0.4973 | |
ETH | <0.01% | $0.010929 | 45.4293 | $0.4964 | |
ETH | <0.01% | $0.001425 | 345.5133 | $0.4922 | |
ETH | <0.01% | $0.496902 | 0.9863 | $0.49 | |
ETH | <0.01% | <$0.000001 | 4,104,781,824.611 | $0.4887 | |
ETH | <0.01% | $0.002205 | 221.2434 | $0.4878 | |
ETH | <0.01% | $0.000004 | 119,585.1834 | $0.4869 | |
ETH | <0.01% | $0.007238 | 66.2407 | $0.4794 | |
ETH | <0.01% | <$0.000001 | 8,250,815,910.3917 | $0.4779 | |
ETH | <0.01% | $0.034698 | 13.6707 | $0.4743 | |
ETH | <0.01% | $0.000966 | 479.8762 | $0.4637 | |
ETH | <0.01% | <$0.000001 | 523,428,570.3656 | $0.4549 | |
ETH | <0.01% | <$0.000001 | 2,253,757.7191 | $0.45 | |
ETH | <0.01% | $0.411661 | 1.0875 | $0.4476 | |
ETH | <0.01% | $0.005985 | 74.6143 | $0.4465 | |
ETH | <0.01% | $0.003871 | 114.5067 | $0.4433 | |
ETH | <0.01% | $0.00962 | 45.977 | $0.4422 | |
ETH | <0.01% | $1.25 | 0.3516 | $0.438 | |
ETH | <0.01% | $0.145886 | 2.9388 | $0.4287 | |
ETH | <0.01% | $0.024025 | 17.8425 | $0.4286 | |
ETH | <0.01% | <$0.000001 | 84,423,924,555,465.6 | $0.4257 | |
ETH | <0.01% | $0.001148 | 368.0987 | $0.4225 | |
ETH | <0.01% | $0.000209 | 2,009.4106 | $0.4192 | |
ETH | <0.01% | $0.019484 | 21.2933 | $0.4148 | |
ETH | <0.01% | $0.000011 | 37,564.4254 | $0.406 | |
ETH | <0.01% | $0.00902 | 44.9242 | $0.4052 | |
ETH | <0.01% | $0.352733 | 1.1468 | $0.4045 | |
ETH | <0.01% | $0.962943 | 0.4197 | $0.4041 | |
ETH | <0.01% | $0.012046 | 33.4395 | $0.4028 | |
ETH | <0.01% | $0.000169 | 2,377.4585 | $0.4018 | |
ETH | <0.01% | $2.97 | 0.132 | $0.3924 | |
ETH | <0.01% | $0.000617 | 635.5319 | $0.3918 | |
ETH | <0.01% | $0.003641 | 107.5038 | $0.3914 | |
ETH | <0.01% | <$0.000001 | 862,836.3441 | $0.3881 | |
ETH | <0.01% | $0.00026 | 1,473.0255 | $0.3831 | |
ETH | <0.01% | $0.000983 | 389.1821 | $0.3827 | |
ETH | <0.01% | <$0.000001 | 29,096,792.9115 | $0.3816 | |
ETH | <0.01% | $0.030996 | 12.2478 | $0.3796 | |
ETH | <0.01% | $0.001265 | 299.0302 | $0.3781 | |
ETH | <0.01% | $0.001876 | 201.4439 | $0.3778 | |
ETH | <0.01% | $0.032607 | 11.5541 | $0.3767 | |
ETH | <0.01% | <$0.000001 | 3,001,428.8329 | $0.3743 | |
ETH | <0.01% | $0.001504 | 246.8031 | $0.3711 | |
ETH | <0.01% | $0.981692 | 0.3722 | $0.3653 | |
ETH | <0.01% | $0.090019 | 4.0494 | $0.3645 | |
ETH | <0.01% | $0.000222 | 1,637.5899 | $0.3642 | |
ETH | <0.01% | $0.002461 | 147.4499 | $0.3628 | |
ETH | <0.01% | $0.000245 | 1,468 | $0.3591 | |
ETH | <0.01% | $0.001229 | 292.1779 | $0.359 | |
ETH | <0.01% | $0.021673 | 16.5239 | $0.3581 | |
ETH | <0.01% | $0.000369 | 964.6697 | $0.3563 | |
ETH | <0.01% | $0.000067 | 5,301.7353 | $0.3543 | |
ETH | <0.01% | $0.000028 | 12,737.0232 | $0.3542 | |
ETH | <0.01% | $0.014115 | 25.0044 | $0.3529 | |
ETH | <0.01% | $0.000001 | 312,738.1141 | $0.3523 | |
ETH | <0.01% | $0.000067 | 5,268.7713 | $0.3515 | |
ETH | <0.01% | $1.28 | 0.2734 | $0.3499 | |
ETH | <0.01% | <$0.000001 | 1,259,334,226.6268 | $0.3483 | |
ETH | <0.01% | $0.003398 | 101.9863 | $0.3465 | |
ETH | <0.01% | $0.000232 | 1,491.755 | $0.3464 | |
ETH | <0.01% | $0.000343 | 1,001.8361 | $0.3436 | |
ETH | <0.01% | $0.000072 | 4,745.1064 | $0.3423 | |
ETH | <0.01% | $0.071694 | 4.7659 | $0.3416 | |
ETH | <0.01% | $0.000106 | 3,192.3515 | $0.3385 | |
ETH | <0.01% | $0.507712 | 0.6568 | $0.3334 | |
ETH | <0.01% | $0.0005 | 666.5987 | $0.3333 | |
ETH | <0.01% | $0.003627 | 90.5507 | $0.3284 | |
ETH | <0.01% | $0.000001 | 500,493.7082 | $0.3277 | |
ETH | <0.01% | $0.996747 | 0.3257 | $0.3246 | |
ETH | <0.01% | $0.000216 | 1,491.9481 | $0.3222 | |
ETH | <0.01% | <$0.000001 | 7,896,989.0414 | $0.3202 | |
ETH | <0.01% | $0.001723 | 185.1776 | $0.319 | |
ETH | <0.01% | $0.000261 | 1,205.0042 | $0.3148 | |
ETH | <0.01% | <$0.000001 | 10,794,940,080,737,304 | $0.313 | |
ETH | <0.01% | $0.039862 | 7.8538 | $0.313 | |
ETH | <0.01% | $0.04891 | 6.396 | $0.3128 | |
ETH | <0.01% | $0.0053 | 58.6524 | $0.3108 | |
ETH | <0.01% | $0.000287 | 1,067.9227 | $0.3069 | |
ETH | <0.01% | <$0.000001 | 12,439,543.351 | $0.3033 | |
ETH | <0.01% | $12.32 | 0.0246 | $0.303 | |
ETH | <0.01% | $0.063754 | 4.7325 | $0.3017 | |
ETH | <0.01% | <$0.000001 | 837,878,014.3907 | $0.2994 | |
ETH | <0.01% | <$0.000001 | 1,113,014,255.8145 | $0.2977 | |
ETH | <0.01% | <$0.000001 | 5,888,735.8606 | $0.2942 | |
ETH | <0.01% | $0.000141 | 2,073.5957 | $0.2929 | |
ETH | <0.01% | <$0.000001 | 174,248,266.6663 | $0.287 | |
ETH | <0.01% | $0.000452 | 634.9702 | $0.2868 | |
ETH | <0.01% | $0.539282 | 0.5285 | $0.285 | |
ETH | <0.01% | $0.001241 | 228.3996 | $0.2834 | |
ETH | <0.01% | $0.027265 | 10.3922 | $0.2833 | |
ETH | <0.01% | $0.00003 | 9,586.9933 | $0.2831 | |
ETH | <0.01% | $0.073575 | 3.7873 | $0.2786 | |
ETH | <0.01% | $0.041428 | 6.7104 | $0.2779 | |
ETH | <0.01% | $0.000046 | 5,944.5109 | $0.276 | |
ETH | <0.01% | <$0.000001 | 242,154,639.854 | $0.2673 | |
ETH | <0.01% | <$0.000001 | 3,103,332,927.6931 | $0.2665 | |
ETH | <0.01% | $0.000959 | 277.5597 | $0.2661 | |
ETH | <0.01% | $0.000028 | 9,443.5979 | $0.2656 | |
ETH | <0.01% | <$0.000001 | 914,904.1944 | $0.2573 | |
ETH | <0.01% | $0.002145 | 117.9569 | $0.253 | |
ETH | <0.01% | $0.000949 | 262.2949 | $0.2487 | |
ETH | <0.01% | $0.008131 | 29.7962 | $0.2422 | |
ETH | <0.01% | $0.003246 | 73.3951 | $0.2382 | |
ETH | <0.01% | $0.000007 | 31,418.2127 | $0.2315 | |
ETH | <0.01% | $0.006906 | 33.1404 | $0.2288 | |
ETH | <0.01% | $0.000542 | 416.5447 | $0.2257 | |
ETH | <0.01% | $0.198069 | 1.1321 | $0.2242 | |
ETH | <0.01% | $0.04764 | 4.7011 | $0.2239 | |
ETH | <0.01% | $101,793 | 0.00000218 | $0.2219 | |
ETH | <0.01% | $0.000872 | 251.0263 | $0.2189 | |
ETH | <0.01% | $0.062833 | 3.48 | $0.2186 | |
ETH | <0.01% | $23.12 | 0.00944467 | $0.2183 | |
ETH | <0.01% | <$0.000001 | 6,290,322.3143 | $0.2178 | |
ETH | <0.01% | $0.000573 | 375.1872 | $0.2149 | |
ETH | <0.01% | <$0.000001 | 485,440,505.9813 | $0.2029 | |
ETH | <0.01% | <$0.000001 | 133,649,389.1868 | $0.2007 | |
ETH | <0.01% | $0.00001 | 19,181.215 | $0.2004 | |
ETH | <0.01% | $4.06 | 0.0488 | $0.1983 | |
ETH | <0.01% | $0.000143 | 1,366.0617 | $0.1958 | |
ETH | <0.01% | $0.000093 | 2,107.7981 | $0.1951 | |
ETH | <0.01% | $0.438019 | 0.4453 | $0.195 | |
ETH | <0.01% | <$0.000001 | 327,037,992,964.7354 | $0.1917 | |
ETH | <0.01% | $0.00031 | 618.0275 | $0.1916 | |
ETH | <0.01% | $0.001727 | 110.9014 | $0.1915 | |
ETH | <0.01% | $0.000008 | 24,109.1396 | $0.1897 | |
ETH | <0.01% | $0.020508 | 9.1805 | $0.1882 | |
ETH | <0.01% | $0.024586 | 7.6214 | $0.1873 | |
ETH | <0.01% | $0.000024 | 7,640.2741 | $0.1868 | |
ETH | <0.01% | $0.000235 | 780.3632 | $0.1831 | |
ETH | <0.01% | $0.00224 | 80.646 | $0.1806 | |
ETH | <0.01% | $0.000006 | 28,795.4155 | $0.1793 | |
ETH | <0.01% | $1.3 | 0.1319 | $0.1714 | |
ETH | <0.01% | $0.000001 | 144,764.8718 | $0.1706 | |
ETH | <0.01% | <$0.000001 | 2,145,122,487,873.7021 | $0.1701 | |
ETH | <0.01% | $0.00023 | 730.6735 | $0.1677 | |
ETH | <0.01% | $0.000156 | 1,071.3034 | $0.167 | |
ETH | <0.01% | $0.000301 | 551.3847 | $0.1662 | |
ETH | <0.01% | $0.033759 | 4.9214 | $0.1661 | |
ETH | <0.01% | $0.022765 | 7.2893 | $0.1659 | |
ETH | <0.01% | $0.000022 | 7,624.9124 | $0.1651 | |
ETH | <0.01% | $0.005477 | 29.5371 | $0.1617 | |
ETH | <0.01% | $0.997936 | 0.1618 | $0.1614 | |
ETH | <0.01% | $25.7 | 0.00618391 | $0.1589 | |
ETH | <0.01% | $0.19106 | 0.8244 | $0.1575 | |
ETH | <0.01% | $0.00025 | 622.9285 | $0.1557 | |
ETH | <0.01% | $0.016238 | 9.5628 | $0.1552 | |
ETH | <0.01% | $0.476297 | 0.3253 | $0.1549 | |
ETH | <0.01% | $0.00036 | 426.4674 | $0.1534 | |
ETH | <0.01% | $0.56422 | 0.266 | $0.15 | |
ETH | <0.01% | $0.035971 | 4.1675 | $0.1499 | |
ETH | <0.01% | $20.65 | 0.00722517 | $0.1491 | |
ETH | <0.01% | $0.986662 | 0.1499 | $0.1479 | |
ETH | <0.01% | $0.259655 | 0.5667 | $0.1471 | |
ETH | <0.01% | $0.073014 | 2 | $0.146 | |
ETH | <0.01% | $0.991132 | 0.1465 | $0.1452 | |
ETH | <0.01% | $0.000005 | 31,344.008 | $0.1426 | |
ETH | <0.01% | <$0.000001 | 624,286.5776 | $0.1409 | |
ETH | <0.01% | $0.016849 | 8.3219 | $0.1402 | |
ETH | <0.01% | $0.000016 | 8,799.5002 | $0.1397 | |
ETH | <0.01% | $0.000001 | 140,171.0739 | $0.1351 | |
ETH | <0.01% | <$0.000001 | 42,761,120.8351 | $0.131 | |
ETH | <0.01% | $0.000001 | 188,884.4924 | $0.1305 | |
ETH | <0.01% | <$0.000001 | 298,360,423.0509 | $0.1266 | |
ETH | <0.01% | <$0.000001 | 1,445,832.7905 | $0.1258 | |
ETH | <0.01% | $0.417934 | 0.2959 | $0.1236 | |
ETH | <0.01% | $0.000371 | 332.7608 | $0.1233 | |
ETH | <0.01% | $0.50144 | 0.2458 | $0.1232 | |
ETH | <0.01% | $0.000015 | 7,822.8117 | $0.1205 | |
ETH | <0.01% | $0.008121 | 14.6016 | $0.1185 | |
ETH | <0.01% | $0.01488 | 7.7428 | $0.1152 | |
ETH | <0.01% | $0.002247 | 50.5337 | $0.1135 | |
ETH | <0.01% | $0.000003 | 43,069.1543 | $0.1135 | |
ETH | <0.01% | <$0.000001 | 1,387,669.7049 | $0.1134 | |
ETH | <0.01% | $3,203.19 | 0.000035 | $0.1121 | |
ETH | <0.01% | $0.002768 | 40.0058 | $0.1107 | |
ETH | <0.01% | $0.028521 | 3.8356 | $0.1093 | |
ETH | <0.01% | <$0.000001 | 1,583,002,851.599 | $0.1075 | |
ETH | <0.01% | <$0.000001 | 527,007,274.6883 | $0.1052 | |
ETH | <0.01% | $0.000035 | 2,963.9464 | $0.1031 | |
ETH | <0.01% | $0.027531 | 3.7381 | $0.1029 | |
ETH | <0.01% | $0.007027 | 14.2816 | $0.1003 | |
FTM | <0.01% | $102,291 | 0.0301 | $3,081.72 | |
FTM | <0.01% | <$0.000001 | 21,830,146,001.2389 | $2,115.34 | |
FTM | <0.01% | $304.63 | 4.4797 | $1,364.64 | |
FTM | <0.01% | $3,280.35 | 0.1787 | $586.12 | |
FTM | <0.01% | $0.55195 | 167.4877 | $92.44 | |
FTM | <0.01% | $0.003455 | 21,773.8204 | $75.24 | |
FTM | <0.01% | $7,717.36 | 0.00952049 | $73.47 | |
FTM | <0.01% | $24.35 | 2.8378 | $69.1 | |
FTM | <0.01% | $0.604832 | 110.0807 | $66.58 | |
FTM | <0.01% | $0.031521 | 2,027.5497 | $63.91 | |
FTM | <0.01% | $22,240 | 0.00270677 | $60.2 | |
FTM | <0.01% | $0.342163 | 157.3419 | $53.84 | |
FTM | <0.01% | $0.37013 | 101.9498 | $37.73 | |
FTM | <0.01% | $0.021725 | 1,469.4587 | $31.92 | |
FTM | <0.01% | $0.015917 | 1,990.4943 | $31.68 | |
FTM | <0.01% | $0.178149 | 174.9181 | $31.16 | |
FTM | <0.01% | $1.25 | 22.7827 | $28.48 | |
FTM | <0.01% | $0.092356 | 306.0975 | $28.27 | |
FTM | <0.01% | $0.00035 | 76,949.1122 | $26.93 | |
FTM | <0.01% | $0.998467 | 24.5002 | $24.46 | |
FTM | <0.01% | $0.000001 | 36,126,268.5283 | $24.18 | |
FTM | <0.01% | $0.003638 | 5,680.3743 | $20.66 | |
FTM | <0.01% | $0.003794 | 5,364.3453 | $20.35 | |
FTM | <0.01% | $0.545266 | 30.0721 | $16.4 | |
FTM | <0.01% | $0.000352 | 44,840.4167 | $15.8 | |
FTM | <0.01% | <$0.000001 | 163,616,409.7002 | $12.16 | |
FTM | <0.01% | $0.630323 | 14.9223 | $9.41 | |
FTM | <0.01% | $0.000107 | 86,820.4474 | $9.32 | |
FTM | <0.01% | $0.503209 | 18.2699 | $9.19 | |
FTM | <0.01% | $24.69 | 0.3258 | $8.04 | |
FTM | <0.01% | $0.038967 | 177.08 | $6.9 | |
FTM | <0.01% | $1.37 | 4.7732 | $6.54 | |
FTM | <0.01% | $0.99804 | 6.299 | $6.29 | |
FTM | <0.01% | $1 | 6.2378 | $6.24 | |
FTM | <0.01% | $0.993557 | 5.9234 | $5.89 | |
FTM | <0.01% | $0.447945 | 12.9269 | $5.79 | |
FTM | <0.01% | $10.18 | 0.5565 | $5.67 | |
FTM | <0.01% | $3.94 | 1.4376 | $5.66 | |
FTM | <0.01% | $0.241763 | 20.5632 | $4.97 | |
FTM | <0.01% | $0.000015 | 326,321.8054 | $4.89 | |
FTM | <0.01% | $0.00006 | 74,137.5854 | $4.42 | |
FTM | <0.01% | $0.548561 | 5.9843 | $3.28 | |
FTM | <0.01% | $0.000913 | 3,016.3719 | $2.76 | |
FTM | <0.01% | $2.96 | 0.7125 | $2.11 | |
FTM | <0.01% | $1.58 | 1.1998 | $1.9 | |
FTM | <0.01% | $0.052516 | 34.0669 | $1.79 | |
FTM | <0.01% | $0.02504 | 61.3143 | $1.54 | |
FTM | <0.01% | $318.61 | 0.0045061 | $1.44 | |
FTM | <0.01% | $0.000584 | 2,420.8034 | $1.41 | |
FTM | <0.01% | $3,282.37 | 0.00041214 | $1.35 | |
FTM | <0.01% | $0.289247 | 3.9338 | $1.14 | |
FTM | <0.01% | $68.99 | 0.0146 | $1 | |
FTM | <0.01% | <$0.000001 | 7,647,626.6835 | $0.858 | |
FTM | <0.01% | $35.83 | 0.0211 | $0.757 | |
FTM | <0.01% | $0.003649 | 197.7326 | $0.7214 | |
FTM | <0.01% | $0.996017 | 0.6357 | $0.6331 | |
FTM | <0.01% | $0.000048 | 12,669.1979 | $0.6095 | |
FTM | <0.01% | $0.600409 | 0.792 | $0.4755 | |
FTM | <0.01% | $0.998923 | 0.4681 | $0.4676 | |
FTM | <0.01% | $0.900767 | 0.5011 | $0.4513 | |
FTM | <0.01% | $0.008901 | 47.3195 | $0.4212 | |
FTM | <0.01% | $0.008575 | 46.4591 | $0.3983 | |
FTM | <0.01% | $0.000151 | 2,522.6756 | $0.3814 | |
FTM | <0.01% | $0.012754 | 27.9449 | $0.3564 | |
FTM | <0.01% | $0.996017 | 0.2697 | $0.2686 | |
FTM | <0.01% | $0.160014 | 1.4164 | $0.2266 | |
FTM | <0.01% | $0.00367 | 55.4961 | $0.2036 | |
FTM | <0.01% | $0.01633 | 10.2531 | $0.1674 | |
FTM | <0.01% | $0.008092 | 17.8151 | $0.1441 | |
FTM | <0.01% | $0.000089 | 1,470.6025 | $0.1314 | |
FTM | <0.01% | $0.04616 | 2.6801 | $0.1237 | |
FTM | <0.01% | $0.00006 | 1,828.4031 | $0.1097 | |
POL | <0.01% | $0.00375 | 134,128.6516 | $503.04 | |
POL | <0.01% | $0.004571 | 109,750.3825 | $501.68 | |
POL | <0.01% | $304.91 | 0.6376 | $194.4 | |
POL | <0.01% | $0.021402 | 7,893.8405 | $168.95 | |
POL | <0.01% | $3,285.85 | 0.0288 | $94.69 | |
POL | <0.01% | $2,700.96 | 0.0347 | $93.73 | |
POL | <0.01% | <$0.000001 | 9,087,934,845.592 | $91.79 | |
POL | <0.01% | $0.345197 | 257.9579 | $89.05 | |
POL | <0.01% | $0.99892 | 85.7543 | $85.66 | |
POL | <0.01% | $0.004857 | 17,565.3046 | $85.32 | |
POL | <0.01% | $24.38 | 3.3532 | $81.75 | |
POL | <0.01% | $0.2889 | 280.1582 | $80.94 | |
POL | <0.01% | $0.731017 | 109.0554 | $79.72 | |
POL | <0.01% | $1 | 76.3705 | $76.37 | |
POL | <0.01% | $1 | 72.8426 | $72.84 | |
POL | <0.01% | $0.839825 | 84.1381 | $70.66 | |
POL | <0.01% | $15.99 | 4.2818 | $68.47 | |
POL | <0.01% | $3.71 | 17.3639 | $64.42 | |
POL | <0.01% | $0.036154 | 1,672.289 | $60.46 | |
POL | <0.01% | $0.007091 | 8,477.8834 | $60.11 | |
POL | <0.01% | $319.73 | 0.1684 | $53.85 | |
POL | <0.01% | $6.76 | 7.749 | $52.38 | |
POL | <0.01% | $0.00254 | 19,219.8949 | $48.82 | |
POL | <0.01% | $13.46 | 3.6005 | $48.46 | |
POL | <0.01% | $246.45 | 0.1941 | $47.83 | |
POL | <0.01% | $102,394 | 0.00046675 | $47.79 | |
POL | <0.01% | $0.004443 | 10,518.9847 | $46.74 | |
POL | <0.01% | $0.000567 | 79,438.4317 | $45.05 | |
POL | <0.01% | $0.002594 | 16,563.6262 | $42.96 | |
POL | <0.01% | $0.178632 | 233.9071 | $41.78 | |
POL | <0.01% | $1.37 | 30.474 | $41.75 | |
POL | <0.01% | $0.107194 | 346.5385 | $37.15 | |
POL | <0.01% | $0.00251 | 14,505.6535 | $36.41 | |
POL | <0.01% | $0.676137 | 53.6064 | $36.25 | |
POL | <0.01% | $0.143523 | 244.3067 | $35.06 | |
POL | <0.01% | $0.283776 | 119.7578 | $33.98 | |
POL | <0.01% | $0.199332 | 166.298 | $33.15 | |
POL | <0.01% | $0.169041 | 192.0506 | $32.46 | |
POL | <0.01% | $0.792474 | 40.4731 | $32.07 | |
POL | <0.01% | <$0.000001 | 1,317,160,948.7478 | $31.35 | |
POL | <0.01% | <$0.000001 | 87,809,409.3942 | $31.07 | |
POL | <0.01% | $2.67 | 10.7607 | $28.73 | |
POL | <0.01% | $1.45 | 18.986 | $27.53 | |
POL | <0.01% | $0.198296 | 138.6062 | $27.49 | |
POL | <0.01% | $1.59 | 17.0548 | $27.12 | |
POL | <0.01% | $0.002322 | 11,462.7979 | $26.62 | |
POL | <0.01% | $0.291466 | 87.0508 | $25.37 | |
POL | <0.01% | $0.001281 | 19,227.4126 | $24.63 | |
POL | <0.01% | $0.007595 | 3,214.5471 | $24.41 | |
POL | <0.01% | $0.006271 | 3,769.503 | $23.64 | |
POL | <0.01% | $0.050405 | 468.8904 | $23.63 | |
POL | <0.01% | $0.008098 | 2,891.4954 | $23.41 | |
POL | <0.01% | $0.126744 | 182.717 | $23.16 | |
POL | <0.01% | $0.035457 | 647.3076 | $22.95 | |
POL | <0.01% | $4.19 | 5.4646 | $22.9 | |
POL | <0.01% | $0.000512 | 44,388.81 | $22.72 | |
POL | <0.01% | $0.095688 | 235.9664 | $22.58 | |
POL | <0.01% | $0.000475 | 45,862.1982 | $21.8 | |
POL | <0.01% | $0.000003 | 5,926,861.5496 | $20.16 | |
POL | <0.01% | $4.58 | 4.0086 | $18.36 | |
POL | <0.01% | $0.003891 | 4,670.3132 | $18.17 | |
POL | <0.01% | $0.000019 | 937,814.5274 | $18.02 | |
POL | <0.01% | $0.561843 | 31.4028 | $17.64 | |
POL | <0.01% | $0.003583 | 4,733.5176 | $16.96 | |
POL | <0.01% | $0.031621 | 533.0707 | $16.86 | |
POL | <0.01% | $0.119014 | 132.5547 | $15.78 | |
POL | <0.01% | $0.012161 | 1,294.4214 | $15.74 | |
POL | <0.01% | $0.005755 | 2,705.7704 | $15.57 | |
POL | <0.01% | $1.13 | 13.5948 | $15.36 | |
POL | <0.01% | $0.026728 | 543.4733 | $14.53 | |
POL | <0.01% | $0.006203 | 2,330.4393 | $14.45 | |
POL | <0.01% | $2.74 | 5.2108 | $14.28 | |
POL | <0.01% | $0.000029 | 466,957.6975 | $13.56 | |
POL | <0.01% | $1.7 | 6.8354 | $11.62 | |
POL | <0.01% | $0.448948 | 24.462 | $10.98 | |
POL | <0.01% | $0.013581 | 799.551 | $10.86 | |
POL | <0.01% | $0.002449 | 4,228.257 | $10.36 | |
POL | <0.01% | $1.09 | 9.4049 | $10.21 | |
POL | <0.01% | $0.000021 | 484,592.7014 | $9.97 | |
POL | <0.01% | $0.000496 | 19,799.6163 | $9.81 | |
POL | <0.01% | $0.529828 | 18.1184 | $9.6 | |
POL | <0.01% | $0.342331 | 27.6917 | $9.48 | |
POL | <0.01% | $0.002406 | 3,808.5723 | $9.16 | |
POL | <0.01% | $0.433614 | 20.957 | $9.09 | |
POL | <0.01% | $0.006803 | 1,262.49 | $8.59 | |
POL | <0.01% | $0.01085 | 777.6132 | $8.44 | |
POL | <0.01% | $0.000887 | 8,904.8678 | $7.9 | |
POL | <0.01% | $0.522872 | 14.2257 | $7.44 | |
POL | <0.01% | $0.993012 | 7.3499 | $7.3 | |
POL | <0.01% | $0.000495 | 14,664.1416 | $7.26 | |
POL | <0.01% | $0.154653 | 42.5784 | $6.58 | |
POL | <0.01% | $0.001109 | 5,852.7158 | $6.49 | |
POL | <0.01% | $0.348932 | 18.0864 | $6.31 | |
POL | <0.01% | <$0.000001 | 30,017,508.6741 | $6.24 | |
POL | <0.01% | $0.007642 | 814.2176 | $6.22 | |
POL | <0.01% | $0.010046 | 616.1692 | $6.19 | |
POL | <0.01% | $0.028433 | 215.6089 | $6.13 | |
POL | <0.01% | $2.54 | 2.4122 | $6.13 | |
POL | <0.01% | $0.004898 | 1,177.8159 | $5.77 | |
POL | <0.01% | $0.016281 | 347.4016 | $5.66 | |
POL | <0.01% | $0.183729 | 30.6327 | $5.63 | |
POL | <0.01% | $0.975493 | 5.622 | $5.48 | |
POL | <0.01% | $0.003979 | 1,328.2222 | $5.28 | |
POL | <0.01% | $0.005918 | 875.1505 | $5.18 | |
POL | <0.01% | $0.027172 | 187.7655 | $5.1 | |
POL | <0.01% | $0.002576 | 1,915.0809 | $4.93 | |
POL | <0.01% | $0.015574 | 314.4162 | $4.9 | |
POL | <0.01% | $0.033883 | 134.325 | $4.55 | |
POL | <0.01% | $0.341909 | 12.947 | $4.43 | |
POL | <0.01% | $0.00074 | 5,840.5913 | $4.32 | |
POL | <0.01% | $0.442245 | 9.6302 | $4.26 | |
POL | <0.01% | $0.00053 | 7,773.8916 | $4.12 | |
POL | <0.01% | $0.000002 | 1,978,643.7402 | $4.1 | |
POL | <0.01% | $0.011012 | 363.1889 | $4 | |
POL | <0.01% | $0.026614 | 148.8266 | $3.96 | |
POL | <0.01% | <$0.000001 | 317,974,864.0829 | $3.91 | |
POL | <0.01% | $0.003308 | 1,167.1979 | $3.86 | |
POL | <0.01% | $0.009133 | 414.9963 | $3.79 | |
POL | <0.01% | $0.002402 | 1,566.5254 | $3.76 | |
POL | <0.01% | $1.14 | 3.2053 | $3.65 | |
POL | <0.01% | $0.000292 | 12,303.3886 | $3.6 | |
POL | <0.01% | $0.002598 | 1,373.5896 | $3.57 | |
POL | <0.01% | $0.000329 | 10,068.3669 | $3.31 | |
POL | <0.01% | $0.002583 | 1,269.7704 | $3.28 | |
POL | <0.01% | $0.00137 | 2,265.323 | $3.1 | |
POL | <0.01% | $0.000044 | 69,588.3158 | $3.09 | |
POL | <0.01% | $0.007053 | 430.381 | $3.04 | |
POL | <0.01% | $0.804231 | 3.7297 | $3 | |
POL | <0.01% | $1.03 | 2.7869 | $2.87 | |
POL | <0.01% | $0.000001 | 3,718,440.227 | $2.65 | |
POL | <0.01% | $0.052516 | 49.6703 | $2.61 | |
POL | <0.01% | $0.00125 | 2,081.979 | $2.6 | |
POL | <0.01% | $0.073808 | 34.6682 | $2.56 | |
POL | <0.01% | $0.001182 | 2,103.8834 | $2.49 | |
POL | <0.01% | $0.507221 | 4.7464 | $2.41 | |
POL | <0.01% | $0.199225 | 11.9172 | $2.37 | |
POL | <0.01% | $0.468873 | 4.5632 | $2.14 | |
POL | <0.01% | $0.03773 | 56.6879 | $2.14 | |
POL | <0.01% | $0.011749 | 177.797 | $2.09 | |
POL | <0.01% | $0.09999 | 20.8539 | $2.09 | |
POL | <0.01% | $0.002381 | 867.4032 | $2.07 | |
POL | <0.01% | $0.005974 | 320.2673 | $1.91 | |
POL | <0.01% | $0.000002 | 926,111.6093 | $1.85 | |
POL | <0.01% | $0.005787 | 311.1648 | $1.8 | |
POL | <0.01% | $0.01086 | 162.6051 | $1.77 | |
POL | <0.01% | $0.000821 | 2,024.106 | $1.66 | |
POL | <0.01% | $0.00016 | 10,316.742 | $1.65 | |
POL | <0.01% | $0.000665 | 2,438.467 | $1.62 | |
POL | <0.01% | $0.849209 | 1.8485 | $1.57 | |
POL | <0.01% | $0.000075 | 20,607.3293 | $1.55 | |
POL | <0.01% | $0.096691 | 15.9263 | $1.54 | |
POL | <0.01% | $0.476595 | 2.8497 | $1.36 | |
POL | <0.01% | $0.082961 | 15.7058 | $1.3 | |
POL | <0.01% | $35.91 | 0.0346 | $1.24 | |
POL | <0.01% | $82.36 | 0.0145 | $1.2 | |
POL | <0.01% | $0.084603 | 12.9503 | $1.1 | |
POL | <0.01% | $0.001022 | 1,047.193 | $1.07 | |
POL | <0.01% | $19.99 | 0.0532 | $1.06 | |
POL | <0.01% | $0.006984 | 148.8307 | $1.04 | |
POL | <0.01% | $0.003451 | 293.6019 | $1.01 | |
POL | <0.01% | $0.003045 | 326.048 | $0.9928 | |
POL | <0.01% | $0.004675 | 200.5728 | $0.9375 | |
POL | <0.01% | $0.000078 | 11,823.1588 | $0.9256 | |
POL | <0.01% | $0.00408 | 218.3545 | $0.8908 | |
POL | <0.01% | $1 | 0.8478 | $0.8477 | |
POL | <0.01% | $0.000826 | 966.7437 | $0.7983 | |
POL | <0.01% | $0.003207 | 248.5945 | $0.7973 | |
POL | <0.01% | $0.001143 | 692.4973 | $0.7914 | |
POL | <0.01% | $0.299567 | 2.611 | $0.7821 | |
POL | <0.01% | $0.066984 | 11.3949 | $0.7632 | |
POL | <0.01% | $0.010295 | 73.5431 | $0.7571 | |
POL | <0.01% | $0.000057 | 13,192.6272 | $0.746 | |
POL | <0.01% | $0.113593 | 6.4161 | $0.7288 | |
POL | <0.01% | $0.000704 | 1,033.4779 | $0.7272 | |
POL | <0.01% | $1 | 0.6672 | $0.6678 | |
POL | <0.01% | $0.000432 | 1,469.731 | $0.6343 | |
POL | <0.01% | $0.000209 | 2,943.5327 | $0.6144 | |
POL | <0.01% | $0.061311 | 9.7573 | $0.5982 | |
POL | <0.01% | $0.001559 | 362.8155 | $0.5656 | |
POL | <0.01% | $0.084016 | 6.5772 | $0.5525 | |
POL | <0.01% | $0.010007 | 53.8251 | $0.5386 | |
POL | <0.01% | $0.000761 | 705.1697 | $0.5366 | |
POL | <0.01% | $0.001715 | 308.9757 | $0.5297 | |
POL | <0.01% | $0.001114 | 462.2194 | $0.5148 | |
POL | <0.01% | $0.11536 | 4.4276 | $0.5107 | |
POL | <0.01% | $0.000001 | 441,056.5368 | $0.4851 | |
POL | <0.01% | $0.02096 | 23.1309 | $0.4848 | |
POL | <0.01% | $0.597998 | 0.7768 | $0.4645 | |
POL | <0.01% | $0.026765 | 17.0058 | $0.4551 | |
POL | <0.01% | $0.000023 | 19,601.766 | $0.4479 | |
POL | <0.01% | $0.000194 | 2,204.8653 | $0.4271 | |
POL | <0.01% | $0.000288 | 1,478.5453 | $0.425 | |
POL | <0.01% | $0.002686 | 150.8251 | $0.4051 | |
POL | <0.01% | $0.217129 | 1.8371 | $0.3988 | |
POL | <0.01% | $0.125759 | 3.1342 | $0.3941 | |
POL | <0.01% | $0.001806 | 210.9877 | $0.381 | |
POL | <0.01% | $1.1 | 0.34 | $0.374 | |
POL | <0.01% | $0.994385 | 0.3612 | $0.3592 | |
POL | <0.01% | $0.002459 | 141.5864 | $0.3482 | |
POL | <0.01% | $0.043084 | 7.9811 | $0.3438 | |
POL | <0.01% | $0.012549 | 25.1071 | $0.315 | |
POL | <0.01% | $0.002931 | 105.5899 | $0.3094 | |
POL | <0.01% | <$0.000001 | 1,894,375.3497 | $0.2938 | |
POL | <0.01% | $0.018767 | 15.2133 | $0.2855 | |
POL | <0.01% | $0.001414 | 201.9112 | $0.2855 | |
POL | <0.01% | $0.00019 | 1,488.18 | $0.2826 | |
POL | <0.01% | $0.005918 | 46.9096 | $0.2776 | |
POL | <0.01% | $0.035577 | 7.654 | $0.2723 | |
POL | <0.01% | $0.000875 | 303.232 | $0.2653 | |
POL | <0.01% | $0.000136 | 1,929.8292 | $0.262 | |
POL | <0.01% | $0.140977 | 1.8104 | $0.2552 | |
POL | <0.01% | $0.52278 | 0.4795 | $0.2506 | |
POL | <0.01% | $0.015844 | 15.6773 | $0.2483 | |
POL | <0.01% | $1.07 | 0.2286 | $0.2443 | |
POL | <0.01% | $0.001279 | 186.5294 | $0.2385 | |
POL | <0.01% | $0.000118 | 1,977.6194 | $0.2337 | |
POL | <0.01% | $0.001155 | 201.5882 | $0.2329 | |
POL | <0.01% | $0.000306 | 747.1141 | $0.2289 | |
POL | <0.01% | $0.00103 | 216.1936 | $0.2227 | |
POL | <0.01% | $72.54 | 0.00306559 | $0.2223 | |
POL | <0.01% | $0.000746 | 286.6951 | $0.2139 | |
POL | <0.01% | $0.512672 | 0.3901 | $0.1999 | |
POL | <0.01% | $0.000006 | 31,706.637 | $0.1921 | |
POL | <0.01% | $0.00146 | 124.3261 | $0.1815 | |
POL | <0.01% | $0.580629 | 0.3022 | $0.1754 | |
POL | <0.01% | $0.023283 | 7.355 | $0.1712 | |
POL | <0.01% | $0.000653 | 253.3506 | $0.1655 | |
POL | <0.01% | $0.073506 | 2.2377 | $0.1644 | |
POL | <0.01% | $0.000011 | 13,795.9312 | $0.156 | |
POL | <0.01% | $0.002701 | 51.368 | $0.1387 | |
POL | <0.01% | $0.00001 | 11,641.9804 | $0.1218 | |
POL | <0.01% | $0.005132 | 23.0447 | $0.1182 | |
POL | <0.01% | $22.15 | 0.00523267 | $0.1159 | |
POL | <0.01% | $0.000136 | 816.0405 | $0.1113 | |
POL | <0.01% | $0.008912 | 12.2462 | $0.1091 | |
POL | <0.01% | $0.225961 | 0.4793 | $0.1083 | |
POL | <0.01% | $0.001187 | 87.7406 | $0.1041 | |
POL | <0.01% | $0.027405 | 3.7552 | $0.1029 | |
ARB | <0.01% | $304.58 | 0.8729 | $265.86 | |
ARB | <0.01% | $0.998896 | 103.2755 | $103.16 | |
ARB | <0.01% | $0.199122 | 418.5225 | $83.34 | |
ARB | <0.01% | $23.12 | 3.4931 | $80.76 | |
ARB | <0.01% | $0.187835 | 420.0988 | $78.91 | |
ARB | <0.01% | $0.059908 | 1,208.5994 | $72.4 | |
ARB | <0.01% | $1.7 | 37.5595 | $63.85 | |
ARB | <0.01% | $24.35 | 2.563 | $62.41 | |
ARB | <0.01% | $0.703105 | 82.5729 | $58.06 | |
ARB | <0.01% | $1.37 | 39.2167 | $53.73 | |
ARB | <0.01% | $3.71 | 10.7974 | $40.06 | |
ARB | <0.01% | $0.002388 | 16,022.3796 | $38.26 | |
ARB | <0.01% | $0.05819 | 635.8664 | $37 | |
ARB | <0.01% | $0.010294 | 3,406.4992 | $35.07 | |
ARB | <0.01% | $0.129851 | 262.0696 | $34.03 | |
ARB | <0.01% | $0.670588 | 40.07 | $26.87 | |
ARB | <0.01% | $0.37509 | 62.1965 | $23.33 | |
ARB | <0.01% | $0.049877 | 458.8358 | $22.89 | |
ARB | <0.01% | $1.45 | 14.9767 | $21.72 | |
ARB | <0.01% | $0.036249 | 584.0491 | $21.17 | |
ARB | <0.01% | $0.000912 | 22,689.0583 | $20.7 | |
ARB | <0.01% | $0.027289 | 705.1373 | $19.24 | |
ARB | <0.01% | <$0.000001 | 95,456,068,253.461 | $19.09 | |
ARB | <0.01% | $13.44 | 1.3359 | $17.95 | |
ARB | <0.01% | $0.230072 | 77.7236 | $17.88 | |
ARB | <0.01% | $0.035901 | 475.957 | $17.09 | |
ARB | <0.01% | $0.540669 | 29.6411 | $16.03 | |
ARB | <0.01% | $3,289.14 | 0.00474747 | $15.62 | |
ARB | <0.01% | $0.014611 | 1,047.3599 | $15.3 | |
ARB | <0.01% | $4.19 | 3.4246 | $14.35 | |
ARB | <0.01% | $707.22 | 0.0189 | $13.33 | |
ARB | <0.01% | $0.343043 | 37.1152 | $12.73 | |
ARB | <0.01% | $3.63 | 3.439 | $12.48 | |
ARB | <0.01% | $0.000005 | 2,116,781.6132 | $9.97 | |
ARB | <0.01% | $1 | 9.4833 | $9.48 | |
ARB | <0.01% | $4.1 | 2.1076 | $8.64 | |
ARB | <0.01% | $0.007077 | 1,205.3425 | $8.53 | |
ARB | <0.01% | $0.000007 | 1,154,905.1239 | $8.13 | |
ARB | <0.01% | $0.3228 | 25.1658 | $8.12 | |
ARB | <0.01% | $0.000016 | 512,581.5581 | $8.08 | |
ARB | <0.01% | $0.018017 | 446.6708 | $8.05 | |
ARB | <0.01% | $0.597236 | 12.8655 | $7.68 | |
ARB | <0.01% | $0.07694 | 95.4528 | $7.34 | |
ARB | <0.01% | $0.178297 | 35.8608 | $6.39 | |
ARB | <0.01% | $0.004466 | 1,332.0909 | $5.95 | |
ARB | <0.01% | <$0.000001 | 1,606,712,005.8181 | $5.94 | |
ARB | <0.01% | $0.027399 | 206.9155 | $5.67 | |
ARB | <0.01% | $0.098924 | 50.1019 | $4.96 | |
ARB | <0.01% | $0.000621 | 7,869.0004 | $4.89 | |
ARB | <0.01% | $1 | 4.5151 | $4.52 | |
ARB | <0.01% | $0.000013 | 332,251.2943 | $4.41 | |
ARB | <0.01% | $0.01347 | 323.9503 | $4.36 | |
ARB | <0.01% | $0.007743 | 513.84 | $3.98 | |
ARB | <0.01% | $0.177492 | 22.3517 | $3.97 | |
ARB | <0.01% | <$0.000001 | 32,306,444.7325 | $3.97 | |
ARB | <0.01% | $0.9933 | 3.7127 | $3.69 | |
ARB | <0.01% | $0.031151 | 114.9731 | $3.58 | |
ARB | <0.01% | <$0.000001 | 15,048,383.3213 | $3.13 | |
ARB | <0.01% | $0.001994 | 1,553.9629 | $3.1 | |
ARB | <0.01% | $0.002015 | 1,479.14 | $2.98 | |
ARB | <0.01% | $0.001894 | 1,433.6157 | $2.71 | |
ARB | <0.01% | <$0.000001 | 22,581,086.1299 | $2.6 | |
ARB | <0.01% | $0.031694 | 80.6665 | $2.56 | |
ARB | <0.01% | $0.839566 | 3.0385 | $2.55 | |
ARB | <0.01% | $1.03 | 2.2591 | $2.32 | |
ARB | <0.01% | $0.549774 | 4.0008 | $2.2 | |
ARB | <0.01% | $1 | 1.9401 | $1.94 | |
ARB | <0.01% | $2.73 | 0.697 | $1.9 | |
ARB | <0.01% | $0.995624 | 1.6583 | $1.65 | |
ARB | <0.01% | $0.003596 | 421.3369 | $1.52 | |
ARB | <0.01% | $25.77 | 0.0581 | $1.5 | |
ARB | <0.01% | $0.005723 | 261.5389 | $1.5 | |
ARB | <0.01% | $0.031621 | 47.0499 | $1.49 | |
ARB | <0.01% | $0.003201 | 463.2544 | $1.48 | |
ARB | <0.01% | $0.997963 | 1.4682 | $1.47 | |
ARB | <0.01% | $1.79 | 0.8148 | $1.46 | |
ARB | <0.01% | $0.256254 | 5.1659 | $1.32 | |
ARB | <0.01% | <$0.000001 | 18,096,529.7576 | $1.2 | |
ARB | <0.01% | $0.001947 | 461.4691 | $0.8986 | |
ARB | <0.01% | $0.029202 | 29.7149 | $0.8677 | |
ARB | <0.01% | $0.02555 | 32.3934 | $0.8276 | |
ARB | <0.01% | $1 | 0.8076 | $0.8076 | |
ARB | <0.01% | $0.002091 | 379.5889 | $0.7936 | |
ARB | <0.01% | $0.005914 | 130.3026 | $0.7706 | |
ARB | <0.01% | $0.952183 | 0.7464 | $0.7107 | |
ARB | <0.01% | $0.000012 | 55,659.4985 | $0.6673 | |
ARB | <0.01% | $0.022822 | 28.0233 | $0.6395 | |
ARB | <0.01% | $0.018057 | 34.294 | $0.6192 | |
ARB | <0.01% | $3,666.07 | 0.00016888 | $0.6191 | |
ARB | <0.01% | $1.58 | 0.3693 | $0.5834 | |
ARB | <0.01% | $0.17977 | 2.8312 | $0.5089 | |
ARB | <0.01% | $0.022006 | 22.6121 | $0.4976 | |
ARB | <0.01% | $102,287 | 0.00000461 | $0.4715 | |
ARB | <0.01% | $0.046309 | 9.2448 | $0.4281 | |
ARB | <0.01% | $0.00143 | 290.3769 | $0.4153 | |
ARB | <0.01% | <$0.000001 | 1,347,007,939.748 | $0.4041 | |
ARB | <0.01% | $0.130534 | 3.0875 | $0.403 | |
ARB | <0.01% | $0.059146 | 6.6917 | $0.3957 | |
ARB | <0.01% | $0.000111 | 3,550.5754 | $0.3947 | |
ARB | <0.01% | $0.044509 | 8.5155 | $0.379 | |
ARB | <0.01% | $0.118916 | 2.7992 | $0.3328 | |
ARB | <0.01% | $0.093009 | 3.3895 | $0.3152 | |
ARB | <0.01% | $0.000025 | 11,936.429 | $0.2979 | |
ARB | <0.01% | $0.054275 | 4.5965 | $0.2494 | |
ARB | <0.01% | $2.19 | 0.1126 | $0.2466 | |
ARB | <0.01% | $0.000006 | 39,594.8597 | $0.2411 | |
ARB | <0.01% | $0.016423 | 11.5836 | $0.1902 | |
ARB | <0.01% | $0.012671 | 13.5836 | $0.1721 | |
ARB | <0.01% | $0.000034 | 4,965.7938 | $0.1683 | |
ARB | <0.01% | $0.003866 | 36.2122 | $0.1399 | |
ARB | <0.01% | $0.997765 | 0.1323 | $0.1319 | |
ARB | <0.01% | <$0.000001 | 1,166,708,643.6064 | $0.1166 | |
ARB | <0.01% | $0.015879 | 7.2313 | $0.1148 | |
ARB | <0.01% | $0.021001 | 5.3722 | $0.1128 | |
ARB | <0.01% | $0.0013 | 79.4938 | $0.1033 | |
AVAX | <0.01% | $0.000116 | 1,845,270.7827 | $213.35 | |
AVAX | <0.01% | $305.27 | 0.6492 | $198.18 | |
AVAX | <0.01% | $0.00297 | 54,798.4018 | $162.76 | |
AVAX | <0.01% | $0.99902 | 94.3329 | $94.24 | |
AVAX | <0.01% | $0.321881 | 265.0337 | $85.31 | |
AVAX | <0.01% | $35.77 | 1.905 | $68.13 | |
AVAX | <0.01% | $0.5116 | 126.4712 | $64.7 | |
AVAX | <0.01% | $0.99902 | 62.1535 | $62.09 | |
AVAX | <0.01% | $0.013215 | 4,364.5145 | $57.68 | |
AVAX | <0.01% | $0.260489 | 199.1576 | $51.88 | |
AVAX | <0.01% | $1 | 47.6018 | $47.6 | |
AVAX | <0.01% | $0.001444 | 30,510.7162 | $44.05 | |
AVAX | <0.01% | $23.06 | 1.8384 | $42.39 | |
AVAX | <0.01% | $0.999674 | 37.0336 | $37.02 | |
AVAX | <0.01% | $0.000001 | 38,431,572.1023 | $33.29 | |
AVAX | <0.01% | $0.122333 | 214.4218 | $26.23 | |
AVAX | <0.01% | $0.008042 | 3,193.0011 | $25.68 | |
AVAX | <0.01% | $0.025052 | 697.5703 | $17.48 | |
AVAX | <0.01% | $443.11 | 0.0389 | $17.25 | |
AVAX | <0.01% | $0.000913 | 18,204.0939 | $16.62 | |
AVAX | <0.01% | $0.02207 | 723.1155 | $15.96 | |
AVAX | <0.01% | $0.998519 | 14.535 | $14.51 | |
AVAX | <0.01% | $42.35 | 0.3367 | $14.26 | |
AVAX | <0.01% | $24.25 | 0.5107 | $12.39 | |
AVAX | <0.01% | $0.009434 | 1,068.2217 | $10.08 | |
AVAX | <0.01% | $3.69 | 2.3465 | $8.66 | |
AVAX | <0.01% | $0.005373 | 1,543.424 | $8.29 | |
AVAX | <0.01% | $318.5 | 0.0253 | $8.05 | |
AVAX | <0.01% | $0.000002 | 3,273,075.6347 | $7.79 | |
AVAX | <0.01% | $102,284 | 0.00007513 | $7.68 | |
AVAX | <0.01% | <$0.000001 | 113,998,376.6443 | $7.62 | |
AVAX | <0.01% | $0.087308 | 84.8425 | $7.41 | |
AVAX | <0.01% | $0.342212 | 17.7685 | $6.08 | |
AVAX | <0.01% | $0.000007 | 781,067.7071 | $5.48 | |
AVAX | <0.01% | $0.000137 | 34,532.2045 | $4.73 | |
AVAX | <0.01% | $0.99595 | 4.5257 | $4.51 | |
AVAX | <0.01% | $0.004647 | 862.4561 | $4.01 | |
AVAX | <0.01% | $0.99446 | 3.5748 | $3.55 | |
AVAX | <0.01% | $0.005555 | 631.8433 | $3.51 | |
AVAX | <0.01% | $0.000616 | 5,426.7406 | $3.34 | |
AVAX | <0.01% | $0.85826 | 3.6881 | $3.17 | |
AVAX | <0.01% | $0.000686 | 3,621.7052 | $2.48 | |
AVAX | <0.01% | $0.022103 | 105.5094 | $2.33 | |
AVAX | <0.01% | <$0.000001 | 203,378,409.9985 | $2.32 | |
AVAX | <0.01% | $0.001942 | 1,181.8378 | $2.29 | |
AVAX | <0.01% | $0.000253 | 8,680.3173 | $2.19 | |
AVAX | <0.01% | $1.36 | 1.4938 | $2.03 | |
AVAX | <0.01% | $0.989027 | 1.7059 | $1.69 | |
AVAX | <0.01% | $0.027122 | 61.8792 | $1.68 | |
AVAX | <0.01% | $0.138095 | 10.0522 | $1.39 | |
AVAX | <0.01% | $13.42 | 0.0864 | $1.16 | |
AVAX | <0.01% | $102,277 | 0.00000907 | $0.9276 | |
AVAX | <0.01% | $0.066097 | 10.2294 | $0.6761 | |
AVAX | <0.01% | $0.002088 | 292.5373 | $0.6107 | |
AVAX | <0.01% | $0.197893 | 3.0426 | $0.6021 | |
AVAX | <0.01% | $0.000201 | 2,830.7147 | $0.5699 | |
AVAX | <0.01% | $0.012384 | 44.0043 | $0.5449 | |
AVAX | <0.01% | $4.16 | 0.1303 | $0.5421 | |
AVAX | <0.01% | $0.000867 | 590.8053 | $0.5121 | |
AVAX | <0.01% | $0.000021 | 23,450.264 | $0.4816 | |
AVAX | <0.01% | $2.96 | 0.1585 | $0.4688 | |
AVAX | <0.01% | $0.076928 | 5.2545 | $0.4042 | |
AVAX | <0.01% | $0.00002 | 18,333.4 | $0.3705 | |
AVAX | <0.01% | $0.905569 | 0.3703 | $0.3353 | |
AVAX | <0.01% | $0.071521 | 4.1771 | $0.2987 | |
AVAX | <0.01% | $0.198044 | 1.2857 | $0.2546 | |
AVAX | <0.01% | $0.0014 | 166.4385 | $0.2329 | |
AVAX | <0.01% | $0.547411 | 0.3224 | $0.1765 | |
AVAX | <0.01% | $0.002654 | 64.3434 | $0.1707 | |
AVAX | <0.01% | $0.031499 | 5.3575 | $0.1687 | |
AVAX | <0.01% | $0.338934 | 0.464 | $0.1572 | |
AVAX | <0.01% | $0.000052 | 2,765.5777 | $0.1434 | |
AVAX | <0.01% | $0.0001 | 1,409.8189 | $0.1414 | |
AVAX | <0.01% | $0.009278 | 14.7412 | $0.1367 | |
AVAX | <0.01% | $0.000496 | 264.305 | $0.1309 | |
AVAX | <0.01% | $2.47 | 0.0504 | $0.1244 | |
AVAX | <0.01% | $0.003053 | 36.5848 | $0.1116 | |
AVAX | <0.01% | $0.989027 | 0.1127 | $0.1114 | |
AVAX | <0.01% | $0.028064 | 3.6483 | $0.1023 | |
OP | <0.01% | $0.998917 | 77.2003 | $77.12 | |
OP | <0.01% | $1.7 | 39.8173 | $67.81 | |
OP | <0.01% | $1 | 61.7133 | $61.71 | |
OP | <0.01% | $1.91 | 21.7261 | $41.6 | |
OP | <0.01% | $3,280.12 | 0.0117 | $38.46 | |
OP | <0.01% | $24.35 | 1.5301 | $37.26 | |
OP | <0.01% | $0.696909 | 36.2137 | $25.24 | |
OP | <0.01% | $1.58 | 14.8476 | $23.46 | |
OP | <0.01% | $0.649147 | 34.2313 | $22.22 | |
OP | <0.01% | $0.110815 | 162.2111 | $17.98 | |
OP | <0.01% | $4.16 | 2.1489 | $8.94 | |
OP | <0.01% | $2.73 | 3.1725 | $8.66 | |
OP | <0.01% | $1 | 8.3624 | $8.36 | |
OP | <0.01% | $0.015976 | 476.9657 | $7.62 | |
OP | <0.01% | $0.001628 | 4,636.9154 | $7.55 | |
OP | <0.01% | $0.004571 | 1,603.5823 | $7.33 | |
OP | <0.01% | $0.999856 | 6.7755 | $6.77 | |
OP | <0.01% | $2.85 | 1.6495 | $4.7 | |
OP | <0.01% | $0.005913 | 370.4663 | $2.19 | |
OP | <0.01% | $13.42 | 0.1522 | $2.04 | |
OP | <0.01% | $22.8 | 0.0883 | $2.01 | |
OP | <0.01% | $0.98387 | 1.0871 | $1.07 | |
OP | <0.01% | $0.000025 | 37,713.0254 | $0.9605 | |
OP | <0.01% | $3,911.66 | 0.00017685 | $0.6917 | |
OP | <0.01% | $318.5 | 0.0020554 | $0.6546 | |
OP | <0.01% | <$0.000001 | 2,152,376.5335 | $0.4472 | |
OP | <0.01% | $3,658.57 | 0.00012037 | $0.4403 | |
OP | <0.01% | $1 | 0.3974 | $0.3973 | |
OP | <0.01% | $0.539408 | 0.7045 | $0.38 | |
OP | <0.01% | $0.391189 | 0.948 | $0.3708 | |
OP | <0.01% | $0.001688 | 213.1095 | $0.3596 | |
OP | <0.01% | $0.110815 | 3.1717 | $0.3514 | |
OP | <0.01% | $0.046508 | 5.55 | $0.2581 | |
OP | <0.01% | $0.001241 | 187.4643 | $0.2326 | |
OP | <0.01% | $0.000246 | 873.2761 | $0.2143 | |
OP | <0.01% | $0.005158 | 33.0435 | $0.1704 | |
OP | <0.01% | $0.001003 | 112.382 | $0.1126 | |
BASE | <0.01% | $0.01836 | 1,331.6998 | $24.45 | |
BASE | <0.01% | $0.003638 | 6,502 | $23.65 | |
BASE | <0.01% | $0.011661 | 1,180.9577 | $13.77 | |
BASE | <0.01% | $0.060021 | 189.224 | $11.36 | |
BASE | <0.01% | $0.000273 | 10,563 | $2.88 | |
BASE | <0.01% | $0.000006 | 200,004.2069 | $1.18 | |
BASE | <0.01% | $0.014896 | 25 | $0.3724 | |
GNO | <0.01% | $0.097376 | 4.4495 | $0.4332 |
Loading...
Loading
[ 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.