Feature Tip: Add private address tag to any address under My Name Tag !
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
0x3d602d80 | 21122941 | 336 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
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": {} }
Contract ABI
API[{"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 | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
BSC | 99.73% | $0.004571 | 77,592,245,344,405.391 | $354,684,669,408.86 | |
BSC | <0.01% | $0.000622 | 9,189,319,923.7873 | $5,718,521.49 | |
BSC | <0.01% | $0.144765 | 1,908,484.571 | $276,281.78 | |
BSC | <0.01% | $3.77 | 72,054.0192 | $271,643.65 | |
BSC | <0.01% | $0.009053 | 5,034,061.9237 | $45,570.85 | |
BSC | <0.01% | $0.000106 | 70,103,711.2959 | $7,418.37 | |
BSC | <0.01% | $1 | 243.868 | $244.45 | |
BSC | <0.01% | <$0.000001 | 2,308,400,767.8867 | $77.15 | |
BSC | <0.01% | $1,300.86 | 0.0568 | $73.94 | |
BSC | <0.01% | $0.300687 | 159.2913 | $47.9 | |
BSC | <0.01% | $1 | 47.6754 | $47.68 | |
BSC | <0.01% | $5.75 | 7.6387 | $43.92 | |
BSC | <0.01% | $0.000053 | 801,124.6315 | $42.2 | |
BSC | <0.01% | $0.039824 | 1,002.4292 | $39.92 | |
BSC | <0.01% | $0.000163 | 221,378.2916 | $36.19 | |
BSC | <0.01% | $0.189446 | 190.2309 | $36.04 | |
BSC | <0.01% | $28.46 | 1.2039 | $34.26 | |
BSC | <0.01% | $2.79 | 12.1077 | $33.78 | |
BSC | <0.01% | $2.88 | 9.1358 | $26.27 | |
BSC | <0.01% | $0.471118 | 55.0679 | $25.94 | |
BSC | <0.01% | $2.11 | 12.1022 | $25.54 | |
BSC | <0.01% | $0.062523 | 390.7768 | $24.43 | |
BSC | <0.01% | $0.002315 | 10,444.2441 | $24.18 | |
BSC | <0.01% | $0.000382 | 61,721.5489 | $23.56 | |
BSC | <0.01% | $33.76 | 0.6958 | $23.49 | |
BSC | <0.01% | <$0.000001 | 23,103,086,855.5283 | $22.61 | |
BSC | <0.01% | $0.00 | 17.2744 | $0.00 | |
BSC | <0.01% | $0.123092 | 182.3474 | $22.45 | |
BSC | <0.01% | $0.000324 | 67,786.0436 | $21.99 | |
BSC | <0.01% | $0.098184 | 223.0377 | $21.9 | |
BSC | <0.01% | $1.04 | 20.3239 | $21.17 | |
BSC | <0.01% | $122,778 | 0.00016804 | $20.63 | |
BSC | <0.01% | $4.26 | 4.48 | $19.08 | |
BSC | <0.01% | $23.62 | 0.7993 | $18.88 | |
BSC | <0.01% | $0.064239 | 286.6647 | $18.42 | |
BSC | <0.01% | $0.006286 | 2,879.3396 | $18.1 | |
BSC | <0.01% | $0.00 | 63.0713 | $0.00 | |
BSC | <0.01% | $0.000001 | 20,266,589.548 | $17.48 | |
BSC | <0.01% | <$0.000001 | 1,412,214,745.5715 | $17.12 | |
BSC | <0.01% | $0.114228 | 148.3782 | $16.95 | |
BSC | <0.01% | $0.003729 | 4,486.7935 | $16.73 | |
BSC | <0.01% | $0.466001 | 33.2679 | $15.5 | |
BSC | <0.01% | $0.252111 | 61.3786 | $15.47 | |
BSC | <0.01% | $22.07 | 0.7007 | $15.46 | |
BSC | <0.01% | $1,376.09 | 0.0104 | $14.37 | |
BSC | <0.01% | <$0.000001 | 86,634,732.7085 | $14.31 | |
BSC | <0.01% | $0.001175 | 11,864.2281 | $13.94 | |
BSC | <0.01% | $0.229677 | 59.417 | $13.65 | |
BSC | <0.01% | $0.00 | 289,815,439.024 | $0.00 | |
BSC | <0.01% | $0.249159 | 54.124 | $13.49 | |
BSC | <0.01% | $1.12 | 12.0049 | $13.44 | |
BSC | <0.01% | $0.000165 | 80,812.167 | $13.33 | |
BSC | <0.01% | $1.44 | 8.904 | $12.84 | |
BSC | <0.01% | $2.02 | 6.1357 | $12.4 | |
BSC | <0.01% | $0.015658 | 783.8032 | $12.27 | |
BSC | <0.01% | $0.340541 | 32.2824 | $10.99 | |
BSC | <0.01% | $0.28118 | 37.4436 | $10.53 | |
BSC | <0.01% | $0.002202 | 4,759.8831 | $10.48 | |
BSC | <0.01% | $0.010946 | 926.3359 | $10.14 | |
BSC | <0.01% | $0.059915 | 166.024 | $9.95 | |
BSC | <0.01% | $0.001172 | 7,926.3849 | $9.29 | |
BSC | <0.01% | $0.330726 | 27.9495 | $9.24 | |
BSC | <0.01% | $0.085928 | 101.1723 | $8.69 | |
BSC | <0.01% | $0.000049 | 169,928.0558 | $8.35 | |
BSC | <0.01% | $0.998494 | 8.3512 | $8.34 | |
BSC | <0.01% | $142.39 | 0.0573 | $8.16 | |
BSC | <0.01% | <$0.000001 | 959,298,933,898.7125 | $7.99 | |
BSC | <0.01% | $0.000012 | 650,976.6053 | $7.93 | |
BSC | <0.01% | $122,132 | 0.00006148 | $7.51 | |
BSC | <0.01% | $1,301.68 | 0.00563593 | $7.34 | |
BSC | <0.01% | $0.001503 | 4,785.9151 | $7.19 | |
BSC | <0.01% | $0.000002 | 3,597,305.8155 | $7.05 | |
BSC | <0.01% | $0.097179 | 69.5812 | $6.76 | |
BSC | <0.01% | $0.630467 | 10.3545 | $6.53 | |
BSC | <0.01% | $0.000009 | 675,438.1929 | $6.33 | |
BSC | <0.01% | $0.00 | 561.3169 | $0.00 | |
BSC | <0.01% | $0.000409 | 13,725.6897 | $5.61 | |
BSC | <0.01% | $0.025548 | 218.3989 | $5.58 | |
BSC | <0.01% | <$0.000001 | 7,106,723,361.7296 | $5.54 | |
BSC | <0.01% | $0.262246 | 20.2368 | $5.31 | |
BSC | <0.01% | $0.012547 | 413.2627 | $5.19 | |
BSC | <0.01% | $0.000276 | 17,690.8487 | $4.87 | |
BSC | <0.01% | $0.011853 | 406.372 | $4.82 | |
BSC | <0.01% | $0.000915 | 5,179.1202 | $4.74 | |
BSC | <0.01% | <$0.000001 | 52,112,974.9302 | $4.51 | |
BSC | <0.01% | $0.080107 | 54.7307 | $4.38 | |
BSC | <0.01% | <$0.000001 | 2,625,612,985.8038 | $3.99 | |
BSC | <0.01% | $2.42 | 1.6024 | $3.88 | |
BSC | <0.01% | $0.0277 | 131.724 | $3.65 | |
BSC | <0.01% | $4.71 | 0.767 | $3.61 | |
BSC | <0.01% | $0.001144 | 3,145.9717 | $3.6 | |
BSC | <0.01% | $0.000001 | 2,460,663.9542 | $3.52 | |
BSC | <0.01% | <$0.000001 | 438,708,216.595 | $3.34 | |
BSC | <0.01% | $0.073349 | 42.4503 | $3.11 | |
BSC | <0.01% | $12.48 | 0.2468 | $3.08 | |
BSC | <0.01% | $0.000407 | 7,499.4999 | $3.05 | |
BSC | <0.01% | $0.177775 | 16.3123 | $2.9 | |
BSC | <0.01% | $221.78 | 0.0122 | $2.71 | |
BSC | <0.01% | $0.000916 | 2,840.8844 | $2.6 | |
BSC | <0.01% | $0.00 | 2.1529 | $0.00 | |
BSC | <0.01% | $0.002497 | 1,013.1583 | $2.53 | |
BSC | <0.01% | $0.009808 | 251.6355 | $2.47 | |
BSC | <0.01% | $0.605132 | 3.9519 | $2.39 | |
BSC | <0.01% | $2.73 | 0.8212 | $2.24 | |
BSC | <0.01% | $0.004515 | 484.4418 | $2.19 | |
BSC | <0.01% | $0.083053 | 25.4333 | $2.11 | |
BSC | <0.01% | $0.024416 | 85.6065 | $2.09 | |
BSC | <0.01% | $0.02964 | 69.1251 | $2.05 | |
BSC | <0.01% | $0.00425 | 462.4154 | $1.97 | |
BSC | <0.01% | $0.005108 | 380.1616 | $1.94 | |
BSC | <0.01% | $0.772839 | 2.4548 | $1.9 | |
BSC | <0.01% | <$0.000001 | 5,191,174,175,747.7324 | $1.88 | |
BSC | <0.01% | <$0.000001 | 1,407,283,660.9778 | $1.86 | |
BSC | <0.01% | $0.022865 | 81.2699 | $1.86 | |
BSC | <0.01% | $0.000009 | 205,372.1621 | $1.83 | |
BSC | <0.01% | $0.040089 | 45.4717 | $1.82 | |
BSC | <0.01% | <$0.000001 | 9,727,444.0412 | $1.82 | |
BSC | <0.01% | <$0.000001 | 4,579,964,851.2189 | $1.75 | |
BSC | <0.01% | $0.004219 | 413.4773 | $1.74 | |
BSC | <0.01% | $0.002702 | 638.8511 | $1.73 | |
BSC | <0.01% | $4.15 | 0.4076 | $1.69 | |
BSC | <0.01% | $0.001752 | 879.3238 | $1.54 | |
BSC | <0.01% | $0.000466 | 3,144.4813 | $1.47 | |
BSC | <0.01% | $0.005841 | 248.9437 | $1.45 | |
BSC | <0.01% | $0.279104 | 5.1744 | $1.44 | |
BSC | <0.01% | $0.01188 | 120.3568 | $1.43 | |
BSC | <0.01% | $0.011753 | 119.3765 | $1.4 | |
BSC | <0.01% | $0.509099 | 2.7409 | $1.4 | |
BSC | <0.01% | <$0.000001 | 4,731,425,449.1472 | $1.39 | |
BSC | <0.01% | $0.066718 | 20.6 | $1.37 | |
BSC | <0.01% | $0.028451 | 47.4645 | $1.35 | |
BSC | <0.01% | <$0.000001 | 17,844,975,164 | $1.33 | |
BSC | <0.01% | $0.033707 | 38.7658 | $1.31 | |
BSC | <0.01% | $0.822377 | 1.5879 | $1.31 | |
BSC | <0.01% | $0.006534 | 199.0114 | $1.3 | |
BSC | <0.01% | $0.997538 | 1.2654 | $1.26 | |
BSC | <0.01% | $0.006032 | 207.8548 | $1.25 | |
BSC | <0.01% | $116.82 | 0.0102 | $1.2 | |
BSC | <0.01% | <$0.000001 | 267,444,345.834 | $1.15 | |
BSC | <0.01% | $1.14 | 1.0024 | $1.14 | |
BSC | <0.01% | $0.00 | 0.00023803 | $0.00 | |
BSC | <0.01% | $0.00 | 19.425 | $0.00 | |
BSC | <0.01% | $6.48 | 0.1674 | $1.08 | |
BSC | <0.01% | $0.004785 | 221.8532 | $1.06 | |
BSC | <0.01% | <$0.000001 | 7,251,377,735.9174 | $1.06 | |
BSC | <0.01% | $0.000002 | 523,381.7828 | $1.06 | |
BSC | <0.01% | $0.000557 | 1,870.9222 | $1.04 | |
BSC | <0.01% | $280.36 | 0.00368165 | $1.03 | |
BSC | <0.01% | $0.004074 | 249.9333 | $1.02 | |
BSC | <0.01% | $2.29 | 0.4416 | $1.01 | |
BSC | <0.01% | $0.167749 | 5.9967 | $1.01 | |
BSC | <0.01% | $0.00002 | 49,634.1778 | $0.9852 | |
BSC | <0.01% | $0.232655 | 4.2283 | $0.9837 | |
BSC | <0.01% | <$0.000001 | 366,412,290.2254 | $0.9581 | |
BSC | <0.01% | $0.003424 | 279.1738 | $0.9558 | |
BSC | <0.01% | $0.101422 | 9.1865 | $0.9317 | |
BSC | <0.01% | $0.00 | 23,110,536.1254 | $0.00 | |
BSC | <0.01% | $0.000063 | 13,621.9266 | $0.8598 | |
BSC | <0.01% | $0.01024 | 82.4339 | $0.844 | |
BSC | <0.01% | $0.008791 | 93.2472 | $0.8197 | |
BSC | <0.01% | $0.008772 | 89.7288 | $0.787 | |
BSC | <0.01% | $0.00 | 642.7815 | $0.00 | |
BSC | <0.01% | <$0.000001 | 50,694,344.1177 | $0.7756 | |
BSC | <0.01% | $0.997731 | 0.7707 | $0.769 | |
BSC | <0.01% | $0.103182 | 7.4093 | $0.7645 | |
BSC | <0.01% | $0.000001 | 1,226,293.2401 | $0.7405 | |
BSC | <0.01% | $4.08 | 0.1747 | $0.7131 | |
BSC | <0.01% | $0.004647 | 150.8758 | $0.7011 | |
BSC | <0.01% | $0.010887 | 63.2667 | $0.6887 | |
BSC | <0.01% | $0.128169 | 5.2804 | $0.6767 | |
BSC | <0.01% | $0.000501 | 1,284.0579 | $0.6432 | |
BSC | <0.01% | $0.00 | 4.8821 | $0.00 | |
BSC | <0.01% | <$0.000001 | 378,675,289,641.5526 | $0.6153 | |
BSC | <0.01% | $0.192272 | 3.1902 | $0.6133 | |
BSC | <0.01% | $0.000043 | 14,233.596 | $0.6114 | |
BSC | <0.01% | $0.026567 | 22.7887 | $0.6054 | |
BSC | <0.01% | $0.236286 | 2.5612 | $0.6051 | |
BSC | <0.01% | $0.21861 | 2.7578 | $0.6028 | |
BSC | <0.01% | $0.000189 | 3,183.7279 | $0.6013 | |
BSC | <0.01% | $0.000001 | 1,010,097.6369 | $0.5968 | |
BSC | <0.01% | $0.001086 | 549.3394 | $0.5965 | |
BSC | <0.01% | <$0.000001 | 246,374,986,672.7584 | $0.5893 | |
BSC | <0.01% | $0.304275 | 1.8267 | $0.5558 | |
BSC | <0.01% | $0.407881 | 1.3363 | $0.545 | |
BSC | <0.01% | $0.127914 | 4.2398 | $0.5423 | |
BSC | <0.01% | $578.8 | 0.00091246 | $0.5281 | |
BSC | <0.01% | $0.002108 | 241.7899 | $0.5096 | |
BSC | <0.01% | $0.046546 | 10.9495 | $0.5096 | |
BSC | <0.01% | $0.003546 | 139.2999 | $0.4939 | |
BSC | <0.01% | $0.004542 | 107.3416 | $0.4875 | |
BSC | <0.01% | $0.00 | 894.0212 | $0.00 | |
BSC | <0.01% | $0.01564 | 29.3269 | $0.4586 | |
BSC | <0.01% | $0.185338 | 2.4432 | $0.4528 | |
BSC | <0.01% | $0.000711 | 636.3788 | $0.4521 | |
BSC | <0.01% | $7.83 | 0.0557 | $0.4361 | |
BSC | <0.01% | $0.018503 | 23.3924 | $0.4328 | |
BSC | <0.01% | $0.004272 | 99.595 | $0.4254 | |
BSC | <0.01% | $0.001483 | 283.527 | $0.4204 | |
BSC | <0.01% | $0.011579 | 36.1002 | $0.4179 | |
BSC | <0.01% | $0.00 | 0.8172 | $0.00 | |
BSC | <0.01% | $0.269385 | 1.5303 | $0.4122 | |
BSC | <0.01% | $0.03412 | 12.0834 | $0.4122 | |
BSC | <0.01% | $0.00 | 17,470.6041 | $0.00 | |
BSC | <0.01% | $0.584645 | 0.6921 | $0.4046 | |
BSC | <0.01% | $0.111355 | 3.5532 | $0.3956 | |
BSC | <0.01% | $1 | 0.3907 | $0.391 | |
BSC | <0.01% | $2.95 | 0.1311 | $0.3861 | |
BSC | <0.01% | $0.009231 | 41.2413 | $0.3806 | |
BSC | <0.01% | $0.084399 | 4.4336 | $0.3741 | |
BSC | <0.01% | $0.005301 | 70.0902 | $0.3715 | |
BSC | <0.01% | $0.538722 | 0.6859 | $0.3695 | |
BSC | <0.01% | <$0.000001 | 6,644,193,545,702.4863 | $0.3667 | |
BSC | <0.01% | $0.06677 | 5.4786 | $0.3658 | |
BSC | <0.01% | $0.151271 | 2.3321 | $0.3527 | |
BSC | <0.01% | $0.128882 | 2.7247 | $0.3511 | |
BSC | <0.01% | $0.193229 | 1.7904 | $0.3459 | |
BSC | <0.01% | <$0.000001 | 804,961.3128 | $0.3453 | |
BSC | <0.01% | $0.000232 | 1,438.0156 | $0.3332 | |
BSC | <0.01% | $0.085502 | 3.8437 | $0.3286 | |
BSC | <0.01% | $0.025633 | 12.7078 | $0.3257 | |
BSC | <0.01% | $0.300142 | 1.0452 | $0.3137 | |
BSC | <0.01% | $0.767613 | 0.4082 | $0.3133 | |
BSC | <0.01% | <$0.000001 | 2,299,347.6142 | $0.2997 | |
BSC | <0.01% | $0.095654 | 3.1055 | $0.297 | |
BSC | <0.01% | $0.000023 | 12,966.8642 | $0.2951 | |
BSC | <0.01% | $0.001633 | 180.6963 | $0.2951 | |
BSC | <0.01% | $0.003939 | 74.6809 | $0.2941 | |
BSC | <0.01% | $0.00 | 4.6999 | $0.00 | |
BSC | <0.01% | $122,225 | 0.00000232 | $0.2831 | |
BSC | <0.01% | $0.00 | 90.8263 | $0.00 | |
BSC | <0.01% | $0.000356 | 747.4478 | $0.266 | |
BSC | <0.01% | $0.022417 | 11.5124 | $0.258 | |
BSC | <0.01% | $0.000013 | 19,279.6194 | $0.2579 | |
BSC | <0.01% | $0.021716 | 11.2661 | $0.2446 | |
BSC | <0.01% | $1.18 | 0.2049 | $0.2425 | |
BSC | <0.01% | $0.209404 | 1.156 | $0.242 | |
BSC | <0.01% | $0.000005 | 44,823.3469 | $0.2278 | |
BSC | <0.01% | $0.000121 | 1,851.198 | $0.2236 | |
BSC | <0.01% | $0.013862 | 15.9129 | $0.2205 | |
BSC | <0.01% | $0.004535 | 47.5076 | $0.2154 | |
BSC | <0.01% | $0.000726 | 295.2716 | $0.2143 | |
BSC | <0.01% | $0.157406 | 1.3463 | $0.2119 | |
BSC | <0.01% | $0.002199 | 95.9178 | $0.2109 | |
BSC | <0.01% | $0.8656 | 0.239 | $0.2069 | |
BSC | <0.01% | <$0.000001 | 29,433,895.9123 | $0.2051 | |
BSC | <0.01% | $0.00037 | 539.3806 | $0.1993 | |
BSC | <0.01% | $0.01373 | 14.4626 | $0.1985 | |
BSC | <0.01% | $0.000012 | 15,882.3633 | $0.1977 | |
BSC | <0.01% | $0.014944 | 13.1962 | $0.1972 | |
BSC | <0.01% | $0.000375 | 525.9322 | $0.1971 | |
BSC | <0.01% | $1,366.75 | 0.00014331 | $0.1958 | |
BSC | <0.01% | $0.002664 | 72.4301 | $0.1929 | |
BSC | <0.01% | $0.257576 | 0.7291 | $0.1877 | |
BSC | <0.01% | $42.49 | 0.00423008 | $0.1797 | |
BSC | <0.01% | $0.024687 | 7.2597 | $0.1792 | |
BSC | <0.01% | $0.018274 | 9.7961 | $0.179 | |
BSC | <0.01% | $0.000058 | 3,064.4327 | $0.1763 | |
BSC | <0.01% | $0.009633 | 18.0659 | $0.174 | |
BSC | <0.01% | $0.000042 | 4,092.1019 | $0.1713 | |
BSC | <0.01% | <$0.000001 | 60,708,794.1555 | $0.1712 | |
BSC | <0.01% | $0.999161 | 0.1689 | $0.1687 | |
BSC | <0.01% | <$0.000001 | 72,336,453.5665 | $0.1672 | |
BSC | <0.01% | $0.000356 | 459.6011 | $0.1637 | |
BSC | <0.01% | $0.002579 | 63.1679 | $0.1629 | |
BSC | <0.01% | $0.060377 | 2.6 | $0.1569 | |
BSC | <0.01% | <$0.000001 | 848,409.1099 | $0.1541 | |
BSC | <0.01% | $0.027973 | 5.4431 | $0.1522 | |
BSC | <0.01% | $0.329043 | 0.4517 | $0.1486 | |
BSC | <0.01% | $0.28937 | 0.5087 | $0.1472 | |
BSC | <0.01% | $0.002148 | 67.4627 | $0.1449 | |
BSC | <0.01% | $4,486.22 | 0.00003187 | $0.1429 | |
BSC | <0.01% | $0.050171 | 2.8501 | $0.1429 | |
BSC | <0.01% | $0.023723 | 5.9054 | $0.14 | |
BSC | <0.01% | $0.110747 | 1.247 | $0.1381 | |
BSC | <0.01% | $0.003562 | 37.1189 | $0.1322 | |
BSC | <0.01% | $0.005766 | 22.8301 | $0.1316 | |
BSC | <0.01% | $0.208741 | 0.613 | $0.1279 | |
BSC | <0.01% | <$0.000001 | 4,153,643,069.0151 | $0.1248 | |
BSC | <0.01% | $0.065542 | 1.7443 | $0.1143 | |
BSC | <0.01% | $0.000271 | 420.6305 | $0.1138 | |
BSC | <0.01% | $0.000087 | 1,283.6899 | $0.1118 | |
BSC | <0.01% | $0.000012 | 9,113.4573 | $0.1112 | |
BSC | <0.01% | $0.000015 | 7,275.2835 | $0.1092 | |
BSC | <0.01% | $0.001565 | 67.942 | $0.1063 | |
BSC | <0.01% | $0.00017 | 616.447 | $0.1046 | |
ETH | 0.27% | <$0.000001 | 9,510,961,006,838,250 | $951,316,216.42 | |
ETH | <0.01% | $3,702,596.32 | 0.4546 | $1,683,211.13 | |
ETH | <0.01% | $0.066347 | 65,952.0693 | $4,375.72 | |
ETH | <0.01% | $0.143395 | 27,030.1995 | $3,876 | |
ETH | <0.01% | $0.007241 | 73,344.7349 | $531.09 | |
ETH | <0.01% | $4,479.94 | 0.1054 | $472.17 | |
ETH | <0.01% | $122,462 | 0.0037015 | $453.29 | |
ETH | <0.01% | $4.71 | 92.6754 | $436.5 | |
ETH | <0.01% | $1.86 | 211.1394 | $392.72 | |
ETH | <0.01% | $0.253202 | 1,450.4639 | $367.26 | |
ETH | <0.01% | $0.053268 | 6,862.3049 | $365.54 | |
ETH | <0.01% | $1.77 | 204.9972 | $362.84 | |
ETH | <0.01% | $0.177543 | 1,854.8519 | $329.32 | |
ETH | <0.01% | $0.114194 | 2,874.8482 | $328.29 | |
ETH | <0.01% | $4,756.07 | 0.0689 | $327.82 | |
ETH | <0.01% | $1 | 327.1958 | $327.2 | |
ETH | <0.01% | $0.746194 | 430.5176 | $321.25 | |
ETH | <0.01% | $5,445.88 | 0.0574 | $312.7 | |
ETH | <0.01% | $0.027584 | 11,254.2058 | $310.43 | |
ETH | <0.01% | $4,698.14 | 0.0627 | $294.66 | |
ETH | <0.01% | $0.000748 | 377,408.6686 | $282.42 | |
ETH | <0.01% | $1.91 | 142.8395 | $272.82 | |
ETH | <0.01% | $0.0083 | 32,862.6996 | $272.76 | |
ETH | <0.01% | $1.72 | 158.3883 | $272.43 | |
ETH | <0.01% | $0.003449 | 78,320.0406 | $270.09 | |
ETH | <0.01% | $0.000009 | 27,997,900.4565 | $262.06 | |
ETH | <0.01% | $0.000001 | 278,425,570.3897 | $256.44 | |
ETH | <0.01% | <$0.000001 | 6,534,317,546.8863 | $253.41 | |
ETH | <0.01% | $0.00392 | 64,456.8979 | $252.65 | |
ETH | <0.01% | <$0.000001 | 53,627,019,866.885 | $245.18 | |
ETH | <0.01% | $22.04 | 11.0637 | $243.84 | |
ETH | <0.01% | $0.010887 | 22,268.7708 | $242.44 | |
ETH | <0.01% | $222.4 | 1.0848 | $241.26 | |
ETH | <0.01% | <$0.000001 | 495,437,390,775.731 | $238.72 | |
ETH | <0.01% | $0.05832 | 4,077.5316 | $237.8 | |
ETH | <0.01% | $0.000351 | 645,895.1017 | $226.67 | |
ETH | <0.01% | $0.200898 | 1,119.3415 | $224.87 | |
ETH | <0.01% | $0.000001 | 368,995,282.0668 | $222.73 | |
ETH | <0.01% | $0.000012 | 18,224,377.4826 | $222.16 | |
ETH | <0.01% | $2.45 | 90.2041 | $221 | |
ETH | <0.01% | $0.540556 | 407.6955 | $220.38 | |
ETH | <0.01% | $0.451643 | 484.5372 | $218.84 | |
ETH | <0.01% | $4,057.65 | 0.0537 | $217.94 | |
ETH | <0.01% | $0.004185 | 50,581.6205 | $211.67 | |
ETH | <0.01% | $20.87 | 10.1014 | $210.82 | |
ETH | <0.01% | $122,710 | 0.00171398 | $210.32 | |
ETH | <0.01% | <$0.000001 | 1,606,135,451.4383 | $209.36 | |
ETH | <0.01% | $0.003593 | 58,162.5426 | $209 | |
ETH | <0.01% | $0.129047 | 1,595.9212 | $205.95 | |
ETH | <0.01% | $0.00076 | 264,657.4465 | $201.09 | |
ETH | <0.01% | $7.84 | 25.4961 | $199.89 | |
ETH | <0.01% | $4.57 | 42.3619 | $193.79 | |
ETH | <0.01% | $0.998835 | 192.7544 | $192.53 | |
ETH | <0.01% | $0.65577 | 293.3917 | $192.4 | |
ETH | <0.01% | $2.17 | 87.2524 | $189.34 | |
ETH | <0.01% | $1.31 | 144.3201 | $189.06 | |
ETH | <0.01% | $0.108506 | 1,732.0395 | $187.94 | |
ETH | <0.01% | $0.082552 | 2,263.5886 | $186.86 | |
ETH | <0.01% | $0.009162 | 20,261.8506 | $185.64 | |
ETH | <0.01% | $0.282379 | 657.1801 | $185.57 | |
ETH | <0.01% | $0.999982 | 182.8336 | $182.83 | |
ETH | <0.01% | $3.38 | 53.0441 | $179.29 | |
ETH | <0.01% | $0.000009 | 19,557,797.6778 | $177.91 | |
ETH | <0.01% | $0.031666 | 5,458.9318 | $172.86 | |
ETH | <0.01% | $4,937.69 | 0.0349 | $172.51 | |
ETH | <0.01% | $0.204031 | 819.0007 | $167.1 | |
ETH | <0.01% | $0.000051 | 3,230,160.7598 | $166 | |
ETH | <0.01% | $4,519.36 | 0.036 | $162.78 | |
ETH | <0.01% | $0.00044 | 364,218.7284 | $160.12 | |
ETH | <0.01% | $0.029435 | 5,421.8908 | $159.59 | |
ETH | <0.01% | $1,303.67 | 0.1216 | $158.55 | |
ETH | <0.01% | $0.771734 | 204.7056 | $157.98 | |
ETH | <0.01% | $0.01946 | 8,062.3306 | $156.9 | |
ETH | <0.01% | $122,439 | 0.00127963 | $156.68 | |
ETH | <0.01% | $0.585256 | 266.4654 | $155.95 | |
ETH | <0.01% | $0.395173 | 394.1255 | $155.75 | |
ETH | <0.01% | $0.910533 | 170.4974 | $155.24 | |
ETH | <0.01% | $0.074863 | 1,969.2456 | $147.42 | |
ETH | <0.01% | $0.20108 | 720.0897 | $144.8 | |
ETH | <0.01% | $0.016696 | 8,457.1447 | $141.2 | |
ETH | <0.01% | $2.9 | 48.0934 | $139.47 | |
ETH | <0.01% | $1.09 | 127.3645 | $138.95 | |
ETH | <0.01% | $0.005771 | 24,031.8244 | $138.68 | |
ETH | <0.01% | $17.77 | 7.741 | $137.56 | |
ETH | <0.01% | $1,600.97 | 0.0858 | $137.37 | |
ETH | <0.01% | $0.054518 | 2,500.7233 | $136.33 | |
ETH | <0.01% | $0.030385 | 4,378.0037 | $133.02 | |
ETH | <0.01% | $1.19 | 111.0848 | $132.19 | |
ETH | <0.01% | $1.24 | 105.5301 | $130.86 | |
ETH | <0.01% | $0.004448 | 29,087.68 | $129.37 | |
ETH | <0.01% | <$0.000001 | 1,704,530,434,340,648 | $126.74 | |
ETH | <0.01% | $0.006527 | 18,974.5396 | $123.85 | |
ETH | <0.01% | $0.011053 | 11,155.9162 | $123.31 | |
ETH | <0.01% | $1.55 | 79.2747 | $122.88 | |
ETH | <0.01% | $0.009719 | 12,617.5727 | $122.62 | |
ETH | <0.01% | $0.006727 | 18,105.3739 | $121.79 | |
ETH | <0.01% | $0.00029 | 419,517.1982 | $121.49 | |
ETH | <0.01% | $0.074458 | 1,631.621 | $121.49 | |
ETH | <0.01% | $0.053488 | 2,258.2274 | $120.79 | |
ETH | <0.01% | $3.48 | 34.0722 | $118.6 | |
ETH | <0.01% | $0.063913 | 1,837.4289 | $117.44 | |
ETH | <0.01% | $0.695291 | 167.4216 | $116.41 | |
ETH | <0.01% | $0.008509 | 13,523.5005 | $115.08 | |
ETH | <0.01% | $0.000002 | 68,915,237.6845 | $112.75 | |
ETH | <0.01% | $6.57 | 17.0443 | $111.98 | |
ETH | <0.01% | $0.192102 | 582.5508 | $111.91 | |
ETH | <0.01% | <$0.000001 | 307,245,084.9067 | $111 | |
ETH | <0.01% | $0.087576 | 1,260.5607 | $110.39 | |
ETH | <0.01% | $0.235823 | 456.6712 | $107.69 | |
ETH | <0.01% | $0.03638 | 2,942.9554 | $107.07 | |
ETH | <0.01% | $0.064627 | 1,653.465 | $106.86 | |
ETH | <0.01% | $4,054.02 | 0.0262 | $106.3 | |
ETH | <0.01% | $0.000099 | 1,053,230.9644 | $104.6 | |
ETH | <0.01% | $0.25057 | 410.8288 | $102.94 | |
ETH | <0.01% | $5,856.69 | 0.0176 | $102.82 | |
ETH | <0.01% | $0.047098 | 2,179.2248 | $102.64 | |
ETH | <0.01% | $280.08 | 0.3637 | $101.86 | |
ETH | <0.01% | $0.005473 | 18,305.6532 | $100.19 | |
ETH | <0.01% | $0.000037 | 2,703,150.4144 | $99.91 | |
ETH | <0.01% | $0.003644 | 26,800.0351 | $97.67 | |
ETH | <0.01% | $0.054474 | 1,787.6892 | $97.38 | |
ETH | <0.01% | $5,454.3 | 0.0176 | $96.03 | |
ETH | <0.01% | $0.546081 | 172.8424 | $94.39 | |
ETH | <0.01% | <$0.000001 | 2,383,227,973.7196 | $93.47 | |
ETH | <0.01% | $100.99 | 0.9088 | $91.78 | |
ETH | <0.01% | $0.12499 | 728.8858 | $91.1 | |
ETH | <0.01% | $0.138115 | 658.4928 | $90.95 | |
ETH | <0.01% | $0.005957 | 15,160.0132 | $90.31 | |
ETH | <0.01% | $1.19 | 75.3085 | $89.62 | |
ETH | <0.01% | $0.007616 | 11,740.0038 | $89.41 | |
ETH | <0.01% | $0.074309 | 1,198.607 | $89.07 | |
ETH | <0.01% | $0.365057 | 238.7153 | $87.14 | |
ETH | <0.01% | $0.308145 | 282.3303 | $87 | |
ETH | <0.01% | $0.004073 | 21,332.7719 | $86.9 | |
ETH | <0.01% | $1.03 | 81.0967 | $83.84 | |
ETH | <0.01% | $0.055821 | 1,492.2901 | $83.3 | |
ETH | <0.01% | <$0.000001 | 21,291,162,867.3873 | $82.72 | |
ETH | <0.01% | $17.99 | 4.5105 | $81.14 | |
ETH | <0.01% | $0.00002 | 4,056,143.4898 | $80.39 | |
ETH | <0.01% | $0.328076 | 242.4426 | $79.54 | |
ETH | <0.01% | <$0.000001 | 2,298,005,685.4966 | $79.05 | |
ETH | <0.01% | $0.08931 | 871.7143 | $77.85 | |
ETH | <0.01% | <$0.000001 | 2,314,064,534.7513 | $77.31 | |
ETH | <0.01% | $0.404517 | 190.1343 | $76.91 | |
ETH | <0.01% | $0.186766 | 403.9693 | $75.45 | |
ETH | <0.01% | $0.000961 | 77,927.8123 | $74.85 | |
ETH | <0.01% | $0.129333 | 568.6458 | $73.54 | |
ETH | <0.01% | $0.000042 | 1,745,292.2845 | $73.3 | |
ETH | <0.01% | $0.577847 | 126.8398 | $73.29 | |
ETH | <0.01% | $0.000268 | 271,524.1656 | $72.81 | |
ETH | <0.01% | $0.000048 | 1,512,149.4514 | $71.86 | |
ETH | <0.01% | $0.067309 | 1,067.385 | $71.84 | |
ETH | <0.01% | $0.006866 | 10,359.3954 | $71.12 | |
ETH | <0.01% | $0.550375 | 128.5965 | $70.78 | |
ETH | <0.01% | $0.373679 | 188.7052 | $70.52 | |
ETH | <0.01% | $14.93 | 4.6578 | $69.54 | |
ETH | <0.01% | $0.002434 | 28,150.7027 | $68.51 | |
ETH | <0.01% | $21.84 | 3.0986 | $67.67 | |
ETH | <0.01% | $0.305163 | 220.5061 | $67.29 | |
ETH | <0.01% | $0.048754 | 1,367.907 | $66.69 | |
ETH | <0.01% | $0.015869 | 4,198.9637 | $66.63 | |
ETH | <0.01% | $0.12736 | 511.3923 | $65.13 | |
ETH | <0.01% | $0.02206 | 2,899.9474 | $63.97 | |
ETH | <0.01% | $0.702264 | 90.8871 | $63.83 | |
ETH | <0.01% | $0.040893 | 1,557.3801 | $63.69 | |
ETH | <0.01% | $0.000015 | 4,289,045.7839 | $63.65 | |
ETH | <0.01% | $0.560379 | 113.4558 | $63.58 | |
ETH | <0.01% | $0.766599 | 82.4265 | $63.19 | |
ETH | <0.01% | $0.174195 | 361.4792 | $62.97 | |
ETH | <0.01% | $0.077609 | 805.6246 | $62.52 | |
ETH | <0.01% | $0.000245 | 255,254.2584 | $62.52 | |
ETH | <0.01% | $0.016159 | 3,859.7276 | $62.37 | |
ETH | <0.01% | $1.9 | 32.3644 | $61.64 | |
ETH | <0.01% | $0.235225 | 261.9947 | $61.63 | |
ETH | <0.01% | $4,401.54 | 0.0139 | $61.01 | |
ETH | <0.01% | $0.001799 | 33,856.1981 | $60.91 | |
ETH | <0.01% | $0.020931 | 2,855.0724 | $59.76 | |
ETH | <0.01% | $0.104899 | 562.462 | $59 | |
ETH | <0.01% | $1.1 | 52.348 | $57.33 | |
ETH | <0.01% | $0.328831 | 174.1964 | $57.28 | |
ETH | <0.01% | $0.238165 | 239.9783 | $57.15 | |
ETH | <0.01% | $0.084159 | 671.7471 | $56.53 | |
ETH | <0.01% | $0.049472 | 1,142.5833 | $56.53 | |
ETH | <0.01% | $0.000589 | 95,937.9205 | $56.49 | |
ETH | <0.01% | $0.083533 | 675.7416 | $56.45 | |
ETH | <0.01% | $0.07508 | 738.2744 | $55.43 | |
ETH | <0.01% | $0.165396 | 335.0814 | $55.42 | |
ETH | <0.01% | $0.019427 | 2,807.8451 | $54.55 | |
ETH | <0.01% | $0.000273 | 199,535.6532 | $54.51 | |
ETH | <0.01% | $0.094184 | 576.2063 | $54.27 | |
ETH | <0.01% | $0.000066 | 818,067.0115 | $54.22 | |
ETH | <0.01% | $0.102351 | 525.037 | $53.74 | |
ETH | <0.01% | <$0.000001 | 118,144,388.4334 | $53.68 | |
ETH | <0.01% | $0.00023 | 233,149.3318 | $53.59 | |
ETH | <0.01% | $0.002375 | 22,473.6354 | $53.38 | |
ETH | <0.01% | $104.63 | 0.5096 | $53.32 | |
ETH | <0.01% | $74.32 | 0.7164 | $53.24 | |
ETH | <0.01% | <$0.000001 | 104,346,425,915.3291 | $52.43 | |
ETH | <0.01% | <$0.000001 | 465,211,223.8057 | $51.74 | |
ETH | <0.01% | $0.000274 | 186,719.5515 | $51.19 | |
ETH | <0.01% | $0.004351 | 11,465.6655 | $49.89 | |
ETH | <0.01% | $0.000001 | 86,221,150.5342 | $49.55 | |
ETH | <0.01% | $0.031418 | 1,570.2848 | $49.33 | |
ETH | <0.01% | $0.297879 | 165.5619 | $49.32 | |
ETH | <0.01% | $0.471359 | 101.5924 | $47.89 | |
ETH | <0.01% | $0.020381 | 2,309.235 | $47.06 | |
ETH | <0.01% | $0.10282 | 452.5715 | $46.53 | |
ETH | <0.01% | $0.101507 | 457.9131 | $46.48 | |
ETH | <0.01% | $0.001943 | 23,799.0046 | $46.24 | |
ETH | <0.01% | $0.47214 | 97.9088 | $46.23 | |
ETH | <0.01% | $1.24 | 37.1412 | $46.06 | |
ETH | <0.01% | $1 | 44.57 | $44.57 | |
ETH | <0.01% | $0.262395 | 169.7917 | $44.55 | |
ETH | <0.01% | $0.257714 | 172.3394 | $44.41 | |
ETH | <0.01% | $1.64 | 27.0655 | $44.39 | |
ETH | <0.01% | $0.524764 | 84.1052 | $44.14 | |
ETH | <0.01% | $5.15 | 8.5683 | $44.13 | |
ETH | <0.01% | $0.000004 | 10,858,291.4595 | $43.43 | |
ETH | <0.01% | $0.002939 | 14,717.8157 | $43.25 | |
ETH | <0.01% | $0.046718 | 919.0807 | $42.94 | |
ETH | <0.01% | $0.000007 | 6,404,199.3224 | $42.93 | |
ETH | <0.01% | $0.000205 | 208,884.8098 | $42.86 | |
ETH | <0.01% | $0.999947 | 42.8556 | $42.85 | |
ETH | <0.01% | $0.015636 | 2,718.2769 | $42.5 | |
ETH | <0.01% | $0.02807 | 1,502.4582 | $42.17 | |
ETH | <0.01% | $0.361369 | 115.3647 | $41.69 | |
ETH | <0.01% | <$0.000001 | 323,445,015.2699 | $41.65 | |
ETH | <0.01% | $4,823.48 | 0.00844547 | $40.74 | |
ETH | <0.01% | $0.454937 | 89.2929 | $40.62 | |
ETH | <0.01% | $12.48 | 3.239 | $40.44 | |
ETH | <0.01% | $0.214444 | 188.024 | $40.32 | |
ETH | <0.01% | $0.056158 | 717.3665 | $40.29 | |
ETH | <0.01% | $0.00063 | 63,455.3734 | $39.99 | |
ETH | <0.01% | $0.000001 | 41,263,454.4678 | $39.58 | |
ETH | <0.01% | $0.000412 | 95,804.006 | $39.44 | |
ETH | <0.01% | $0.005958 | 6,572.0411 | $39.16 | |
ETH | <0.01% | $0.0008 | 48,717.2834 | $38.99 | |
ETH | <0.01% | $0.001249 | 30,945.0571 | $38.64 | |
ETH | <0.01% | $0.278998 | 138.4738 | $38.63 | |
ETH | <0.01% | $0.073488 | 525.3825 | $38.61 | |
ETH | <0.01% | $329.66 | 0.1163 | $38.33 | |
ETH | <0.01% | $0.000931 | 41,003.1585 | $38.17 | |
ETH | <0.01% | <$0.000001 | 100,127,805.3548 | $38.16 | |
ETH | <0.01% | $2.41 | 15.6324 | $37.67 | |
ETH | <0.01% | $0.109523 | 340.5565 | $37.3 | |
ETH | <0.01% | $0.012545 | 2,956.1894 | $37.09 | |
ETH | <0.01% | $0.000003 | 11,580,364.4958 | $36.83 | |
ETH | <0.01% | $1.03 | 35.4768 | $36.66 | |
ETH | <0.01% | $0.000227 | 161,324.1016 | $36.58 | |
ETH | <0.01% | $0.273934 | 133.2412 | $36.5 | |
ETH | <0.01% | $0.268025 | 134.979 | $36.18 | |
ETH | <0.01% | $0.008708 | 4,074.8814 | $35.48 | |
ETH | <0.01% | $0.009439 | 3,753.7804 | $35.43 | |
ETH | <0.01% | $0.592688 | 59.7441 | $35.41 | |
ETH | <0.01% | $2.42 | 14.5883 | $35.3 | |
ETH | <0.01% | $0.000327 | 107,260.0817 | $35.11 | |
ETH | <0.01% | $15.68 | 2.2388 | $35.1 | |
ETH | <0.01% | $0.000297 | 117,999.7679 | $35.02 | |
ETH | <0.01% | $0.365804 | 95.3803 | $34.89 | |
ETH | <0.01% | $0.696705 | 49.3483 | $34.38 | |
ETH | <0.01% | $0.129667 | 263.2196 | $34.13 | |
ETH | <0.01% | $1.2 | 28.3982 | $34.08 | |
ETH | <0.01% | $121,706 | 0.00027699 | $33.71 | |
ETH | <0.01% | $0.049952 | 667.0625 | $33.32 | |
ETH | <0.01% | $0.001076 | 30,623.4978 | $32.95 | |
ETH | <0.01% | $1.19 | 27.6027 | $32.92 | |
ETH | <0.01% | $0.072833 | 447.7447 | $32.61 | |
ETH | <0.01% | $0.015529 | 2,081.1068 | $32.32 | |
ETH | <0.01% | $0.073709 | 435.8633 | $32.13 | |
ETH | <0.01% | $0.001831 | 17,305.1745 | $31.68 | |
ETH | <0.01% | $0.084227 | 375.8949 | $31.66 | |
ETH | <0.01% | $14.53 | 2.176 | $31.62 | |
ETH | <0.01% | $0.000004 | 7,197,321.4351 | $31.31 | |
ETH | <0.01% | $0.012608 | 2,472.7944 | $31.18 | |
ETH | <0.01% | $0.002882 | 10,709.1641 | $30.86 | |
ETH | <0.01% | <$0.000001 | 9,974,222,468.2796 | $30.84 | |
ETH | <0.01% | $0.00283 | 10,858.4957 | $30.73 | |
ETH | <0.01% | $0.997792 | 29.8084 | $29.74 | |
ETH | <0.01% | <$0.000001 | 103,437,835.1491 | $29.7 | |
ETH | <0.01% | $0.268621 | 110.0213 | $29.55 | |
ETH | <0.01% | $0.012246 | 2,413.0187 | $29.55 | |
ETH | <0.01% | $1.79 | 16.4244 | $29.43 | |
ETH | <0.01% | <$0.000001 | 8,959,744,682.8867 | $29.41 | |
ETH | <0.01% | $0.264272 | 110.2902 | $29.15 | |
ETH | <0.01% | $2.21 | 13.1815 | $29.13 | |
ETH | <0.01% | $4.25 | 6.7252 | $28.58 | |
ETH | <0.01% | $1.16 | 24.583 | $28.52 | |
ETH | <0.01% | $1.12 | 25.3527 | $28.4 | |
ETH | <0.01% | $0.049235 | 574.5401 | $28.29 | |
ETH | <0.01% | $0.016025 | 1,730.312 | $27.73 | |
ETH | <0.01% | $0.014112 | 1,964.3009 | $27.72 | |
ETH | <0.01% | $0.236009 | 116.9201 | $27.59 | |
ETH | <0.01% | $0.04084 | 674.176 | $27.53 | |
ETH | <0.01% | $26.88 | 1.0228 | $27.49 | |
ETH | <0.01% | $0.556541 | 48.8335 | $27.18 | |
ETH | <0.01% | $0.996346 | 27.1709 | $27.07 | |
ETH | <0.01% | $0.289636 | 93.0411 | $26.95 | |
ETH | <0.01% | $0.013005 | 2,068.3465 | $26.9 | |
ETH | <0.01% | $1,353.83 | 0.0195 | $26.45 | |
ETH | <0.01% | $0.009733 | 2,717.4836 | $26.45 | |
ETH | <0.01% | $0.012675 | 2,085.8034 | $26.44 | |
ETH | <0.01% | $0.000461 | 57,148.816 | $26.33 | |
ETH | <0.01% | $0.004227 | 6,226.1147 | $26.32 | |
ETH | <0.01% | $0.000847 | 30,911.4014 | $26.2 | |
ETH | <0.01% | $4.7 | 5.5611 | $26.14 | |
ETH | <0.01% | $0.036867 | 708.8919 | $26.13 | |
ETH | <0.01% | $0.136139 | 189.3536 | $25.78 | |
ETH | <0.01% | $0.000251 | 102,059.2396 | $25.65 | |
ETH | <0.01% | $0.019537 | 1,312.8385 | $25.65 | |
ETH | <0.01% | $0.003203 | 7,995.901 | $25.61 | |
ETH | <0.01% | $0.028465 | 897.4068 | $25.54 | |
ETH | <0.01% | $122,056 | 0.00020869 | $25.47 | |
ETH | <0.01% | $2.95 | 8.5998 | $25.37 | |
ETH | <0.01% | $0.42342 | 59.5713 | $25.22 | |
ETH | <0.01% | $0.605865 | 41.4665 | $25.12 | |
ETH | <0.01% | $0.014562 | 1,687.7791 | $24.58 | |
ETH | <0.01% | $0.008708 | 2,808.8381 | $24.46 | |
ETH | <0.01% | $0.188561 | 129.612 | $24.44 | |
ETH | <0.01% | $0.000285 | 84,899.3462 | $24.2 | |
ETH | <0.01% | $0.000009 | 2,685,157.1291 | $24.06 | |
ETH | <0.01% | $0.809261 | 29.444 | $23.83 | |
ETH | <0.01% | $1.2 | 19.8436 | $23.81 | |
ETH | <0.01% | $0.000144 | 164,853.2051 | $23.79 | |
ETH | <0.01% | $0.322791 | 72.2705 | $23.33 | |
ETH | <0.01% | $0.929319 | 24.9184 | $23.16 | |
ETH | <0.01% | $0.000048 | 478,562.4386 | $23.1 | |
ETH | <0.01% | $121,944 | 0.00018837 | $22.97 | |
ETH | <0.01% | $0.003824 | 5,998.908 | $22.94 | |
ETH | <0.01% | <$0.000001 | 54,564,720,478.5546 | $22.61 | |
ETH | <0.01% | $0.004708 | 4,800.199 | $22.6 | |
ETH | <0.01% | $0.173844 | 129.9678 | $22.59 | |
ETH | <0.01% | <$0.000001 | 4,844,883,834.1576 | $22.55 | |
ETH | <0.01% | $0.000226 | 99,608.1581 | $22.51 | |
ETH | <0.01% | $0.02926 | 768.9894 | $22.5 | |
ETH | <0.01% | $0.804504 | 27.8077 | $22.37 | |
ETH | <0.01% | $0.99822 | 21.8998 | $21.86 | |
ETH | <0.01% | $0.648029 | 33.665 | $21.82 | |
ETH | <0.01% | $0.193531 | 112.1989 | $21.71 | |
ETH | <0.01% | $0.000525 | 41,085.4824 | $21.58 | |
ETH | <0.01% | $1.21 | 17.8005 | $21.54 | |
ETH | <0.01% | $0.002306 | 9,337.5039 | $21.53 | |
ETH | <0.01% | $0.345948 | 61.665 | $21.33 | |
ETH | <0.01% | $0.202267 | 104.7464 | $21.19 | |
ETH | <0.01% | $0.000001 | 14,284,217.9595 | $21.14 | |
ETH | <0.01% | <$0.000001 | 93,411,551.6025 | $21.03 | |
ETH | <0.01% | $0.006925 | 3,011.6573 | $20.86 | |
ETH | <0.01% | $0.030086 | 693.1921 | $20.86 | |
ETH | <0.01% | $0.107122 | 194.3914 | $20.82 | |
ETH | <0.01% | $0.000061 | 337,542.9347 | $20.75 | |
ETH | <0.01% | $0.001169 | 17,700.8143 | $20.69 | |
ETH | <0.01% | $0.000001 | 32,666,730.5771 | $20.38 | |
ETH | <0.01% | $0.000007 | 2,976,724.3677 | $20.04 | |
ETH | <0.01% | $220.18 | 0.09 | $19.82 | |
ETH | <0.01% | $0.001296 | 15,175.2515 | $19.67 | |
ETH | <0.01% | $0.021924 | 896.467 | $19.65 | |
ETH | <0.01% | $0.001021 | 19,045.4744 | $19.45 | |
ETH | <0.01% | $0.000187 | 103,503.976 | $19.37 | |
ETH | <0.01% | $0.000152 | 127,083.4817 | $19.36 | |
ETH | <0.01% | $2.73 | 7.0678 | $19.29 | |
ETH | <0.01% | $0.466841 | 41.2618 | $19.26 | |
ETH | <0.01% | $16.21 | 1.1653 | $18.89 | |
ETH | <0.01% | $0.010775 | 1,751.8058 | $18.88 | |
ETH | <0.01% | $0.000007 | 2,651,563.2852 | $18.79 | |
ETH | <0.01% | $0.06071 | 307.6806 | $18.68 | |
ETH | <0.01% | $24.7 | 0.752 | $18.57 | |
ETH | <0.01% | $0.066347 | 278.3744 | $18.47 | |
ETH | <0.01% | $0.000001 | 19,519,630.2079 | $18.31 | |
ETH | <0.01% | $0.00014 | 129,231.4525 | $18.03 | |
ETH | <0.01% | $0.021785 | 822.209 | $17.91 | |
ETH | <0.01% | $5,132.57 | 0.00347659 | $17.84 | |
ETH | <0.01% | $1.14 | 15.5734 | $17.75 | |
ETH | <0.01% | $0.000031 | 568,698.7316 | $17.64 | |
ETH | <0.01% | $0.001123 | 15,704.3872 | $17.64 | |
ETH | <0.01% | $4,887.52 | 0.00358632 | $17.53 | |
ETH | <0.01% | $0.253356 | 69.1702 | $17.52 | |
ETH | <0.01% | $0.017244 | 1,009.9445 | $17.42 | |
ETH | <0.01% | $0.001841 | 9,419.0855 | $17.34 | |
ETH | <0.01% | $0.445172 | 38.7472 | $17.25 | |
ETH | <0.01% | $0.000004 | 4,018,066.381 | $17.24 | |
ETH | <0.01% | $0.037699 | 452.7521 | $17.07 | |
ETH | <0.01% | $0.134341 | 127.0387 | $17.07 | |
ETH | <0.01% | <$0.000001 | 36,751,432,153.0222 | $16.97 | |
ETH | <0.01% | $0.000928 | 18,245.8514 | $16.93 | |
ETH | <0.01% | $0.241397 | 69.6252 | $16.81 | |
ETH | <0.01% | $0.01577 | 1,063.7815 | $16.78 | |
ETH | <0.01% | $2.05 | 8.1097 | $16.62 | |
ETH | <0.01% | $0.000035 | 468,356.2065 | $16.59 | |
ETH | <0.01% | $0.004415 | 3,748.8219 | $16.55 | |
ETH | <0.01% | <$0.000001 | 69,359,883.6223 | $16.55 | |
ETH | <0.01% | $1.77 | 9.341 | $16.53 | |
ETH | <0.01% | $0.000644 | 25,636.7542 | $16.51 | |
ETH | <0.01% | <$0.000001 | 6,613,793,144.987 | $16.3 | |
ETH | <0.01% | $0.020112 | 801.665 | $16.12 | |
ETH | <0.01% | $0.024175 | 666.166 | $16.1 | |
ETH | <0.01% | $0.000384 | 41,014.1672 | $15.74 | |
ETH | <0.01% | $0.0933 | 167.7352 | $15.65 | |
ETH | <0.01% | $0.116312 | 134.3086 | $15.62 | |
ETH | <0.01% | $44.5 | 0.3473 | $15.46 | |
ETH | <0.01% | $0.999537 | 15.4465 | $15.44 | |
ETH | <0.01% | $0.098513 | 156.6204 | $15.43 | |
ETH | <0.01% | $0.000003 | 4,647,662.1366 | $15.29 | |
ETH | <0.01% | $0.356918 | 42.7724 | $15.27 | |
ETH | <0.01% | $0.626841 | 24 | $15.04 | |
ETH | <0.01% | $41.71 | 0.3599 | $15.01 | |
ETH | <0.01% | $0.155385 | 94.7 | $14.71 | |
ETH | <0.01% | $6.32 | 2.3268 | $14.71 | |
ETH | <0.01% | $0.27299 | 53.54 | $14.62 | |
ETH | <0.01% | $0.000001 | 18,013,211.7641 | $14.59 | |
ETH | <0.01% | $0.116509 | 124.637 | $14.52 | |
ETH | <0.01% | $1.17 | 12.378 | $14.48 | |
ETH | <0.01% | $0.000125 | 115,460.6395 | $14.45 | |
ETH | <0.01% | $0.000092 | 156,760.2461 | $14.44 | |
ETH | <0.01% | $0.000467 | 30,881.4862 | $14.42 | |
ETH | <0.01% | $3.53 | 4.063 | $14.35 | |
ETH | <0.01% | $0.0011 | 13,035.164 | $14.34 | |
ETH | <0.01% | $0.009817 | 1,460.0027 | $14.33 | |
ETH | <0.01% | $0.006492 | 2,172.6397 | $14.1 | |
ETH | <0.01% | $0.000001 | 25,298,256.0904 | $14.09 | |
ETH | <0.01% | $1.33 | 10.5472 | $14.03 | |
ETH | <0.01% | <$0.000001 | 32,402,229,468.1957 | $13.97 | |
ETH | <0.01% | $0.021844 | 636.5311 | $13.9 | |
ETH | <0.01% | $0.107804 | 128.9399 | $13.9 | |
ETH | <0.01% | $0.073962 | 187.8403 | $13.89 | |
ETH | <0.01% | $0.021928 | 632.379 | $13.87 | |
ETH | <0.01% | $0.0004 | 34,626.8925 | $13.86 | |
ETH | <0.01% | $1 | 13.8316 | $13.83 | |
ETH | <0.01% | $1.45 | 9.5264 | $13.81 | |
ETH | <0.01% | $0.99909 | 13.8106 | $13.8 | |
ETH | <0.01% | $0.000005 | 2,658,859.1287 | $13.79 | |
ETH | <0.01% | $0.051058 | 269.8863 | $13.78 | |
ETH | <0.01% | $0.090932 | 150.819 | $13.71 | |
ETH | <0.01% | $0.000049 | 278,172.0694 | $13.61 | |
ETH | <0.01% | $1.36 | 9.9459 | $13.53 | |
ETH | <0.01% | $0.04621 | 291.2875 | $13.46 | |
ETH | <0.01% | $0.000175 | 76,715.509 | $13.43 | |
ETH | <0.01% | $0.000303 | 44,252.4676 | $13.42 | |
ETH | <0.01% | $0.000178 | 75,193.9848 | $13.36 | |
ETH | <0.01% | $1 | 13.3026 | $13.32 | |
ETH | <0.01% | $0.00016 | 82,825.3159 | $13.28 | |
ETH | <0.01% | $0.005012 | 2,642.7497 | $13.24 | |
ETH | <0.01% | $0.000169 | 78,231.5417 | $13.22 | |
ETH | <0.01% | $0.002856 | 4,609.5333 | $13.17 | |
ETH | <0.01% | <$0.000001 | 168,510,036.2085 | $13.16 | |
ETH | <0.01% | $0.090904 | 143.9132 | $13.08 | |
ETH | <0.01% | $15.93 | 0.815 | $12.98 | |
ETH | <0.01% | $0.000138 | 93,595.0083 | $12.94 | |
ETH | <0.01% | $0.001408 | 9,151.4978 | $12.89 | |
ETH | <0.01% | $1.23 | 10.4591 | $12.86 | |
ETH | <0.01% | $0.011481 | 1,109.7182 | $12.74 | |
ETH | <0.01% | $0.076964 | 164.6251 | $12.67 | |
ETH | <0.01% | $0.000189 | 66,874.8191 | $12.61 | |
ETH | <0.01% | $0.000003 | 4,889,647.5682 | $12.6 | |
ETH | <0.01% | $42.53 | 0.2942 | $12.51 | |
ETH | <0.01% | $0.715427 | 17.1723 | $12.29 | |
ETH | <0.01% | $0.034971 | 346.7616 | $12.13 | |
ETH | <0.01% | <$0.000001 | 11,630,967,744.9765 | $12.09 | |
ETH | <0.01% | $0.245921 | 48.6551 | $11.97 | |
ETH | <0.01% | $0.000034 | 345,755.1797 | $11.85 | |
ETH | <0.01% | $0.008029 | 1,470.2565 | $11.8 | |
ETH | <0.01% | $0.000039 | 299,030 | $11.74 | |
ETH | <0.01% | $1.08 | 10.8298 | $11.7 | |
ETH | <0.01% | $4,484.1 | 0.00259134 | $11.62 | |
ETH | <0.01% | $0.868782 | 13.307 | $11.56 | |
ETH | <0.01% | $0.014993 | 763.343 | $11.44 | |
ETH | <0.01% | $2.94 | 3.8744 | $11.37 | |
ETH | <0.01% | $0.075638 | 150.3227 | $11.37 | |
ETH | <0.01% | <$0.000001 | 12,911,090,723.7032 | $11.35 | |
ETH | <0.01% | $0.000124 | 91,619.1772 | $11.35 | |
ETH | <0.01% | $0.001041 | 10,807.7802 | $11.26 | |
ETH | <0.01% | $0.005926 | 1,892.4448 | $11.22 | |
ETH | <0.01% | $0.01377 | 812.987 | $11.19 | |
ETH | <0.01% | $0.071972 | 152.6725 | $10.99 | |
ETH | <0.01% | <$0.000001 | 72,318,067.8245 | $10.98 | |
ETH | <0.01% | $0.000302 | 36,343.6899 | $10.96 | |
ETH | <0.01% | $13.66 | 0.8002 | $10.93 | |
ETH | <0.01% | <$0.000001 | 64,247,376,901.593 | $10.65 | |
ETH | <0.01% | $0.362829 | 29.1174 | $10.56 | |
ETH | <0.01% | $0.019124 | 550.1637 | $10.52 | |
ETH | <0.01% | $0.003078 | 3,417.6712 | $10.52 | |
ETH | <0.01% | $0.000023 | 462,054.1203 | $10.51 | |
ETH | <0.01% | $122,828 | 0.0000854 | $10.49 | |
ETH | <0.01% | $0.002096 | 4,997.1223 | $10.47 | |
ETH | <0.01% | $0.070608 | 148.3225 | $10.47 | |
ETH | <0.01% | <$0.000001 | 40,152,821.9999 | $10.41 | |
ETH | <0.01% | $36.9 | 0.2816 | $10.39 | |
ETH | <0.01% | $0.013073 | 794.6503 | $10.39 | |
ETH | <0.01% | $0.000223 | 46,239.149 | $10.32 | |
ETH | <0.01% | $0.116275 | 88.6338 | $10.31 | |
ETH | <0.01% | $0.00174 | 5,827.0328 | $10.14 | |
ETH | <0.01% | $0.000007 | 1,547,584.9057 | $10.14 | |
ETH | <0.01% | $1.03 | 9.7673 | $10.03 | |
ETH | <0.01% | $0.001692 | 5,912.3621 | $10 | |
ETH | <0.01% | <$0.000001 | 2,885,856,899.2073 | $9.98 | |
ETH | <0.01% | $0.903983 | 11 | $9.94 | |
ETH | <0.01% | <$0.000001 | 6,457,767,526.2097 | $9.89 | |
ETH | <0.01% | $0.167702 | 58.9471 | $9.89 | |
ETH | <0.01% | $0.175801 | 56.0334 | $9.85 | |
ETH | <0.01% | $0.000559 | 17,531.9982 | $9.8 | |
ETH | <0.01% | $0.011804 | 829.0724 | $9.79 | |
ETH | <0.01% | $0.000898 | 10,887.3937 | $9.78 | |
ETH | <0.01% | $0.008877 | 1,094.0916 | $9.71 | |
ETH | <0.01% | $0.002589 | 3,719.0954 | $9.63 | |
ETH | <0.01% | $0.017903 | 537.3498 | $9.62 | |
ETH | <0.01% | $0.252693 | 37.6328 | $9.51 | |
ETH | <0.01% | $0.001824 | 5,161.1085 | $9.41 | |
ETH | <0.01% | $0.439967 | 21.3463 | $9.39 | |
ETH | <0.01% | <$0.000001 | 216,542,577.442 | $9.33 | |
ETH | <0.01% | $0.036873 | 252.72 | $9.32 | |
ETH | <0.01% | $0.000065 | 142,172.1474 | $9.31 | |
ETH | <0.01% | $0.088176 | 105.4053 | $9.29 | |
ETH | <0.01% | <$0.000001 | 31,251,114.3486 | $9.26 | |
ETH | <0.01% | $0.313836 | 29.1779 | $9.16 | |
ETH | <0.01% | $0.041788 | 218.72 | $9.14 | |
ETH | <0.01% | $0.000806 | 11,336.3675 | $9.14 | |
ETH | <0.01% | $0.048839 | 186.4509 | $9.11 | |
ETH | <0.01% | $0.33776 | 26.7746 | $9.04 | |
ETH | <0.01% | <$0.000001 | 423,292,491.2453 | $8.99 | |
ETH | <0.01% | <$0.000001 | 58,013,957.164 | $8.94 | |
ETH | <0.01% | $0.449796 | 19.8501 | $8.93 | |
ETH | <0.01% | $0.00 | 1,042.8043 | $0.00 | |
ETH | <0.01% | $0.103329 | 86.1808 | $8.9 | |
ETH | <0.01% | $0.097944 | 90.7058 | $8.88 | |
ETH | <0.01% | $0.021578 | 410.4025 | $8.86 | |
ETH | <0.01% | $0.015327 | 576.2339 | $8.83 | |
ETH | <0.01% | $0.2328 | 37.8603 | $8.81 | |
ETH | <0.01% | $0.031307 | 279.8432 | $8.76 | |
ETH | <0.01% | $0.257202 | 34.0112 | $8.75 | |
ETH | <0.01% | <$0.000001 | 6,214,761,235.9605 | $8.74 | |
ETH | <0.01% | <$0.000001 | 52,752,748,613.2823 | $8.73 | |
ETH | <0.01% | $0.160532 | 53.6324 | $8.61 | |
ETH | <0.01% | <$0.000001 | 175,756,406,190.9561 | $8.61 | |
ETH | <0.01% | <$0.000001 | 89,407,496.9949 | $8.59 | |
ETH | <0.01% | <$0.000001 | 14,248,091,745.9889 | $8.54 | |
ETH | <0.01% | $0.030234 | 281.4427 | $8.51 | |
ETH | <0.01% | $0.001033 | 8,232.4868 | $8.5 | |
ETH | <0.01% | $0.131586 | 64.5505 | $8.49 | |
ETH | <0.01% | $0.00005 | 170,674.341 | $8.49 | |
ETH | <0.01% | $0.040921 | 206.5323 | $8.45 | |
ETH | <0.01% | $0.000766 | 11,024.4842 | $8.44 | |
ETH | <0.01% | $0.002152 | 3,909.5149 | $8.42 | |
ETH | <0.01% | $0.135318 | 62.1046 | $8.4 | |
ETH | <0.01% | $1.27 | 6.5939 | $8.37 | |
ETH | <0.01% | $0.000075 | 111,869.9418 | $8.35 | |
ETH | <0.01% | <$0.000001 | 101,341,478.0649 | $8.31 | |
ETH | <0.01% | $0.00 | 2,027.0599 | $0.00 | |
ETH | <0.01% | $0.00004 | 205,128.2773 | $8.25 | |
ETH | <0.01% | $0.000946 | 8,722.3204 | $8.25 | |
ETH | <0.01% | $0.000015 | 564,604.7014 | $8.23 | |
ETH | <0.01% | $0.025507 | 320 | $8.16 | |
ETH | <0.01% | $0.349486 | 23.3468 | $8.16 | |
ETH | <0.01% | $0.001503 | 5,364.8878 | $8.06 | |
ETH | <0.01% | $0.068153 | 118.1339 | $8.05 | |
ETH | <0.01% | <$0.000001 | 64,024,475,254.1376 | $8.01 | |
ETH | <0.01% | $0.024342 | 328.0634 | $7.99 | |
ETH | <0.01% | $0.000016 | 505,325.9215 | $7.98 | |
ETH | <0.01% | $0.99818 | 7.9875 | $7.97 | |
ETH | <0.01% | $0.071162 | 112.0134 | $7.97 | |
ETH | <0.01% | $1.55 | 5.1417 | $7.97 | |
ETH | <0.01% | $0.000002 | 3,932,244.3799 | $7.9 | |
ETH | <0.01% | $0.000125 | 62,994.1353 | $7.9 | |
ETH | <0.01% | $5,404.01 | 0.00145698 | $7.87 | |
ETH | <0.01% | $0.003462 | 2,262.2823 | $7.83 | |
ETH | <0.01% | $2.45 | 3.1652 | $7.75 | |
ETH | <0.01% | $0.12526 | 61.889 | $7.75 | |
ETH | <0.01% | $0.208823 | 36.9851 | $7.72 | |
ETH | <0.01% | $2.15 | 3.568 | $7.67 | |
ETH | <0.01% | $0.01398 | 543.7159 | $7.6 | |
ETH | <0.01% | $0.218595 | 34.6354 | $7.57 | |
ETH | <0.01% | $0.00 | 101.3067 | $0.00 | |
ETH | <0.01% | $0.00328 | 2,282.0577 | $7.49 | |
ETH | <0.01% | $0.000187 | 39,936.8772 | $7.47 | |
ETH | <0.01% | $0.021277 | 350.4373 | $7.46 | |
ETH | <0.01% | $0.131298 | 56.6578 | $7.44 | |
ETH | <0.01% | $0.062251 | 119.2048 | $7.42 | |
ETH | <0.01% | $0.53535 | 13.8032 | $7.39 | |
ETH | <0.01% | $0.000076 | 96,661.7794 | $7.38 | |
ETH | <0.01% | $0.012406 | 594.9174 | $7.38 | |
ETH | <0.01% | $0.500479 | 14.5854 | $7.3 | |
ETH | <0.01% | $0.003011 | 2,422.4542 | $7.3 | |
ETH | <0.01% | $0.000004 | 1,805,049.9719 | $7.27 | |
ETH | <0.01% | $173.65 | 0.0414 | $7.19 | |
ETH | <0.01% | $0.020895 | 344.2992 | $7.19 | |
ETH | <0.01% | $0.442825 | 16.1971 | $7.17 | |
ETH | <0.01% | $0.000001 | 5,427,460.8832 | $7.16 | |
ETH | <0.01% | $0.2363 | 30.2367 | $7.14 | |
ETH | <0.01% | $0.080103 | 89.1194 | $7.14 | |
ETH | <0.01% | <$0.000001 | 39,380,730,241.9614 | $7.06 | |
ETH | <0.01% | $0.110573 | 63.784 | $7.05 | |
ETH | <0.01% | $0.00014 | 50,093.335 | $7.03 | |
ETH | <0.01% | $0.000001 | 5,265,286.2214 | $6.95 | |
ETH | <0.01% | $0.000296 | 23,236.408 | $6.87 | |
ETH | <0.01% | $0.000182 | 37,718.5036 | $6.85 | |
ETH | <0.01% | $0.008851 | 767.9254 | $6.8 | |
ETH | <0.01% | $0.00063 | 10,622.8782 | $6.7 | |
ETH | <0.01% | $0.04411 | 151.5433 | $6.68 | |
ETH | <0.01% | $0.000604 | 11,057.1784 | $6.68 | |
ETH | <0.01% | $0.061382 | 108.7363 | $6.67 | |
ETH | <0.01% | $0.000104 | 63,646.5044 | $6.61 | |
ETH | <0.01% | $0.067947 | 96.6529 | $6.57 | |
ETH | <0.01% | $0.000292 | 22,475.7661 | $6.55 | |
ETH | <0.01% | $0.743408 | 8.8021 | $6.54 | |
ETH | <0.01% | $0.008981 | 722.0863 | $6.48 | |
ETH | <0.01% | $0.000001 | 8,968,815.6131 | $6.43 | |
ETH | <0.01% | $0.002393 | 2,686.6301 | $6.43 | |
ETH | <0.01% | <$0.000001 | 35,694,179.2177 | $6.42 | |
ETH | <0.01% | $0.379098 | 16.8305 | $6.38 | |
ETH | <0.01% | <$0.000001 | 32,098,237,496.8639 | $6.36 | |
ETH | <0.01% | $0.291042 | 21.8194 | $6.35 | |
ETH | <0.01% | $0.45909 | 13.8301 | $6.35 | |
ETH | <0.01% | $0.054631 | 116.0329 | $6.34 | |
ETH | <0.01% | $0.00022 | 28,775.0178 | $6.33 | |
ETH | <0.01% | <$0.000001 | 95,138,062,645.7019 | $6.32 | |
ETH | <0.01% | <$0.000001 | 1,321,116,749.4319 | $6.22 | |
ETH | <0.01% | $0.000029 | 216,501.8903 | $6.2 | |
ETH | <0.01% | $0.399226 | 15.2482 | $6.09 | |
ETH | <0.01% | $0.477834 | 12.7281 | $6.08 | |
ETH | <0.01% | $0.023677 | 256.0733 | $6.06 | |
ETH | <0.01% | $10.13 | 0.5959 | $6.04 | |
ETH | <0.01% | $1.75 | 3.4479 | $6.03 | |
ETH | <0.01% | $0.446801 | 13.466 | $6.02 | |
ETH | <0.01% | $0.000051 | 117,736.7232 | $5.98 | |
ETH | <0.01% | $0.077977 | 76.536 | $5.97 | |
ETH | <0.01% | $0.003607 | 1,647.6869 | $5.94 | |
ETH | <0.01% | $0.001326 | 4,473.5768 | $5.93 | |
ETH | <0.01% | $0.019055 | 311.2763 | $5.93 | |
ETH | <0.01% | $0.404255 | 14.6583 | $5.93 | |
ETH | <0.01% | $8.88 | 0.6657 | $5.91 | |
ETH | <0.01% | <$0.000001 | 1,082,617,677.5928 | $5.88 | |
ETH | <0.01% | $0.000735 | 8,000 | $5.88 | |
ETH | <0.01% | $0.998005 | 5.8693 | $5.86 | |
ETH | <0.01% | $4,729.03 | 0.00122518 | $5.79 | |
ETH | <0.01% | $0.046068 | 124.6592 | $5.74 | |
ETH | <0.01% | $0.005272 | 1,080.1373 | $5.69 | |
ETH | <0.01% | $0.000112 | 50,592.3216 | $5.67 | |
ETH | <0.01% | <$0.000001 | 45,511,803,185.7311 | $5.67 | |
ETH | <0.01% | $0.004714 | 1,199.3472 | $5.65 | |
ETH | <0.01% | $0.001644 | 3,434.3679 | $5.64 | |
ETH | <0.01% | $0.009751 | 578.3597 | $5.64 | |
ETH | <0.01% | $12.86 | 0.4373 | $5.62 | |
ETH | <0.01% | $0.29536 | 19.0055 | $5.61 | |
ETH | <0.01% | $1.05 | 5.2837 | $5.54 | |
ETH | <0.01% | $0.002034 | 2,710.2148 | $5.51 | |
ETH | <0.01% | $5.61 | 0.98 | $5.5 | |
ETH | <0.01% | $0.00338 | 1,625.6449 | $5.5 | |
ETH | <0.01% | $0.176518 | 31.1122 | $5.49 | |
ETH | <0.01% | $0.511025 | 10.687 | $5.46 | |
ETH | <0.01% | $0.000145 | 37,298.9016 | $5.42 | |
ETH | <0.01% | <$0.000001 | 2,049,816,027.4393 | $5.42 | |
ETH | <0.01% | $0.00 | 29.6609 | $0.00 | |
ETH | <0.01% | $0.000543 | 9,901.4982 | $5.38 | |
ETH | <0.01% | $0.012522 | 426.0735 | $5.34 | |
ETH | <0.01% | $1.75 | 3.0464 | $5.32 | |
ETH | <0.01% | $123.88 | 0.0429 | $5.32 | |
ETH | <0.01% | $0.000002 | 3,189,449.2621 | $5.26 | |
ETH | <0.01% | $0.000097 | 53,983.2872 | $5.25 | |
ETH | <0.01% | $0.000001 | 4,634,455.7114 | $5.24 | |
ETH | <0.01% | <$0.000001 | 3,929,514,005.1779 | $5.21 | |
ETH | <0.01% | $0.069857 | 74.5496 | $5.21 | |
ETH | <0.01% | $2.65 | 1.9652 | $5.21 | |
ETH | <0.01% | $0.963722 | 5.3916 | $5.2 | |
ETH | <0.01% | $0.648146 | 7.9299 | $5.14 | |
ETH | <0.01% | $0.008423 | 607.8993 | $5.12 | |
ETH | <0.01% | $0.000014 | 374,350.5292 | $5.08 | |
ETH | <0.01% | $0.000131 | 38,413.0913 | $5.03 | |
ETH | <0.01% | $0.20949 | 23.8318 | $4.99 | |
ETH | <0.01% | <$0.000001 | 990,555,001.6484 | $4.89 | |
ETH | <0.01% | $0.003864 | 1,252.3009 | $4.84 | |
ETH | <0.01% | $0.00 | 0.1997 | $0.00 | |
ETH | <0.01% | $0.001314 | 3,660.8 | $4.81 | |
ETH | <0.01% | $1,302.71 | 0.00368929 | $4.81 | |
ETH | <0.01% | $0.000397 | 12,010.6267 | $4.77 | |
ETH | <0.01% | $1 | 4.764 | $4.77 | |
ETH | <0.01% | $0.0035 | 1,360 | $4.76 | |
ETH | <0.01% | $0.166788 | 28.5269 | $4.76 | |
ETH | <0.01% | $0.002971 | 1,594.8038 | $4.74 | |
ETH | <0.01% | $0.000025 | 188,665.7471 | $4.67 | |
ETH | <0.01% | $0.028474 | 163.1685 | $4.65 | |
ETH | <0.01% | $0.058047 | 79.999 | $4.64 | |
ETH | <0.01% | <$0.000001 | 8,197,770,324.5407 | $4.58 | |
ETH | <0.01% | $0.832313 | 5.4867 | $4.57 | |
ETH | <0.01% | $0.330175 | 13.7189 | $4.53 | |
ETH | <0.01% | $0.000182 | 24,783.3909 | $4.51 | |
ETH | <0.01% | $0.010224 | 440.0103 | $4.5 | |
ETH | <0.01% | $0.993433 | 4.4652 | $4.44 | |
ETH | <0.01% | $16.14 | 0.2737 | $4.42 | |
ETH | <0.01% | $0.000004 | 1,089,539.6823 | $4.3 | |
ETH | <0.01% | $0.018269 | 234.5924 | $4.29 | |
ETH | <0.01% | $0.008406 | 507.9767 | $4.27 | |
ETH | <0.01% | $4,721.78 | 0.000902 | $4.26 | |
ETH | <0.01% | $149.41 | 0.0284 | $4.25 | |
ETH | <0.01% | $122,122 | 0.00003476 | $4.24 | |
ETH | <0.01% | $0.120178 | 35.2511 | $4.24 | |
ETH | <0.01% | $0.009355 | 452.6971 | $4.23 | |
ETH | <0.01% | $0.093995 | 44.959 | $4.23 | |
ETH | <0.01% | $0.028117 | 149.8432 | $4.21 | |
ETH | <0.01% | $0.000001 | 5,540,681.7103 | $4.19 | |
ETH | <0.01% | $0.652681 | 6.4113 | $4.18 | |
ETH | <0.01% | $5,986.13 | 0.00069137 | $4.14 | |
ETH | <0.01% | $0.006492 | 637.1901 | $4.14 | |
ETH | <0.01% | $0.010676 | 385.4292 | $4.11 | |
ETH | <0.01% | $0.006327 | 649.8446 | $4.11 | |
ETH | <0.01% | $0.11994 | 34.0383 | $4.08 | |
ETH | <0.01% | $0.001833 | 2,223.3876 | $4.08 | |
ETH | <0.01% | $2.38 | 1.6982 | $4.04 | |
ETH | <0.01% | $0.277897 | 14.5282 | $4.04 | |
ETH | <0.01% | $0.114264 | 35.2399 | $4.03 | |
ETH | <0.01% | $0.025121 | 159.0838 | $4 | |
ETH | <0.01% | <$0.000001 | 54,989,690.9922 | $3.94 | |
ETH | <0.01% | $0.001229 | 3,190.816 | $3.92 | |
ETH | <0.01% | $0.004025 | 971.5358 | $3.91 | |
ETH | <0.01% | $0.034959 | 111.4932 | $3.9 | |
ETH | <0.01% | $1.01 | 3.8539 | $3.88 | |
ETH | <0.01% | $5.61 | 0.6845 | $3.84 | |
ETH | <0.01% | $0.047836 | 79.9996 | $3.83 | |
ETH | <0.01% | $0.012185 | 313.702 | $3.82 | |
ETH | <0.01% | $0.000063 | 60,027.4113 | $3.81 | |
ETH | <0.01% | $0.732281 | 5.1888 | $3.8 | |
ETH | <0.01% | $0.000343 | 11,053.8668 | $3.79 | |
ETH | <0.01% | $4,841.11 | 0.00078221 | $3.79 | |
ETH | <0.01% | $0.405079 | 9.3161 | $3.77 | |
ETH | <0.01% | $11.66 | 0.32 | $3.73 | |
ETH | <0.01% | $0.013327 | 277.6989 | $3.7 | |
ETH | <0.01% | $0.000116 | 31,900.7508 | $3.7 | |
ETH | <0.01% | $0.000072 | 50,823.8474 | $3.67 | |
ETH | <0.01% | $0.00097 | 3,764.2543 | $3.65 | |
ETH | <0.01% | $0.00249 | 1,461.3793 | $3.64 | |
ETH | <0.01% | $0.076113 | 47.6472 | $3.63 | |
ETH | <0.01% | $0.000601 | 5,982.9897 | $3.6 | |
ETH | <0.01% | $0.000098 | 36,791.822 | $3.59 | |
ETH | <0.01% | <$0.000001 | 372,552,531.9928 | $3.58 | |
ETH | <0.01% | $360.65 | 0.00981566 | $3.54 | |
ETH | <0.01% | $0.020348 | 170.6369 | $3.47 | |
ETH | <0.01% | $0.007218 | 479.3457 | $3.46 | |
ETH | <0.01% | <$0.000001 | 1,102,034,377.387 | $3.45 | |
ETH | <0.01% | $0.999702 | 3.4242 | $3.42 | |
ETH | <0.01% | $0.000067 | 51,291.0597 | $3.42 | |
ETH | <0.01% | $336.15 | 0.0101 | $3.41 | |
ETH | <0.01% | $0.152717 | 22.1121 | $3.38 | |
ETH | <0.01% | $0.001648 | 2,037.5291 | $3.36 | |
ETH | <0.01% | $0.218063 | 15.3905 | $3.36 | |
ETH | <0.01% | $0.000626 | 5,353.7836 | $3.35 | |
ETH | <0.01% | $0.024597 | 135.6358 | $3.34 | |
ETH | <0.01% | $0.000004 | 808,654.3517 | $3.33 | |
ETH | <0.01% | $0.027059 | 123.0126 | $3.33 | |
ETH | <0.01% | $0.024458 | 136 | $3.33 | |
ETH | <0.01% | $0.000223 | 14,773.4033 | $3.29 | |
ETH | <0.01% | $0.00545 | 603.3497 | $3.29 | |
ETH | <0.01% | $0.003887 | 845.0385 | $3.29 | |
ETH | <0.01% | $0.002612 | 1,244.3099 | $3.25 | |
ETH | <0.01% | <$0.000001 | 72,959,096.654 | $3.22 | |
ETH | <0.01% | $0.000004 | 890,647.2845 | $3.2 | |
ETH | <0.01% | $0.007506 | 423.516 | $3.18 | |
ETH | <0.01% | $0.111504 | 28.5017 | $3.18 | |
ETH | <0.01% | $0.001432 | 2,189.3508 | $3.13 | |
ETH | <0.01% | $0.016574 | 189.1304 | $3.13 | |
ETH | <0.01% | $0.000532 | 5,895.7767 | $3.13 | |
ETH | <0.01% | $0.000093 | 33,579.7036 | $3.12 | |
ETH | <0.01% | $0.082367 | 37.7994 | $3.11 | |
ETH | <0.01% | $0.072507 | 42.771 | $3.1 | |
ETH | <0.01% | $0.001256 | 2,462.1214 | $3.09 | |
ETH | <0.01% | $0.024438 | 125.4636 | $3.07 | |
ETH | <0.01% | $0.888057 | 3.4294 | $3.05 | |
ETH | <0.01% | $0.001779 | 1,698.2801 | $3.02 | |
ETH | <0.01% | $1.96 | 1.5391 | $3.02 | |
ETH | <0.01% | <$0.000001 | 103,723,962,445,036,820 | $3.01 | |
ETH | <0.01% | $0.475431 | 6.3139 | $3 | |
ETH | <0.01% | <$0.000001 | 12,398,048.9671 | $3 | |
ETH | <0.01% | $0.092969 | 32.2548 | $3 | |
ETH | <0.01% | $5,355.3 | 0.00055636 | $2.98 | |
ETH | <0.01% | $0.023808 | 124.679 | $2.97 | |
ETH | <0.01% | $0.008338 | 355.4058 | $2.96 | |
ETH | <0.01% | $0.000008 | 369,424.9227 | $2.9 | |
ETH | <0.01% | $0.00118 | 2,453.9111 | $2.9 | |
ETH | <0.01% | $0.101572 | 28.3772 | $2.88 | |
ETH | <0.01% | $0.017621 | 163.2617 | $2.88 | |
ETH | <0.01% | $0.010474 | 273.7741 | $2.87 | |
ETH | <0.01% | $0.632263 | 4.5293 | $2.86 | |
ETH | <0.01% | $0.008681 | 329.3509 | $2.86 | |
ETH | <0.01% | $0.000014 | 208,028.239 | $2.85 | |
ETH | <0.01% | <$0.000001 | 443,882,641.6033 | $2.83 | |
ETH | <0.01% | <$0.000001 | 121,308,669,475.7298 | $2.83 | |
ETH | <0.01% | $0.020649 | 136.1219 | $2.81 | |
ETH | <0.01% | $0.237673 | 11.7777 | $2.8 | |
ETH | <0.01% | $0.024097 | 116.1543 | $2.8 | |
ETH | <0.01% | $0.000047 | 59,681.9574 | $2.79 | |
ETH | <0.01% | $0.004428 | 629.9087 | $2.79 | |
ETH | <0.01% | <$0.000001 | 9,182,225.1988 | $2.78 | |
ETH | <0.01% | $0.078173 | 35.4209 | $2.77 | |
ETH | <0.01% | $0.242494 | 11.4047 | $2.77 | |
ETH | <0.01% | $0.189165 | 14.6057 | $2.76 | |
ETH | <0.01% | $0.651471 | 4.2256 | $2.75 | |
ETH | <0.01% | $0.014333 | 191.4667 | $2.74 | |
ETH | <0.01% | $0.025358 | 107.8471 | $2.73 | |
ETH | <0.01% | $0.138878 | 19.6827 | $2.73 | |
ETH | <0.01% | $0.222607 | 12.1726 | $2.71 | |
ETH | <0.01% | $0.000115 | 23,475.2524 | $2.71 | |
ETH | <0.01% | $0.000001 | 2,937,147.335 | $2.7 | |
ETH | <0.01% | $0.041525 | 64.8764 | $2.69 | |
ETH | <0.01% | $0.101441 | 26.3967 | $2.68 | |
ETH | <0.01% | <$0.000001 | 326,203,180.0583 | $2.67 | |
ETH | <0.01% | $0.000002 | 1,326,569.2556 | $2.65 | |
ETH | <0.01% | $0.000009 | 279,543.0891 | $2.65 | |
ETH | <0.01% | <$0.000001 | 1,600,000,000,000 | $2.62 | |
ETH | <0.01% | <$0.000001 | 8,357,428.652 | $2.61 | |
ETH | <0.01% | $1.08 | 2.4184 | $2.6 | |
ETH | <0.01% | $0.193442 | 13.464 | $2.6 | |
ETH | <0.01% | $0.03032 | 85.517 | $2.59 | |
ETH | <0.01% | $0.021687 | 118.4044 | $2.57 | |
ETH | <0.01% | $0.020583 | 124.1725 | $2.56 | |
ETH | <0.01% | $0.030176 | 84.5663 | $2.55 | |
ETH | <0.01% | $0.000023 | 109,615.4 | $2.55 | |
ETH | <0.01% | $0.000867 | 2,938.3407 | $2.55 | |
ETH | <0.01% | $0.071449 | 35.6033 | $2.54 | |
ETH | <0.01% | $0.113291 | 22.2218 | $2.52 | |
ETH | <0.01% | $0.007113 | 353.3563 | $2.51 | |
ETH | <0.01% | $0.000104 | 23,874.7072 | $2.49 | |
ETH | <0.01% | $0.002325 | 1,070.4064 | $2.49 | |
ETH | <0.01% | <$0.000001 | 5,519,155.8489 | $2.46 | |
ETH | <0.01% | $0.00008 | 30,533.5378 | $2.44 | |
ETH | <0.01% | $0.006971 | 348.1677 | $2.43 | |
ETH | <0.01% | $0.305546 | 7.9338 | $2.42 | |
ETH | <0.01% | $0.00603 | 400.3158 | $2.41 | |
ETH | <0.01% | $0.832792 | 2.86 | $2.38 | |
ETH | <0.01% | $0.76563 | 3.1034 | $2.38 | |
ETH | <0.01% | $0.958182 | 2.4736 | $2.37 | |
ETH | <0.01% | $0.010906 | 216.92 | $2.37 | |
ETH | <0.01% | <$0.000001 | 2,000,000,000 | $2.35 | |
ETH | <0.01% | $0.003229 | 728.6893 | $2.35 | |
ETH | <0.01% | $0.001941 | 1,209.5374 | $2.35 | |
ETH | <0.01% | $0.000186 | 12,611.4785 | $2.34 | |
ETH | <0.01% | $0.002716 | 862.7498 | $2.34 | |
ETH | <0.01% | $4,835.06 | 0.0004821 | $2.33 | |
ETH | <0.01% | $0.012948 | 178.9372 | $2.32 | |
ETH | <0.01% | $0.018603 | 124.4372 | $2.31 | |
ETH | <0.01% | $0.000006 | 357,592.2122 | $2.31 | |
ETH | <0.01% | $4.95 | 0.4656 | $2.3 | |
ETH | <0.01% | $0.00001 | 236,964.3737 | $2.3 | |
ETH | <0.01% | <$0.000001 | 770,456,068.0223 | $2.3 | |
ETH | <0.01% | $0.054736 | 41.9965 | $2.3 | |
ETH | <0.01% | $0.03101 | 73.7647 | $2.29 | |
ETH | <0.01% | <$0.000001 | 5,254,493.132 | $2.28 | |
ETH | <0.01% | $0.000001 | 3,247,259.1112 | $2.28 | |
ETH | <0.01% | <$0.000001 | 4,132,265,402.5514 | $2.28 | |
ETH | <0.01% | $0.065103 | 34.9891 | $2.28 | |
ETH | <0.01% | $0.247836 | 9.1151 | $2.26 | |
ETH | <0.01% | $0.039386 | 57.3142 | $2.26 | |
ETH | <0.01% | $0.624876 | 3.5915 | $2.24 | |
ETH | <0.01% | $0.00 | 1,041.659 | $0.00 | |
ETH | <0.01% | $0.560787 | 3.9801 | $2.23 | |
ETH | <0.01% | $0.011516 | 193.6172 | $2.23 | |
ETH | <0.01% | $0.000016 | 143,752.9133 | $2.23 | |
ETH | <0.01% | $0.000016 | 143,636.0543 | $2.23 | |
ETH | <0.01% | $0.351965 | 6.3255 | $2.23 | |
ETH | <0.01% | $0.000125 | 17,725.5859 | $2.22 | |
ETH | <0.01% | $0.006414 | 343.2027 | $2.2 | |
ETH | <0.01% | $0.000225 | 9,773.9372 | $2.2 | |
ETH | <0.01% | $0.000539 | 4,071.5117 | $2.19 | |
ETH | <0.01% | $0.157578 | 13.8938 | $2.19 | |
ETH | <0.01% | $0.015368 | 142.4235 | $2.19 | |
ETH | <0.01% | <$0.000001 | 177,097,043.787 | $2.18 | |
ETH | <0.01% | $0.027138 | 80 | $2.17 | |
ETH | <0.01% | $0.049792 | 43.5393 | $2.17 | |
ETH | <0.01% | $0.000014 | 156,429.1238 | $2.16 | |
ETH | <0.01% | $0.000482 | 4,476.3424 | $2.16 | |
ETH | <0.01% | $0.001755 | 1,225.5352 | $2.15 | |
ETH | <0.01% | $0.026602 | 80.49 | $2.14 | |
ETH | <0.01% | $1.35 | 1.5783 | $2.13 | |
ETH | <0.01% | $0.001273 | 1,676.5185 | $2.13 | |
ETH | <0.01% | $1.76 | 1.2078 | $2.13 | |
ETH | <0.01% | $0.000003 | 609,551 | $2.13 | |
ETH | <0.01% | <$0.000001 | 9,501,060.6232 | $2.11 | |
ETH | <0.01% | $0.078993 | 26.7115 | $2.11 | |
ETH | <0.01% | $0.004123 | 508.8161 | $2.1 | |
ETH | <0.01% | $0.007385 | 283.1244 | $2.09 | |
ETH | <0.01% | <$0.000001 | 1,550,886,506.2599 | $2.08 | |
ETH | <0.01% | $0.016612 | 125.4484 | $2.08 | |
ETH | <0.01% | $0.010667 | 190.4061 | $2.03 | |
ETH | <0.01% | $0.003488 | 578.5767 | $2.02 | |
ETH | <0.01% | $0.000173 | 11,598.4753 | $2.01 | |
ETH | <0.01% | $0.056939 | 35.2353 | $2.01 | |
ETH | <0.01% | $7.71 | 0.26 | $2 | |
ETH | <0.01% | $0.02985 | 66.9405 | $2 | |
ETH | <0.01% | $0.00001 | 208,797.9526 | $2 | |
ETH | <0.01% | $0.000135 | 14,734.2853 | $2 | |
ETH | <0.01% | $0.002483 | 800 | $1.99 | |
ETH | <0.01% | $0.00007 | 28,456.0086 | $1.98 | |
ETH | <0.01% | $0.000038 | 51,036.5778 | $1.96 | |
ETH | <0.01% | $0.073959 | 26.4902 | $1.96 | |
ETH | <0.01% | $0.000174 | 11,135.9095 | $1.94 | |
ETH | <0.01% | $0.000473 | 4,088.8879 | $1.93 | |
ETH | <0.01% | $0.001006 | 1,921.4487 | $1.93 | |
ETH | <0.01% | $0.096552 | 20 | $1.93 | |
ETH | <0.01% | $0.02013 | 95.7318 | $1.93 | |
ETH | <0.01% | $0.525188 | 3.6649 | $1.92 | |
ETH | <0.01% | <$0.000001 | 3,964,946.364 | $1.91 | |
ETH | <0.01% | $0.000032 | 60,025.817 | $1.91 | |
ETH | <0.01% | $0.35448 | 5.3824 | $1.91 | |
ETH | <0.01% | $0.008546 | 222.6941 | $1.9 | |
ETH | <0.01% | $0.046011 | 41.3107 | $1.9 | |
ETH | <0.01% | $0.031027 | 60.9667 | $1.89 | |
ETH | <0.01% | $0.001504 | 1,252.432 | $1.88 | |
ETH | <0.01% | $0.000228 | 8,167.2677 | $1.86 | |
ETH | <0.01% | <$0.000001 | 22,799,583.9986 | $1.86 | |
ETH | <0.01% | $0.300025 | 6.1878 | $1.86 | |
ETH | <0.01% | $0.000053 | 35,319.833 | $1.85 | |
ETH | <0.01% | $0.023597 | 78.2088 | $1.85 | |
ETH | <0.01% | <$0.000001 | 2,302,881,054.2065 | $1.84 | |
ETH | <0.01% | $0.00364 | 504.6429 | $1.84 | |
ETH | <0.01% | <$0.000001 | 3,917,982.8131 | $1.84 | |
ETH | <0.01% | $0.000171 | 10,673.8949 | $1.83 | |
ETH | <0.01% | $0.000005 | 377,797.2269 | $1.83 | |
ETH | <0.01% | $0.038173 | 47.7143 | $1.82 | |
ETH | <0.01% | <$0.000001 | 501,367,494.71 | $1.82 | |
ETH | <0.01% | $0.774296 | 2.3489 | $1.82 | |
ETH | <0.01% | $4,456.81 | 0.00040801 | $1.82 | |
ETH | <0.01% | $0.000378 | 4,800 | $1.81 | |
ETH | <0.01% | $0.00134 | 1,347.817 | $1.81 | |
ETH | <0.01% | $0.005009 | 359.4531 | $1.8 | |
ETH | <0.01% | $0.003834 | 469.069 | $1.8 | |
ETH | <0.01% | $0.999393 | 1.7811 | $1.78 | |
ETH | <0.01% | $0.000074 | 24,000 | $1.78 | |
ETH | <0.01% | $0.032714 | 54.2856 | $1.78 | |
ETH | <0.01% | $0.626022 | 2.8278 | $1.77 | |
ETH | <0.01% | <$0.000001 | 20,025,712.2448 | $1.77 | |
ETH | <0.01% | $0.000062 | 28,567.1563 | $1.77 | |
ETH | <0.01% | $0.128799 | 13.6953 | $1.76 | |
ETH | <0.01% | $0.000065 | 27,128.7975 | $1.75 | |
ETH | <0.01% | $0.295434 | 5.8911 | $1.74 | |
ETH | <0.01% | $0.156362 | 11.1 | $1.74 | |
ETH | <0.01% | $0.000772 | 2,240.4515 | $1.73 | |
ETH | <0.01% | $0.013463 | 127.6748 | $1.72 | |
ETH | <0.01% | $0.066904 | 25.3649 | $1.7 | |
ETH | <0.01% | $0.485866 | 3.4474 | $1.67 | |
ETH | <0.01% | $0.003553 | 471.2069 | $1.67 | |
ETH | <0.01% | $0.00068 | 2,459.3024 | $1.67 | |
ETH | <0.01% | <$0.000001 | 21,362,535.5115 | $1.67 | |
ETH | <0.01% | $151.22 | 0.011 | $1.67 | |
ETH | <0.01% | $0.003491 | 474.2549 | $1.66 | |
ETH | <0.01% | $0.046561 | 35.0247 | $1.63 | |
ETH | <0.01% | $0.995409 | 1.627 | $1.62 | |
ETH | <0.01% | $0.000005 | 338,943.2988 | $1.62 | |
ETH | <0.01% | $0.016925 | 95.5407 | $1.62 | |
ETH | <0.01% | $0.033581 | 48 | $1.61 | |
ETH | <0.01% | <$0.000001 | 12,563,694.6353 | $1.6 | |
ETH | <0.01% | $0.000047 | 33,344.3041 | $1.58 | |
ETH | <0.01% | $0.003022 | 522.1688 | $1.58 | |
ETH | <0.01% | $0.000023 | 69,266.3711 | $1.58 | |
ETH | <0.01% | <$0.000001 | 253,878,925.7271 | $1.58 | |
ETH | <0.01% | $28.39 | 0.0553 | $1.57 | |
ETH | <0.01% | $0.114648 | 13.6551 | $1.57 | |
ETH | <0.01% | $0.030692 | 50.9358 | $1.56 | |
ETH | <0.01% | $0.000412 | 3,792.1073 | $1.56 | |
ETH | <0.01% | $0.003646 | 426.3427 | $1.55 | |
ETH | <0.01% | $0.030265 | 50.8746 | $1.54 | |
ETH | <0.01% | $0.060901 | 24.9694 | $1.52 | |
ETH | <0.01% | $155.24 | 0.0097941 | $1.52 | |
ETH | <0.01% | $0.000249 | 6,094.3731 | $1.52 | |
ETH | <0.01% | $0.0077 | 197.1289 | $1.52 | |
ETH | <0.01% | $0.000031 | 49,177.2206 | $1.52 | |
ETH | <0.01% | $0.085279 | 17.6734 | $1.51 | |
ETH | <0.01% | $0.000347 | 4,344.1248 | $1.51 | |
ETH | <0.01% | $0.429987 | 3.4918 | $1.5 | |
ETH | <0.01% | $11.3 | 0.1319 | $1.49 | |
ETH | <0.01% | $0.041677 | 35.3567 | $1.47 | |
ETH | <0.01% | $0.000005 | 306,152.2271 | $1.47 | |
ETH | <0.01% | $0.000011 | 138,876.7042 | $1.47 | |
ETH | <0.01% | $0.000002 | 773,962.635 | $1.46 | |
ETH | <0.01% | $1 | 1.4634 | $1.46 | |
ETH | <0.01% | $0.008334 | 175.6306 | $1.46 | |
ETH | <0.01% | $0.99986 | 1.4615 | $1.46 | |
ETH | <0.01% | $0.001798 | 810.7563 | $1.46 | |
ETH | <0.01% | $0.054885 | 26.5025 | $1.45 | |
ETH | <0.01% | $0.000298 | 4,873.0464 | $1.45 | |
ETH | <0.01% | $0.000309 | 4,701.3124 | $1.45 | |
ETH | <0.01% | $0.000771 | 1,866.568 | $1.44 | |
ETH | <0.01% | <$0.000001 | 11,358,630 | $1.43 | |
ETH | <0.01% | $0.00194 | 734.1238 | $1.42 | |
ETH | <0.01% | $0.13775 | 10.2575 | $1.41 | |
ETH | <0.01% | $0.122308 | 11.5488 | $1.41 | |
ETH | <0.01% | <$0.000001 | 9,245,907.9957 | $1.41 | |
ETH | <0.01% | $0.00001 | 145,893.3605 | $1.4 | |
ETH | <0.01% | $0.000228 | 6,110.341 | $1.39 | |
ETH | <0.01% | $0.005937 | 232.1419 | $1.38 | |
ETH | <0.01% | $0.000224 | 6,123.2865 | $1.37 | |
ETH | <0.01% | $0.000021 | 65,534.6927 | $1.36 | |
ETH | <0.01% | $0.013085 | 103.1623 | $1.35 | |
ETH | <0.01% | $0.000087 | 15,425.4842 | $1.35 | |
ETH | <0.01% | $0.029883 | 45.1507 | $1.35 | |
ETH | <0.01% | <$0.000001 | 3,763,904,771.3303 | $1.34 | |
ETH | <0.01% | $0.000093 | 14,363.4664 | $1.33 | |
ETH | <0.01% | $0.000056 | 23,709.2876 | $1.33 | |
ETH | <0.01% | $0.000287 | 4,606.4944 | $1.32 | |
ETH | <0.01% | $0.000096 | 13,748.8512 | $1.32 | |
ETH | <0.01% | $0.004867 | 264.7145 | $1.29 | |
ETH | <0.01% | $0.008317 | 153.9706 | $1.28 | |
ETH | <0.01% | $0.005369 | 237.8475 | $1.28 | |
ETH | <0.01% | $0.00004 | 31,662.1669 | $1.27 | |
ETH | <0.01% | $0.000749 | 1,694.3324 | $1.27 | |
ETH | <0.01% | $0.013537 | 93.4256 | $1.26 | |
ETH | <0.01% | $0.146696 | 8.6144 | $1.26 | |
ETH | <0.01% | $0.021126 | 59.704 | $1.26 | |
ETH | <0.01% | $0.000548 | 2,276.2814 | $1.25 | |
ETH | <0.01% | $0.02487 | 50.0795 | $1.25 | |
ETH | <0.01% | $0.000104 | 11,970.3645 | $1.24 | |
ETH | <0.01% | $0.000414 | 2,993.5301 | $1.24 | |
ETH | <0.01% | $0.989503 | 1.2526 | $1.24 | |
ETH | <0.01% | <$0.000001 | 1,930,380,577.3791 | $1.24 | |
ETH | <0.01% | $0.005276 | 234.2624 | $1.24 | |
ETH | <0.01% | $0.003521 | 348.348 | $1.23 | |
ETH | <0.01% | $0.340558 | 3.6 | $1.23 | |
ETH | <0.01% | $0.000462 | 2,650.5218 | $1.22 | |
ETH | <0.01% | $1.45 | 0.8396 | $1.22 | |
ETH | <0.01% | $0.000041 | 29,273.3706 | $1.21 | |
ETH | <0.01% | $0.000785 | 1,541.4515 | $1.21 | |
ETH | <0.01% | $0.045648 | 26.0375 | $1.19 | |
ETH | <0.01% | $0.152695 | 7.7651 | $1.19 | |
ETH | <0.01% | $0.00436 | 271.5645 | $1.18 | |
ETH | <0.01% | <$0.000001 | 123,654,708.3863 | $1.17 | |
ETH | <0.01% | $0.021305 | 54.8392 | $1.17 | |
ETH | <0.01% | $0.000084 | 13,846.6993 | $1.17 | |
ETH | <0.01% | $0.00011 | 10,600.9609 | $1.17 | |
ETH | <0.01% | $0.001136 | 1,024.0171 | $1.16 | |
ETH | <0.01% | $0.000123 | 9,467.4035 | $1.16 | |
ETH | <0.01% | $118,989 | 0.00000975 | $1.16 | |
ETH | <0.01% | $0.062263 | 18.6267 | $1.16 | |
ETH | <0.01% | $0.000233 | 4,968.493 | $1.16 | |
ETH | <0.01% | $0.000924 | 1,247.486 | $1.15 | |
ETH | <0.01% | $1.09 | 1.0518 | $1.15 | |
ETH | <0.01% | $0.097031 | 11.8084 | $1.15 | |
ETH | <0.01% | $0.00417 | 274.528 | $1.14 | |
ETH | <0.01% | $0.005438 | 207.9353 | $1.13 | |
ETH | <0.01% | $0.014101 | 80 | $1.13 | |
ETH | <0.01% | $0.001808 | 622.8511 | $1.13 | |
ETH | <0.01% | $0.004951 | 227.3458 | $1.13 | |
ETH | <0.01% | $0.002325 | 483.727 | $1.12 | |
ETH | <0.01% | $0.008611 | 129.8974 | $1.12 | |
ETH | <0.01% | $2.51 | 0.4441 | $1.12 | |
ETH | <0.01% | $0.011673 | 95.4335 | $1.11 | |
ETH | <0.01% | <$0.000001 | 3,679,456.5505 | $1.11 | |
ETH | <0.01% | $0.029748 | 37.413 | $1.11 | |
ETH | <0.01% | $0.002085 | 532.8102 | $1.11 | |
ETH | <0.01% | $0.001565 | 708.9171 | $1.11 | |
ETH | <0.01% | $0.993935 | 1.1152 | $1.11 | |
ETH | <0.01% | <$0.000001 | 1,624,183,347.2816 | $1.1 | |
ETH | <0.01% | $1 | 1.1 | $1.1 | |
ETH | <0.01% | $0.010102 | 108.7697 | $1.1 | |
ETH | <0.01% | <$0.000001 | 6,184,874.5348 | $1.1 | |
ETH | <0.01% | $0.872142 | 1.2576 | $1.1 | |
ETH | <0.01% | $0.08513 | 12.8647 | $1.1 | |
ETH | <0.01% | $0.999736 | 1.0869 | $1.09 | |
ETH | <0.01% | $0.040672 | 26.5617 | $1.08 | |
ETH | <0.01% | <$0.000001 | 16,055,256.6795 | $1.07 | |
ETH | <0.01% | <$0.000001 | 1,136,350,626.8237 | $1.06 | |
ETH | <0.01% | $4,842.82 | 0.00021802 | $1.06 | |
ETH | <0.01% | $0.006726 | 156.3018 | $1.05 | |
ETH | <0.01% | $4,333.87 | 0.00024239 | $1.05 | |
ETH | <0.01% | $0.00044 | 2,337.6841 | $1.03 | |
ETH | <0.01% | $0.001321 | 778.898 | $1.03 | |
ETH | <0.01% | $0.004752 | 215.8808 | $1.03 | |
ETH | <0.01% | $0.000004 | 276,255.7147 | $1.02 | |
ETH | <0.01% | <$0.000001 | 1,088,974,868.0595 | $1.02 | |
ETH | <0.01% | $4,733.64 | 0.00021301 | $1.01 | |
ETH | <0.01% | <$0.000001 | 470,455,157.7013 | $1.01 | |
ETH | <0.01% | $0.070926 | 14.1785 | $1.01 | |
ETH | <0.01% | $0.010352 | 97.132 | $1.01 | |
ETH | <0.01% | $0.039744 | 25.2707 | $1 | |
ETH | <0.01% | $62.08 | 0.0162 | $1 | |
ETH | <0.01% | $0.000018 | 54,929.884 | $1 | |
ETH | <0.01% | $0.295746 | 3.3731 | $0.9975 | |
ETH | <0.01% | $0.000697 | 1,428.8617 | $0.9954 | |
ETH | <0.01% | $0.070188 | 14.1693 | $0.9945 | |
ETH | <0.01% | $0.028079 | 35.3422 | $0.9923 | |
ETH | <0.01% | $0.043003 | 23.0739 | $0.9922 | |
ETH | <0.01% | $0.000022 | 45,925.896 | $0.9919 | |
ETH | <0.01% | $0.007572 | 130.8079 | $0.9904 | |
ETH | <0.01% | $0.002465 | 401.5989 | $0.9898 | |
ETH | <0.01% | $0.000155 | 6,365.8099 | $0.9886 | |
ETH | <0.01% | $0.124528 | 7.9146 | $0.9855 | |
ETH | <0.01% | $0.016956 | 57.944 | $0.9824 | |
ETH | <0.01% | <$0.000001 | 64,241,223.6295 | $0.9817 | |
ETH | <0.01% | $0.00347 | 282.0059 | $0.9785 | |
ETH | <0.01% | $0.185843 | 5.2513 | $0.9759 | |
ETH | <0.01% | $0.000316 | 3,085.7777 | $0.9755 | |
ETH | <0.01% | $0.010916 | 89.024 | $0.9717 | |
ETH | <0.01% | $0.011862 | 81.136 | $0.9624 | |
ETH | <0.01% | $0.052398 | 18.3191 | $0.9598 | |
ETH | <0.01% | <$0.000001 | 599,848,693.3584 | $0.9555 | |
ETH | <0.01% | $0.027699 | 34.4696 | $0.9547 | |
ETH | <0.01% | $0.005858 | 161.4324 | $0.9456 | |
ETH | <0.01% | $0.000075 | 12,562.4612 | $0.9432 | |
ETH | <0.01% | <$0.000001 | 18,990,562.8225 | $0.9424 | |
ETH | <0.01% | $12,714.17 | 0.00007411 | $0.9422 | |
ETH | <0.01% | <$0.000001 | 110,093,121,285.577 | $0.9414 | |
ETH | <0.01% | $0.001996 | 469.1795 | $0.9366 | |
ETH | <0.01% | $0.000192 | 4,865.5068 | $0.9362 | |
ETH | <0.01% | <$0.000001 | 2,231,706.7525 | $0.935 | |
ETH | <0.01% | $0.007423 | 125.646 | $0.9327 | |
ETH | <0.01% | $0.055969 | 16.6307 | $0.9308 | |
ETH | <0.01% | $0.000109 | 8,401.4222 | $0.9182 | |
ETH | <0.01% | $0.000221 | 4,130.3865 | $0.9147 | |
ETH | <0.01% | $0.000642 | 1,422.7576 | $0.9135 | |
ETH | <0.01% | $0.06906 | 13.0155 | $0.8988 | |
ETH | <0.01% | <$0.000001 | 3,343,731.4015 | $0.8966 | |
ETH | <0.01% | <$0.000001 | 9,626,774.4214 | $0.8948 | |
ETH | <0.01% | $0.00004 | 22,413.2513 | $0.894 | |
ETH | <0.01% | $0.238339 | 3.7486 | $0.8934 | |
ETH | <0.01% | $0.011505 | 77.5897 | $0.8926 | |
ETH | <0.01% | $0.000337 | 2,651.1701 | $0.8922 | |
ETH | <0.01% | $0.003795 | 233.8511 | $0.8873 | |
ETH | <0.01% | $0.003384 | 261.0815 | $0.8834 | |
ETH | <0.01% | $0.018229 | 48.3889 | $0.882 | |
ETH | <0.01% | <$0.000001 | 1,362,800,164.5263 | $0.8763 | |
ETH | <0.01% | $0.000435 | 2,000 | $0.8707 | |
ETH | <0.01% | $0.126145 | 6.871 | $0.8667 | |
ETH | <0.01% | $0.046352 | 18.6688 | $0.8653 | |
ETH | <0.01% | <$0.000001 | 1,849,336.3673 | $0.8642 | |
ETH | <0.01% | $0.00015 | 5,751.6168 | $0.8617 | |
ETH | <0.01% | $0.000514 | 1,658.7804 | $0.853 | |
ETH | <0.01% | $0.000005 | 169,120.5515 | $0.8523 | |
ETH | <0.01% | $0.004898 | 173.635 | $0.8504 | |
ETH | <0.01% | $0.000992 | 855.536 | $0.8488 | |
ETH | <0.01% | <$0.000001 | 139,505,142,725.5098 | $0.8478 | |
ETH | <0.01% | $0.999635 | 0.8475 | $0.8471 | |
ETH | <0.01% | $0.000749 | 1,124.7475 | $0.8429 | |
ETH | <0.01% | $0.003993 | 210.5037 | $0.8405 | |
ETH | <0.01% | <$0.000001 | 15,289,267,657.4725 | $0.8392 | |
ETH | <0.01% | $0.000001 | 823,427.8149 | $0.8383 | |
ETH | <0.01% | <$0.000001 | 9,413,046.1335 | $0.8342 | |
ETH | <0.01% | $0.000343 | 2,423.749 | $0.8309 | |
ETH | <0.01% | $0.214696 | 3.8372 | $0.8238 | |
ETH | <0.01% | $0.000171 | 4,800 | $0.8217 | |
ETH | <0.01% | $0.001198 | 682.3148 | $0.8171 | |
ETH | <0.01% | $0.001146 | 711.76 | $0.8158 | |
ETH | <0.01% | $0.00062 | 1,310.6535 | $0.8121 | |
ETH | <0.01% | $0.006103 | 132.1114 | $0.8062 | |
ETH | <0.01% | $0.003536 | 223.8725 | $0.7916 | |
ETH | <0.01% | $0.407061 | 1.925 | $0.7835 | |
ETH | <0.01% | $0.283864 | 2.7546 | $0.7819 | |
ETH | <0.01% | $0.001843 | 423.4957 | $0.7807 | |
ETH | <0.01% | $0.000153 | 5,055.2107 | $0.7756 | |
ETH | <0.01% | $0.011069 | 69.6298 | $0.7707 | |
ETH | <0.01% | <$0.000001 | 2,876,618.4328 | $0.7699 | |
ETH | <0.01% | $0.054311 | 14.1199 | $0.7668 | |
ETH | <0.01% | $0.000055 | 13,874.616 | $0.7639 | |
ETH | <0.01% | $0.000002 | 492,588.7596 | $0.7565 | |
ETH | <0.01% | $0.009419 | 80.3045 | $0.7563 | |
ETH | <0.01% | $0.005395 | 140 | $0.7552 | |
ETH | <0.01% | $0.007544 | 99.7428 | $0.7524 | |
ETH | <0.01% | $0.014659 | 51.2869 | $0.7518 | |
ETH | <0.01% | $0.142519 | 5.2686 | $0.7508 | |
ETH | <0.01% | $0.030363 | 24.6453 | $0.7483 | |
ETH | <0.01% | $0.046997 | 15.92 | $0.7481 | |
ETH | <0.01% | $0.626259 | 1.1924 | $0.7467 | |
ETH | <0.01% | $0.003109 | 239.9584 | $0.7459 | |
ETH | <0.01% | $0.027866 | 26.688 | $0.7436 | |
ETH | <0.01% | $0.013698 | 54.1363 | $0.7415 | |
ETH | <0.01% | $0.067638 | 10.9571 | $0.7411 | |
ETH | <0.01% | $0.007792 | 95.079 | $0.7408 | |
ETH | <0.01% | $59.56 | 0.0124 | $0.7371 | |
ETH | <0.01% | $0.000783 | 940.3353 | $0.7361 | |
ETH | <0.01% | $0.025636 | 28.6571 | $0.7346 | |
ETH | <0.01% | $1 | 0.7279 | $0.7307 | |
ETH | <0.01% | $0.003741 | 195.296 | $0.7305 | |
ETH | <0.01% | $0.002136 | 341.8128 | $0.7299 | |
ETH | <0.01% | $0.000006 | 124,996.1143 | $0.7203 | |
ETH | <0.01% | $0.007585 | 94.1601 | $0.7141 | |
ETH | <0.01% | $0.00005 | 14,413.338 | $0.7136 | |
ETH | <0.01% | $0.005658 | 125.0791 | $0.7077 | |
ETH | <0.01% | $0.00075 | 936.6063 | $0.7028 | |
ETH | <0.01% | $0.172107 | 4.0794 | $0.702 | |
ETH | <0.01% | $0.16958 | 4.1274 | $0.6999 | |
ETH | <0.01% | $0.042848 | 16.312 | $0.6989 | |
ETH | <0.01% | $0.004614 | 150.1419 | $0.6928 | |
ETH | <0.01% | $1.12 | 0.617 | $0.6917 | |
ETH | <0.01% | $0.000001 | 1,249,960.5935 | $0.6906 | |
ETH | <0.01% | $0.005457 | 126.1711 | $0.6884 | |
ETH | <0.01% | $0.000045 | 15,187.2357 | $0.686 | |
ETH | <0.01% | $0.000066 | 10,413.9112 | $0.6853 | |
ETH | <0.01% | $0.000001 | 627,988.9516 | $0.6845 | |
ETH | <0.01% | $0.017033 | 40.1673 | $0.6841 | |
ETH | <0.01% | $0.001333 | 512.3604 | $0.6831 | |
ETH | <0.01% | $0.649723 | 1.0503 | $0.6824 | |
ETH | <0.01% | $2.81 | 0.2412 | $0.6777 | |
ETH | <0.01% | <$0.000001 | 10,553,256,057.8677 | $0.6775 | |
ETH | <0.01% | $0.063968 | 10.5596 | $0.6754 | |
ETH | <0.01% | <$0.000001 | 780,596,975.5249 | $0.6737 | |
ETH | <0.01% | $0.003804 | 176.97 | $0.6731 | |
ETH | <0.01% | $0.000002 | 365,556.6006 | $0.6726 | |
ETH | <0.01% | $0.052165 | 12.8718 | $0.6714 | |
ETH | <0.01% | $0.000243 | 2,758.5921 | $0.6704 | |
ETH | <0.01% | <$0.000001 | 44,327,487,252.16 | $0.6683 | |
ETH | <0.01% | $1.48 | 0.4497 | $0.6655 | |
ETH | <0.01% | $0.000397 | 1,673.0185 | $0.6648 | |
ETH | <0.01% | $0.000158 | 4,204.7537 | $0.6628 | |
ETH | <0.01% | $0.002595 | 253.9186 | $0.659 | |
ETH | <0.01% | $0.001168 | 563.6732 | $0.6585 | |
ETH | <0.01% | $0.127754 | 5.1354 | $0.656 | |
ETH | <0.01% | $0.000001 | 836,180.6086 | $0.6544 | |
ETH | <0.01% | $0.000262 | 2,489.7677 | $0.6532 | |
ETH | <0.01% | $0.017078 | 38.1978 | $0.6523 | |
ETH | <0.01% | $0.000574 | 1,128 | $0.647 | |
ETH | <0.01% | <$0.000001 | 207,086,519.6749 | $0.6442 | |
ETH | <0.01% | $0.030361 | 21.2034 | $0.6437 | |
ETH | <0.01% | $1 | 0.64 | $0.64 | |
ETH | <0.01% | $0.052169 | 12.2054 | $0.6367 | |
ETH | <0.01% | $0.000322 | 1,972.858 | $0.6355 | |
ETH | <0.01% | $0.000293 | 2,159.2607 | $0.6335 | |
ETH | <0.01% | <$0.000001 | 6,411,625.6986 | $0.6329 | |
ETH | <0.01% | $0.3488 | 1.8003 | $0.6279 | |
ETH | <0.01% | $0.00009 | 6,987.8587 | $0.6263 | |
ETH | <0.01% | $0.000033 | 18,865.6706 | $0.6221 | |
ETH | <0.01% | <$0.000001 | 78,257,648.4337 | $0.6182 | |
ETH | <0.01% | $0.000717 | 859.3308 | $0.6161 | |
ETH | <0.01% | $0.000018 | 33,632.5704 | $0.6151 | |
ETH | <0.01% | $0.000671 | 915.0557 | $0.6143 | |
ETH | <0.01% | <$0.000001 | 952,326,617.9297 | $0.6134 | |
ETH | <0.01% | $0.624876 | 0.9803 | $0.6125 | |
ETH | <0.01% | $0.002229 | 273.9974 | $0.6107 | |
ETH | <0.01% | <$0.000001 | 1,583,362,628.3309 | $0.6092 | |
ETH | <0.01% | $0.000032 | 18,935.6341 | $0.6087 | |
ETH | <0.01% | $0.00039 | 1,544.0089 | $0.6025 | |
ETH | <0.01% | $73.69 | 0.008119 | $0.5983 | |
ETH | <0.01% | $0.000001 | 804,624.9171 | $0.5945 | |
ETH | <0.01% | $0.000004 | 158,646.703 | $0.5869 | |
ETH | <0.01% | $0.00188 | 312 | $0.5866 | |
ETH | <0.01% | $121,058 | 0.00000483 | $0.5847 | |
ETH | <0.01% | $0.012228 | 47.5294 | $0.5811 | |
ETH | <0.01% | $0.000068 | 8,506.2078 | $0.5802 | |
ETH | <0.01% | $0.000064 | 9,001.7756 | $0.5788 | |
ETH | <0.01% | $0.000166 | 3,489.4891 | $0.5783 | |
ETH | <0.01% | $0.999881 | 0.5767 | $0.5766 | |
ETH | <0.01% | <$0.000001 | 207,047,985.5906 | $0.5754 | |
ETH | <0.01% | $0.000143 | 4,000 | $0.5722 | |
ETH | <0.01% | $8.89 | 0.0643 | $0.5714 | |
ETH | <0.01% | <$0.000001 | 28,674,664,719.5558 | $0.5698 | |
ETH | <0.01% | $23.49 | 0.0241 | $0.5655 | |
ETH | <0.01% | $0.00 | 127 | $0.00 | |
ETH | <0.01% | $0.000123 | 4,589.798 | $0.5625 | |
ETH | <0.01% | $0.010572 | 53.12 | $0.5616 | |
ETH | <0.01% | <$0.000001 | 2,297,881.8012 | $0.5608 | |
ETH | <0.01% | <$0.000001 | 2,783,549.7939 | $0.5595 | |
ETH | <0.01% | $0.001385 | 403.721 | $0.559 | |
ETH | <0.01% | $0.000219 | 2,543.626 | $0.5565 | |
ETH | <0.01% | $0.084714 | 6.562 | $0.5558 | |
ETH | <0.01% | $1.16 | 0.4778 | $0.5542 | |
ETH | <0.01% | $0.000137 | 4,041.5413 | $0.5538 | |
ETH | <0.01% | $0.770629 | 0.7177 | $0.5531 | |
ETH | <0.01% | $0.004668 | 117.8934 | $0.5503 | |
ETH | <0.01% | $0.002196 | 248.6165 | $0.546 | |
ETH | <0.01% | $0.011463 | 47.5102 | $0.5446 | |
ETH | <0.01% | <$0.000001 | 10,500,111.5461 | $0.5433 | |
ETH | <0.01% | $0.147976 | 3.6645 | $0.5422 | |
ETH | <0.01% | $0.000603 | 892.6373 | $0.5385 | |
ETH | <0.01% | $0.000673 | 800 | $0.538 | |
ETH | <0.01% | <$0.000001 | 2,481,013.8365 | $0.5368 | |
ETH | <0.01% | $0.005367 | 99.4803 | $0.5339 | |
ETH | <0.01% | <$0.000001 | 3,745,794.1424 | $0.5337 | |
ETH | <0.01% | $0.000256 | 2,063.6229 | $0.5288 | |
ETH | <0.01% | $3.99 | 0.1317 | $0.5253 | |
ETH | <0.01% | <$0.000001 | 907,075,435.3844 | $0.5218 | |
ETH | <0.01% | $0.000025 | 21,211.3159 | $0.5209 | |
ETH | <0.01% | <$0.000001 | 1,757,951,604,603,893.3 | $0.5185 | |
ETH | <0.01% | $0.113716 | 4.5576 | $0.5182 | |
ETH | <0.01% | $0.00013 | 3,973.4859 | $0.5168 | |
ETH | <0.01% | <$0.000001 | 4,113,826.0301 | $0.5161 | |
ETH | <0.01% | $0.000778 | 661.9841 | $0.5149 | |
ETH | <0.01% | $0.006701 | 75.7707 | $0.5077 | |
ETH | <0.01% | $9.41 | 0.0536 | $0.5045 | |
ETH | <0.01% | $0.000013 | 40,272.1748 | $0.5042 | |
ETH | <0.01% | $0.000067 | 7,540.6783 | $0.5036 | |
ETH | <0.01% | $0.001287 | 391.1561 | $0.5034 | |
ETH | <0.01% | $0.000271 | 1,842.5731 | $0.499 | |
ETH | <0.01% | <$0.000001 | 9,570,920.8898 | $0.4972 | |
ETH | <0.01% | $8.9 | 0.0549 | $0.4888 | |
ETH | <0.01% | $0.0475 | 10.1944 | $0.4842 | |
ETH | <0.01% | $0.006527 | 74.1429 | $0.4839 | |
ETH | <0.01% | <$0.000001 | 1,602,448.8376 | $0.4824 | |
ETH | <0.01% | $0.010867 | 43.9327 | $0.4774 | |
ETH | <0.01% | $0.05928 | 8 | $0.4742 | |
ETH | <0.01% | $0.000516 | 910.5614 | $0.4696 | |
ETH | <0.01% | $1.03 | 0.4546 | $0.4691 | |
ETH | <0.01% | $0.00023 | 2,021.5049 | $0.4646 | |
ETH | <0.01% | $0.006081 | 76.2525 | $0.4637 | |
ETH | <0.01% | <$0.000001 | 2,443,288,153.8614 | $0.4601 | |
ETH | <0.01% | $0.004059 | 113.2779 | $0.4598 | |
ETH | <0.01% | <$0.000001 | 2,323,403.0923 | $0.4582 | |
ETH | <0.01% | $0.000097 | 4,653.3116 | $0.4491 | |
ETH | <0.01% | $1.12 | 0.4006 | $0.4491 | |
ETH | <0.01% | $0.021215 | 20.9524 | $0.4444 | |
ETH | <0.01% | $0.001958 | 225.7957 | $0.4421 | |
ETH | <0.01% | $0.026982 | 16.3719 | $0.4417 | |
ETH | <0.01% | $0.014109 | 31.2788 | $0.4413 | |
ETH | <0.01% | $0.000201 | 2,186.4338 | $0.4392 | |
ETH | <0.01% | $0.173312 | 2.5233 | $0.4373 | |
ETH | <0.01% | $0.000003 | 165,155.2547 | $0.4364 | |
ETH | <0.01% | $0.020085 | 21.4893 | $0.4316 | |
ETH | <0.01% | $0.069848 | 6.1742 | $0.4312 | |
ETH | <0.01% | $0.093274 | 4.5927 | $0.4283 | |
ETH | <0.01% | <$0.000001 | 740,539,002.5225 | $0.427 | |
ETH | <0.01% | $0.000677 | 631.1291 | $0.4269 | |
ETH | <0.01% | $0.000353 | 1,200 | $0.424 | |
ETH | <0.01% | $0.000607 | 696.3172 | $0.4223 | |
ETH | <0.01% | $0.000048 | 8,737.9137 | $0.4218 | |
ETH | <0.01% | $0.007128 | 59.127 | $0.4214 | |
ETH | <0.01% | $0.048422 | 8.6835 | $0.4204 | |
ETH | <0.01% | $0.000056 | 7,513.1547 | $0.4194 | |
ETH | <0.01% | $0.035009 | 11.8655 | $0.4153 | |
ETH | <0.01% | $0.000025 | 16,767.8391 | $0.415 | |
ETH | <0.01% | $0.002552 | 161.3614 | $0.4118 | |
ETH | <0.01% | $0.000045 | 9,079.8734 | $0.4105 | |
ETH | <0.01% | $0.000067 | 6,089.5289 | $0.4086 | |
ETH | <0.01% | $0.001939 | 210.738 | $0.4086 | |
ETH | <0.01% | $0.007824 | 52.1133 | $0.4077 | |
ETH | <0.01% | $0.00266 | 152.7496 | $0.4063 | |
ETH | <0.01% | $0.007587 | 53.1641 | $0.4033 | |
ETH | <0.01% | $0.001903 | 211.6403 | $0.4028 | |
ETH | <0.01% | $0.085532 | 4.6918 | $0.4012 | |
ETH | <0.01% | $0.880756 | 0.4552 | $0.4008 | |
ETH | <0.01% | $1 | 0.3996 | $0.4004 | |
ETH | <0.01% | $0.000001 | 372,022 | $0.398 | |
ETH | <0.01% | $0.054384 | 7.3033 | $0.3971 | |
ETH | <0.01% | $0.00 | 3.7332 | $0.00 | |
ETH | <0.01% | $0.000243 | 1,630.4493 | $0.3957 | |
ETH | <0.01% | $0.000281 | 1,404.288 | $0.3951 | |
ETH | <0.01% | $0.003001 | 131.6033 | $0.3949 | |
ETH | <0.01% | $0.000078 | 5,078.9146 | $0.3948 | |
ETH | <0.01% | <$0.000001 | 3,563,915.8523 | $0.3917 | |
ETH | <0.01% | $0.037808 | 10.3383 | $0.3908 | |
ETH | <0.01% | $0.016943 | 22.9409 | $0.3886 | |
ETH | <0.01% | <$0.000001 | 502,592,772.3203 | $0.3885 | |
ETH | <0.01% | $1.03 | 0.3781 | $0.3883 | |
ETH | <0.01% | $0.001055 | 364.3606 | $0.3843 | |
ETH | <0.01% | <$0.000001 | 1,512,108,418.8975 | $0.3819 | |
ETH | <0.01% | $0.000144 | 2,651.37 | $0.3811 | |
ETH | <0.01% | <$0.000001 | 6,499,256.368 | $0.3798 | |
ETH | <0.01% | $0.056839 | 6.6451 | $0.3777 | |
ETH | <0.01% | $4.4 | 0.0851 | $0.3745 | |
ETH | <0.01% | $0.00046 | 813.2848 | $0.3741 | |
ETH | <0.01% | $0.013211 | 28.1598 | $0.372 | |
ETH | <0.01% | $0.001941 | 190.8813 | $0.3705 | |
ETH | <0.01% | $0.000809 | 457.8116 | $0.3701 | |
ETH | <0.01% | $0.060565 | 6.112 | $0.3701 | |
ETH | <0.01% | $0.000462 | 800 | $0.3699 | |
ETH | <0.01% | $2.18 | 0.1692 | $0.3691 | |
ETH | <0.01% | $1.02 | 0.3636 | $0.369 | |
ETH | <0.01% | $17.11 | 0.0215 | $0.368 | |
ETH | <0.01% | $0.000007 | 55,515.8414 | $0.3675 | |
ETH | <0.01% | <$0.000001 | 275,731,639.4585 | $0.3653 | |
ETH | <0.01% | $0.318764 | 1.1408 | $0.3636 | |
ETH | <0.01% | $0.010667 | 34.0537 | $0.3632 | |
ETH | <0.01% | $0.035846 | 10.1233 | $0.3628 | |
ETH | <0.01% | $0.006303 | 57.5362 | $0.3626 | |
ETH | <0.01% | $0.000013 | 27,937.2401 | $0.3623 | |
ETH | <0.01% | $0.000013 | 28,162.455 | $0.3618 | |
ETH | <0.01% | <$0.000001 | 286,866,639.2072 | $0.361 | |
ETH | <0.01% | $0.000294 | 1,225.4594 | $0.3606 | |
ETH | <0.01% | $10.42 | 0.0346 | $0.3602 | |
ETH | <0.01% | $0.000179 | 2,008.7522 | $0.3592 | |
ETH | <0.01% | $0.000066 | 5,441.6 | $0.3581 | |
ETH | <0.01% | $0.015201 | 23.5272 | $0.3576 | |
ETH | <0.01% | <$0.000001 | 1,715,696.2736 | $0.3563 | |
ETH | <0.01% | $0.000108 | 3,300.2683 | $0.3556 | |
ETH | <0.01% | <$0.000001 | 8,904,272.3199 | $0.3555 | |
ETH | <0.01% | $0.665445 | 0.534 | $0.3553 | |
ETH | <0.01% | $0.000144 | 2,451.2932 | $0.3528 | |
ETH | <0.01% | $0.000346 | 1,014.2903 | $0.351 | |
ETH | <0.01% | $0.048876 | 7.179 | $0.3508 | |
ETH | <0.01% | <$0.000001 | 890,062.3216 | $0.3466 | |
ETH | <0.01% | $10,360.9 | 0.00003337 | $0.3457 | |
ETH | <0.01% | $0.000004 | 79,680.3287 | $0.3436 | |
ETH | <0.01% | $0.071294 | 4.7989 | $0.3421 | |
ETH | <0.01% | <$0.000001 | 4,789,059,091.1246 | $0.34 | |
ETH | <0.01% | $0.999736 | 0.34 | $0.3399 | |
ETH | <0.01% | $0.019009 | 17.844 | $0.3392 | |
ETH | <0.01% | $0.006169 | 54.9758 | $0.3391 | |
ETH | <0.01% | $0.000003 | 124,229.3913 | $0.3381 | |
ETH | <0.01% | $0.004754 | 70.6215 | $0.3357 | |
ETH | <0.01% | $0.50197 | 0.667 | $0.3347 | |
ETH | <0.01% | $0.000166 | 2,000 | $0.3322 | |
ETH | <0.01% | $0.004841 | 68.5685 | $0.3319 | |
ETH | <0.01% | $5.03 | 0.0659 | $0.3316 | |
ETH | <0.01% | $57,671.17 | 0.00000572 | $0.3301 | |
ETH | <0.01% | $1.41 | 0.2337 | $0.3295 | |
ETH | <0.01% | $0.000463 | 708.9195 | $0.3284 | |
ETH | <0.01% | $0.309852 | 1.0472 | $0.3244 | |
ETH | <0.01% | $0.004422 | 73.1269 | $0.3233 | |
ETH | <0.01% | <$0.000001 | 5,966,503.3402 | $0.3227 | |
ETH | <0.01% | $0.002248 | 142.4622 | $0.3202 | |
ETH | <0.01% | $1 | 0.32 | $0.3201 | |
ETH | <0.01% | $0.016474 | 19.3595 | $0.3189 | |
ETH | <0.01% | $0.225922 | 1.4088 | $0.3182 | |
ETH | <0.01% | $0.005782 | 54.8685 | $0.3172 | |
ETH | <0.01% | <$0.000001 | 15,973,855.7781 | $0.3168 | |
ETH | <0.01% | $0.002334 | 135.546 | $0.3163 | |
ETH | <0.01% | $0.018074 | 17.3463 | $0.3135 | |
ETH | <0.01% | $0.000602 | 519.0256 | $0.3122 | |
ETH | <0.01% | $0.150059 | 2.0743 | $0.3112 | |
ETH | <0.01% | $0.000079 | 3,957.5694 | $0.3107 | |
ETH | <0.01% | $0.000749 | 414.8173 | $0.3107 | |
ETH | <0.01% | $0.001411 | 219.64 | $0.3098 | |
ETH | <0.01% | $0.999938 | 0.3098 | $0.3098 | |
ETH | <0.01% | $0.150522 | 2.0418 | $0.3073 | |
ETH | <0.01% | $670.94 | 0.0004578 | $0.3071 | |
ETH | <0.01% | <$0.000001 | 1,347,592,021.7762 | $0.3037 | |
ETH | <0.01% | $0.00061 | 498.0507 | $0.3037 | |
ETH | <0.01% | $0.000001 | 601,864.509 | $0.3032 | |
ETH | <0.01% | $0.000033 | 9,084.8639 | $0.3025 | |
ETH | <0.01% | $0.157399 | 1.9121 | $0.3009 | |
ETH | <0.01% | $79.48 | 0.00376105 | $0.2989 | |
ETH | <0.01% | $0.000036 | 8,221.6955 | $0.2981 | |
ETH | <0.01% | $7.22 | 0.0405 | $0.2921 | |
ETH | <0.01% | $0.400178 | 0.7188 | $0.2876 | |
ETH | <0.01% | $0.006048 | 47.4966 | $0.2872 | |
ETH | <0.01% | $0.112531 | 2.545 | $0.2863 | |
ETH | <0.01% | $0.000016 | 18,075.652 | $0.2859 | |
ETH | <0.01% | $0.03544 | 8.0226 | $0.2843 | |
ETH | <0.01% | $0.016277 | 17.4501 | $0.284 | |
ETH | <0.01% | $0.079305 | 3.5815 | $0.284 | |
ETH | <0.01% | $0.00514 | 54.846 | $0.2818 | |
ETH | <0.01% | $0.000025 | 11,154.5871 | $0.2807 | |
ETH | <0.01% | $0.261363 | 1.0677 | $0.279 | |
ETH | <0.01% | $0.000185 | 1,510.1038 | $0.2789 | |
ETH | <0.01% | <$0.000001 | 13,746,882.1294 | $0.2775 | |
ETH | <0.01% | $0.000867 | 319.7209 | $0.2771 | |
ETH | <0.01% | $0.551013 | 0.5024 | $0.2768 | |
ETH | <0.01% | <$0.000001 | 390,518,536.5276 | $0.2752 | |
ETH | <0.01% | <$0.000001 | 129,751,167,314.0645 | $0.2748 | |
ETH | <0.01% | $0.009759 | 28.16 | $0.2748 | |
ETH | <0.01% | $0.995553 | 0.2755 | $0.2742 | |
ETH | <0.01% | <$0.000001 | 166,022,314.4417 | $0.2736 | |
ETH | <0.01% | $0.000018 | 15,477.3507 | $0.2731 | |
ETH | <0.01% | $4.58 | 0.0594 | $0.2722 | |
ETH | <0.01% | $0.042327 | 6.4026 | $0.271 | |
ETH | <0.01% | $0.012377 | 21.8796 | $0.2708 | |
ETH | <0.01% | $3.76 | 0.072 | $0.2707 | |
ETH | <0.01% | $0.000094 | 2,868.3529 | $0.2695 | |
ETH | <0.01% | $0.009614 | 28.0185 | $0.2693 | |
ETH | <0.01% | <$0.000001 | 3,869,062.9647 | $0.2676 | |
ETH | <0.01% | $0.000049 | 5,412.9007 | $0.267 | |
ETH | <0.01% | $0.000081 | 3,278.9025 | $0.2669 | |
ETH | <0.01% | $0.000547 | 488.1699 | $0.2668 | |
ETH | <0.01% | $0.020582 | 12.9496 | $0.2665 | |
ETH | <0.01% | $0.00069 | 385.5612 | $0.266 | |
ETH | <0.01% | <$0.000001 | 4,578,242,889.088 | $0.2643 | |
ETH | <0.01% | $0.553319 | 0.4764 | $0.2636 | |
ETH | <0.01% | $0.006847 | 38.4696 | $0.2633 | |
ETH | <0.01% | <$0.000001 | 280,000,000 | $0.2631 | |
ETH | <0.01% | $0.000022 | 11,878.869 | $0.261 | |
ETH | <0.01% | $0.065191 | 4 | $0.2607 | |
ETH | <0.01% | <$0.000001 | 9,882,448,482.8009 | $0.2593 | |
ETH | <0.01% | $0.000354 | 732.9337 | $0.2593 | |
ETH | <0.01% | $0.000318 | 814.2184 | $0.259 | |
ETH | <0.01% | $0.024523 | 10.5486 | $0.2586 | |
ETH | <0.01% | $0.000415 | 619.3212 | $0.2571 | |
ETH | <0.01% | $0.001569 | 163.468 | $0.2564 | |
ETH | <0.01% | $0.000016 | 16,017.6127 | $0.2548 | |
ETH | <0.01% | $0.072315 | 3.52 | $0.2545 | |
ETH | <0.01% | $0.030029 | 8.4625 | $0.2541 | |
ETH | <0.01% | <$0.000001 | 27,739,505.1649 | $0.253 | |
ETH | <0.01% | <$0.000001 | 7,007,000,636.7689 | $0.2525 | |
ETH | <0.01% | $0.000654 | 384.4328 | $0.2515 | |
ETH | <0.01% | $0.010293 | 24.3108 | $0.2502 | |
ETH | <0.01% | $0.000326 | 765.4381 | $0.2498 | |
ETH | <0.01% | <$0.000001 | 767,155.5455 | $0.2471 | |
ETH | <0.01% | $0.00 | 265.6981 | $0.00 | |
ETH | <0.01% | $0.006093 | 40.5125 | $0.2468 | |
ETH | <0.01% | $0.000433 | 565.9904 | $0.2448 | |
ETH | <0.01% | <$0.000001 | 30,984,044.6064 | $0.2436 | |
ETH | <0.01% | $0.000487 | 495.7752 | $0.2415 | |
ETH | <0.01% | $0.000006 | 40,908.056 | $0.2397 | |
ETH | <0.01% | $7.68 | 0.0311 | $0.2389 | |
ETH | <0.01% | $0.997221 | 0.2391 | $0.2384 | |
ETH | <0.01% | <$0.000001 | 10,703,208.6417 | $0.238 | |
ETH | <0.01% | $0.12739 | 1.8567 | $0.2365 | |
ETH | <0.01% | $0.001642 | 143.8985 | $0.2362 | |
ETH | <0.01% | $0.196793 | 1.2007 | $0.2362 | |
ETH | <0.01% | <$0.000001 | 886,599,382.7918 | $0.2329 | |
ETH | <0.01% | $0.006861 | 33.8148 | $0.232 | |
ETH | <0.01% | $0.000358 | 644.8713 | $0.2309 | |
ETH | <0.01% | $0.372144 | 0.6186 | $0.2302 | |
ETH | <0.01% | $0.000128 | 1,795.7581 | $0.23 | |
ETH | <0.01% | $0.091775 | 2.5018 | $0.2296 | |
ETH | <0.01% | $0.000412 | 556.8119 | $0.2293 | |
ETH | <0.01% | $0.014242 | 16 | $0.2278 | |
ETH | <0.01% | <$0.000001 | 17,428,227,654.9293 | $0.2277 | |
ETH | <0.01% | <$0.000001 | 56,624,291.1612 | $0.2241 | |
ETH | <0.01% | <$0.000001 | 208,916,071.5843 | $0.2227 | |
ETH | <0.01% | $0.014864 | 14.9844 | $0.2227 | |
ETH | <0.01% | $0.038091 | 5.7953 | $0.2207 | |
ETH | <0.01% | $0.000232 | 941.3483 | $0.2184 | |
ETH | <0.01% | $0.00003 | 7,340.1506 | $0.2178 | |
ETH | <0.01% | $0.000002 | 128,691.1167 | $0.2169 | |
ETH | <0.01% | $0.002672 | 79.1202 | $0.2114 | |
ETH | <0.01% | $0.000094 | 2,249.2092 | $0.2107 | |
ETH | <0.01% | $0.192973 | 1.0914 | $0.2106 | |
ETH | <0.01% | $0.017186 | 12.0743 | $0.2075 | |
ETH | <0.01% | <$0.000001 | 5,136,985.2241 | $0.2065 | |
ETH | <0.01% | $0.999854 | 0.2059 | $0.2058 | |
ETH | <0.01% | $0.04765 | 4.3165 | $0.2056 | |
ETH | <0.01% | $9.65 | 0.0211 | $0.2033 | |
ETH | <0.01% | $0.000003 | 79,395.1664 | $0.2032 | |
ETH | <0.01% | $0.003943 | 50.9156 | $0.2007 | |
ETH | <0.01% | $2.61 | 0.0766 | $0.2001 | |
ETH | <0.01% | <$0.000001 | 618,350.9906 | $0.1986 | |
ETH | <0.01% | $0.00011 | 1,805.9436 | $0.1984 | |
ETH | <0.01% | $0.004276 | 46.3152 | $0.198 | |
ETH | <0.01% | $0.006116 | 32.2528 | $0.1972 | |
ETH | <0.01% | <$0.000001 | 553,209,607.4577 | $0.1971 | |
ETH | <0.01% | $0.463692 | 0.4241 | $0.1966 | |
ETH | <0.01% | <$0.000001 | 134,704,454.948 | $0.1963 | |
ETH | <0.01% | $0.001155 | 169.5717 | $0.1959 | |
ETH | <0.01% | $0.003937 | 49.6763 | $0.1955 | |
ETH | <0.01% | $0.001525 | 127.1197 | $0.1938 | |
ETH | <0.01% | $0.000857 | 226.093 | $0.1937 | |
ETH | <0.01% | $0.002911 | 66.436 | $0.1934 | |
ETH | <0.01% | <$0.000001 | 1,152,084.1352 | $0.193 | |
ETH | <0.01% | $0.001505 | 127.8734 | $0.1925 | |
ETH | <0.01% | $0.000017 | 11,038.5684 | $0.1918 | |
ETH | <0.01% | $0.261239 | 0.7314 | $0.191 | |
ETH | <0.01% | $0.011882 | 16 | $0.1901 | |
ETH | <0.01% | $1.18 | 0.16 | $0.1888 | |
ETH | <0.01% | <$0.000001 | 446,906,150.252 | $0.1882 | |
ETH | <0.01% | <$0.000001 | 1,718,111,134.5857 | $0.1875 | |
ETH | <0.01% | $0.000487 | 383.2271 | $0.1867 | |
ETH | <0.01% | $0.006814 | 27.2859 | $0.1859 | |
ETH | <0.01% | $1.57 | 0.1183 | $0.1857 | |
ETH | <0.01% | <$0.000001 | 39,832,699.7917 | $0.1855 | |
ETH | <0.01% | $0.000003 | 61,622.9765 | $0.185 | |
ETH | <0.01% | <$0.000001 | 1,454,535.4509 | $0.1845 | |
ETH | <0.01% | $0.000099 | 1,858.1056 | $0.1837 | |
ETH | <0.01% | $0.295634 | 0.6217 | $0.1837 | |
ETH | <0.01% | $0.015253 | 12.0235 | $0.1833 | |
ETH | <0.01% | $0.002996 | 60.7386 | $0.1819 | |
ETH | <0.01% | $0.000032 | 5,758.6436 | $0.1818 | |
ETH | <0.01% | $0.009811 | 18.528 | $0.1817 | |
ETH | <0.01% | <$0.000001 | 642,364.4812 | $0.1813 | |
ETH | <0.01% | $0.128232 | 1.4146 | $0.1813 | |
ETH | <0.01% | $0.004192 | 43.0811 | $0.1806 | |
ETH | <0.01% | $0.000211 | 852.279 | $0.18 | |
ETH | <0.01% | $0.008141 | 22.0659 | $0.1796 | |
ETH | <0.01% | $0.236203 | 0.76 | $0.1795 | |
ETH | <0.01% | $19.41 | 0.0092339 | $0.1792 | |
ETH | <0.01% | $0.000037 | 4,809.8086 | $0.1779 | |
ETH | <0.01% | $0.001855 | 95.9614 | $0.1779 | |
ETH | <0.01% | $0.000001 | 226,758.4089 | $0.1766 | |
ETH | <0.01% | $0.002161 | 81.2963 | $0.1756 | |
ETH | <0.01% | $0.007818 | 22.4334 | $0.1753 | |
ETH | <0.01% | $0.0245 | 7.1556 | $0.1753 | |
ETH | <0.01% | $0.034711 | 5.0162 | $0.1741 | |
ETH | <0.01% | $61.8 | 0.00281567 | $0.174 | |
ETH | <0.01% | $0.000005 | 33,610.6239 | $0.1728 | |
ETH | <0.01% | $0.310807 | 0.5541 | $0.1722 | |
ETH | <0.01% | $0.000377 | 455.7389 | $0.1718 | |
ETH | <0.01% | $0.001095 | 156.4239 | $0.1712 | |
ETH | <0.01% | $0.005434 | 31.5 | $0.1711 | |
ETH | <0.01% | $0.024458 | 6.9962 | $0.1711 | |
ETH | <0.01% | $0.00195 | 87.5802 | $0.1707 | |
ETH | <0.01% | $0.000043 | 4,000 | $0.1702 | |
ETH | <0.01% | $0.327555 | 0.5182 | $0.1697 | |
ETH | <0.01% | $0.000441 | 382.3549 | $0.1685 | |
ETH | <0.01% | $0.017852 | 9.4238 | $0.1682 | |
ETH | <0.01% | <$0.000001 | 3,120,412.4226 | $0.168 | |
ETH | <0.01% | $0.019772 | 8.4566 | $0.1672 | |
ETH | <0.01% | $0.03872 | 4.3064 | $0.1667 | |
ETH | <0.01% | $0.000021 | 8,032.1495 | $0.1666 | |
ETH | <0.01% | $0.006938 | 24 | $0.1665 | |
ETH | <0.01% | $0.002171 | 76.5471 | $0.1661 | |
ETH | <0.01% | <$0.000001 | 3,125,547,644.4227 | $0.1654 | |
ETH | <0.01% | <$0.000001 | 1,679,184,490.9439 | $0.1651 | |
ETH | <0.01% | $0.000721 | 227.7434 | $0.1641 | |
ETH | <0.01% | $0.000024 | 6,699.5489 | $0.164 | |
ETH | <0.01% | $6.77 | 0.024 | $0.1625 | |
ETH | <0.01% | $0.079632 | 2.0383 | $0.1623 | |
ETH | <0.01% | $0.001841 | 87.6911 | $0.1614 | |
ETH | <0.01% | $0.403328 | 0.4 | $0.1613 | |
ETH | <0.01% | $0.000196 | 815.1021 | $0.1597 | |
ETH | <0.01% | $0.038714 | 4.0741 | $0.1577 | |
ETH | <0.01% | $0.015427 | 10.2103 | $0.1575 | |
ETH | <0.01% | $0.165224 | 0.9433 | $0.1558 | |
ETH | <0.01% | <$0.000001 | 1,346,604,783.049 | $0.1556 | |
ETH | <0.01% | $0.014106 | 10.9903 | $0.155 | |
ETH | <0.01% | $0.003591 | 42.4838 | $0.1525 | |
ETH | <0.01% | $0.008801 | 17.321 | $0.1524 | |
ETH | <0.01% | $0.010507 | 14.4683 | $0.152 | |
ETH | <0.01% | $0.01122 | 13.5552 | $0.152 | |
ETH | <0.01% | $0.000446 | 340.4928 | $0.1517 | |
ETH | <0.01% | $0.000467 | 324.504 | $0.1514 | |
ETH | <0.01% | $0.00018 | 838.6264 | $0.1512 | |
ETH | <0.01% | $0.000103 | 1,468.4836 | $0.1509 | |
ETH | <0.01% | $0.029335 | 5.1363 | $0.1506 | |
ETH | <0.01% | $0.000089 | 1,675.0401 | $0.1497 | |
ETH | <0.01% | $0.496902 | 0.3011 | $0.1496 | |
ETH | <0.01% | $0.009333 | 15.8982 | $0.1483 | |
ETH | <0.01% | $0.012341 | 11.9919 | $0.1479 | |
ETH | <0.01% | $0.180099 | 0.8191 | $0.1475 | |
ETH | <0.01% | <$0.000001 | 47,768,528.8603 | $0.1455 | |
ETH | <0.01% | $0.02439 | 5.964 | $0.1454 | |
ETH | <0.01% | <$0.000001 | 51,472,341.3438 | $0.1452 | |
ETH | <0.01% | $0.041803 | 3.4603 | $0.1446 | |
ETH | <0.01% | $0.012168 | 11.855 | $0.1442 | |
ETH | <0.01% | $0.000018 | 8,090.5952 | $0.1441 | |
ETH | <0.01% | <$0.000001 | 30,871,783.7536 | $0.1414 | |
ETH | <0.01% | $0.000006 | 22,035.9039 | $0.141 | |
ETH | <0.01% | $0.000478 | 294.8182 | $0.1408 | |
ETH | <0.01% | $0.002936 | 47.8563 | $0.1405 | |
ETH | <0.01% | <$0.000001 | 626,881.3136 | $0.1391 | |
ETH | <0.01% | $0.03738 | 3.6667 | $0.137 | |
ETH | <0.01% | $0.000034 | 4,011.1714 | $0.1361 | |
ETH | <0.01% | <$0.000001 | 426,580,281,145.6318 | $0.136 | |
ETH | <0.01% | $0.000133 | 1,018.4517 | $0.1352 | |
ETH | <0.01% | $0.022058 | 6.1192 | $0.1349 | |
ETH | <0.01% | $0.080016 | 1.6772 | $0.1342 | |
ETH | <0.01% | $0.005815 | 22.9421 | $0.1333 | |
ETH | <0.01% | $4.94 | 0.0269 | $0.133 | |
ETH | <0.01% | $0.000379 | 346.4447 | $0.1312 | |
ETH | <0.01% | $0.014697 | 8.8605 | $0.1302 | |
ETH | <0.01% | $120,661.16 | 0.00000108 | $0.13 | |
ETH | <0.01% | <$0.000001 | 840,119.8223 | $0.1294 | |
ETH | <0.01% | $1 | 0.129 | $0.1291 | |
ETH | <0.01% | $0.045878 | 2.8036 | $0.1286 | |
ETH | <0.01% | $0.001863 | 68.9793 | $0.1285 | |
ETH | <0.01% | $0.000158 | 806.4996 | $0.1275 | |
ETH | <0.01% | $0.005241 | 24.3098 | $0.1274 | |
ETH | <0.01% | $0.081613 | 1.5507 | $0.1265 | |
ETH | <0.01% | $0.00573 | 21.9678 | $0.1258 | |
ETH | <0.01% | $0.007137 | 17.5024 | $0.1249 | |
ETH | <0.01% | <$0.000001 | 1,291,372.3445 | $0.124 | |
ETH | <0.01% | $18.23 | 0.0068037 | $0.124 | |
ETH | <0.01% | $0.000011 | 11,636.3477 | $0.1239 | |
ETH | <0.01% | $0.00005 | 2,466.0077 | $0.1225 | |
ETH | <0.01% | $0.000045 | 2,685.2857 | $0.122 | |
ETH | <0.01% | $0.00109 | 112 | $0.122 | |
ETH | <0.01% | $0.000093 | 1,309.6226 | $0.1214 | |
ETH | <0.01% | <$0.000001 | 669,472,111.7826 | $0.1209 | |
ETH | <0.01% | $0.000123 | 979.9812 | $0.1209 | |
ETH | <0.01% | <$0.000001 | 715,354.5329 | $0.1204 | |
ETH | <0.01% | $0.000101 | 1,187.2 | $0.1196 | |
ETH | <0.01% | <$0.000001 | 170,279,346.0814 | $0.1192 | |
ETH | <0.01% | $0.083336 | 1.4309 | $0.1192 | |
ETH | <0.01% | $0.003478 | 34.0516 | $0.1184 | |
ETH | <0.01% | $0.000221 | 535.6674 | $0.1182 | |
ETH | <0.01% | $0.013421 | 8.8 | $0.1181 | |
ETH | <0.01% | $0.000098 | 1,196.7539 | $0.1177 | |
ETH | <0.01% | $0.000855 | 137.6572 | $0.1177 | |
ETH | <0.01% | $0.005102 | 22.5912 | $0.1152 | |
ETH | <0.01% | $0.001333 | 86.3724 | $0.1151 | |
ETH | <0.01% | $0.000211 | 544.3841 | $0.1149 | |
ETH | <0.01% | $0.000217 | 528.6479 | $0.1145 | |
ETH | <0.01% | <$0.000001 | 9,457,778.6957 | $0.1142 | |
ETH | <0.01% | $0.146203 | 0.7814 | $0.1142 | |
ETH | <0.01% | $0.161052 | 0.7056 | $0.1136 | |
ETH | <0.01% | <$0.000001 | 2,114,247.5738 | $0.1134 | |
ETH | <0.01% | $0.000028 | 4,091.6317 | $0.1134 | |
ETH | <0.01% | $0.000001 | 188,404.4487 | $0.1113 | |
ETH | <0.01% | <$0.000001 | 55,753,238,940.3591 | $0.1101 | |
ETH | <0.01% | $0.000118 | 926.5486 | $0.1089 | |
ETH | <0.01% | <$0.000001 | 36,847,639.9908 | $0.1087 | |
ETH | <0.01% | $0.00 | 80.008 | $0.00 | |
ETH | <0.01% | $0.000107 | 995.4621 | $0.1064 | |
ETH | <0.01% | $0.997039 | 0.1058 | $0.1055 | |
ETH | <0.01% | <$0.000001 | 19,520,757.0401 | $0.1045 | |
ETH | <0.01% | $0.007445 | 14.0155 | $0.1043 | |
ETH | <0.01% | $0.009533 | 10.9426 | $0.1043 | |
ETH | <0.01% | $0.003302 | 31.2178 | $0.103 | |
ETH | <0.01% | $0.004003 | 25.7208 | $0.1029 | |
ETH | <0.01% | $0.000153 | 671.9421 | $0.1028 | |
ETH | <0.01% | $94.07 | 0.00108697 | $0.1022 | |
ETH | <0.01% | $0.00001 | 10,392.5428 | $0.1021 | |
ETH | <0.01% | $0.102824 | 0.993 | $0.1021 | |
ETH | <0.01% | $0.026816 | 3.8001 | $0.1019 | |
ETH | <0.01% | $0.00073 | 139.5881 | $0.1018 | |
ETH | <0.01% | $0.003059 | 33.0945 | $0.1012 | |
ETH | <0.01% | $0.358688 | 0.2817 | $0.101 | |
ETH | <0.01% | <$0.000001 | 3,118,556.2388 | $0.1007 | |
ETH | <0.01% | <$0.000001 | 349,361.9646 | $0.1006 | |
ETH | <0.01% | $0.004441 | 22.665 | $0.1006 | |
ETH | <0.01% | $0.000358 | 281.1302 | $0.1005 | |
ETH | <0.01% | $0.000469 | 213.9489 | $0.1003 | |
ETH | <0.01% | $0.000914 | 109.7007 | $0.1003 | |
BASE | <0.01% | $0.013844 | 4,521.9615 | $62.6 | |
BASE | <0.01% | $0.01434 | 3,615.0965 | $51.84 | |
BASE | <0.01% | $122,663 | 0.00039099 | $47.96 | |
BASE | <0.01% | $0.00 | 0.00984232 | $0.00 | |
BASE | <0.01% | $0.020942 | 2,074.8868 | $43.45 | |
BASE | <0.01% | $0.020982 | 2,067.6627 | $43.38 | |
BASE | <0.01% | $0.071689 | 582.1554 | $41.73 | |
BASE | <0.01% | $0.001249 | 33,015.6225 | $41.24 | |
BASE | <0.01% | $30.25 | 1.3262 | $40.12 | |
BASE | <0.01% | $0.045488 | 868.4586 | $39.5 | |
BASE | <0.01% | $6.35 | 6.112 | $38.81 | |
BASE | <0.01% | $4,936.28 | 0.00782408 | $38.62 | |
BASE | <0.01% | $1.35 | 27.3444 | $36.91 | |
BASE | <0.01% | $0.001639 | 21,475.2624 | $35.19 | |
BASE | <0.01% | $0.421913 | 83.2828 | $35.14 | |
BASE | <0.01% | $0.000142 | 244,931.2691 | $34.69 | |
BASE | <0.01% | $1.16 | 29.8623 | $34.64 | |
BASE | <0.01% | $5,122.43 | 0.00656458 | $33.63 | |
BASE | <0.01% | $0.363178 | 91.5841 | $33.26 | |
BASE | <0.01% | $0.000062 | 530,322.0466 | $33.02 | |
BASE | <0.01% | $0.007724 | 4,247.1648 | $32.81 | |
BASE | <0.01% | $0.004841 | 6,595.2664 | $31.93 | |
BASE | <0.01% | $0.102267 | 311.0792 | $31.81 | |
BASE | <0.01% | $0.002211 | 14,123.9688 | $31.23 | |
BASE | <0.01% | $0.002257 | 13,516.443 | $30.5 | |
BASE | <0.01% | $0.445806 | 67.3598 | $30.03 | |
BASE | <0.01% | $0.02058 | 1,443.6024 | $29.71 | |
BASE | <0.01% | $0.122923 | 232.6244 | $28.59 | |
BASE | <0.01% | $0.006594 | 4,305.5865 | $28.39 | |
BASE | <0.01% | $0.038661 | 722.0028 | $27.91 | |
BASE | <0.01% | $0.001594 | 17,453.7605 | $27.83 | |
BASE | <0.01% | $5,446.99 | 0.00507798 | $27.66 | |
BASE | <0.01% | $0.052061 | 530.8248 | $27.64 | |
BASE | <0.01% | $0.000051 | 537,549.9187 | $27.58 | |
BASE | <0.01% | $0.492668 | 55.7518 | $27.47 | |
BASE | <0.01% | $4,834.7 | 0.0056699 | $27.41 | |
BASE | <0.01% | $3.46 | 7.736 | $26.77 | |
BASE | <0.01% | $0.00696 | 3,836.9935 | $26.7 | |
BASE | <0.01% | $280.34 | 0.0938 | $26.29 | |
BASE | <0.01% | $0.000793 | 33,123.6826 | $26.27 | |
BASE | <0.01% | $0.004972 | 5,265.7282 | $26.18 | |
BASE | <0.01% | $0.151273 | 173.0496 | $26.18 | |
BASE | <0.01% | $0.030417 | 852.4707 | $25.93 | |
BASE | <0.01% | $0.000589 | 43,663.1837 | $25.71 | |
BASE | <0.01% | $0.003641 | 6,886.6911 | $25.07 | |
BASE | <0.01% | $0.000001 | 30,905,110.1299 | $24.19 | |
BASE | <0.01% | $1.09 | 21.3031 | $23.31 | |
BASE | <0.01% | $0.007456 | 3,096.404 | $23.09 | |
BASE | <0.01% | $0.064137 | 358.6978 | $23.01 | |
BASE | <0.01% | $1.36 | 16.6572 | $22.65 | |
BASE | <0.01% | $0.127347 | 177.312 | $22.58 | |
BASE | <0.01% | $122,571 | 0.00017947 | $22 | |
BASE | <0.01% | $0.002806 | 7,803.4258 | $21.9 | |
BASE | <0.01% | $0.000637 | 34,162.2316 | $21.76 | |
BASE | <0.01% | $0.048734 | 434.0063 | $21.15 | |
BASE | <0.01% | $2.41 | 8.6152 | $20.76 | |
BASE | <0.01% | $0.093278 | 222.3833 | $20.74 | |
BASE | <0.01% | $0.001162 | 17,268.3536 | $20.06 | |
BASE | <0.01% | $0.001809 | 11,011.033 | $19.92 | |
BASE | <0.01% | $0.062398 | 316.6656 | $19.76 | |
BASE | <0.01% | $0.023881 | 802.6659 | $19.17 | |
BASE | <0.01% | $0.207367 | 90.2627 | $18.72 | |
BASE | <0.01% | $0.0061 | 2,930.2592 | $17.87 | |
BASE | <0.01% | $0.000006 | 2,842,611.0145 | $17.79 | |
BASE | <0.01% | $0.014705 | 1,191.8822 | $17.53 | |
BASE | <0.01% | <$0.000001 | 953,236,194.0699 | $16.11 | |
BASE | <0.01% | $0.745651 | 20.9215 | $15.6 | |
BASE | <0.01% | $0.600027 | 24.7594 | $14.86 | |
BASE | <0.01% | $0.006419 | 2,278.7657 | $14.63 | |
BASE | <0.01% | $122,772 | 0.00011869 | $14.57 | |
BASE | <0.01% | $0.002649 | 5,467.7266 | $14.48 | |
BASE | <0.01% | $0.268443 | 53.7603 | $14.43 | |
BASE | <0.01% | $0.01089 | 1,315.5382 | $14.33 | |
BASE | <0.01% | $0.000157 | 90,517.4027 | $14.21 | |
BASE | <0.01% | $0.010525 | 1,327.7255 | $13.97 | |
BASE | <0.01% | $0.006906 | 2,011.4068 | $13.89 | |
BASE | <0.01% | $0.541086 | 25.4709 | $13.78 | |
BASE | <0.01% | $0.000128 | 107,267.8941 | $13.73 | |
BASE | <0.01% | $0.033417 | 409.9136 | $13.7 | |
BASE | <0.01% | <$0.000001 | 2,478,353,740.8061 | $13.63 | |
BASE | <0.01% | $0.019369 | 700.0916 | $13.56 | |
BASE | <0.01% | $0.030195 | 442.8937 | $13.37 | |
BASE | <0.01% | $0.010222 | 1,286.369 | $13.15 | |
BASE | <0.01% | $0.28229 | 46.5674 | $13.15 | |
BASE | <0.01% | $0.197296 | 64.4471 | $12.72 | |
BASE | <0.01% | $0.043789 | 287.6714 | $12.6 | |
BASE | <0.01% | $0.000005 | 2,542,242.5838 | $11.95 | |
BASE | <0.01% | $0.002837 | 4,203.7412 | $11.93 | |
BASE | <0.01% | $2.3 | 5.1497 | $11.84 | |
BASE | <0.01% | $0.000535 | 21,438.4643 | $11.47 | |
BASE | <0.01% | $0.000001 | 12,579,567.0107 | $11.45 | |
BASE | <0.01% | $0.022063 | 501.0504 | $11.05 | |
BASE | <0.01% | $0.000372 | 29,642.1906 | $11.04 | |
BASE | <0.01% | $0.000009 | 1,210,847.3389 | $11.03 | |
BASE | <0.01% | $0.002962 | 3,696.8092 | $10.95 | |
BASE | <0.01% | $0.000007 | 1,479,695.9573 | $10.86 | |
BASE | <0.01% | $0.000216 | 50,035.0491 | $10.79 | |
BASE | <0.01% | $0.052262 | 202.9171 | $10.6 | |
BASE | <0.01% | <$0.000001 | 28,579,329.1538 | $10.33 | |
BASE | <0.01% | $0.004953 | 2,051.854 | $10.16 | |
BASE | <0.01% | $0.032319 | 313.0226 | $10.12 | |
BASE | <0.01% | $0.031488 | 318.2048 | $10.02 | |
BASE | <0.01% | $0.016636 | 600.3821 | $9.99 | |
BASE | <0.01% | $0.003434 | 2,898.9074 | $9.96 | |
BASE | <0.01% | $2.89 | 3.4433 | $9.95 | |
BASE | <0.01% | $0.054191 | 182.3866 | $9.88 | |
BASE | <0.01% | $122,482 | 0.00008052 | $9.86 | |
BASE | <0.01% | $0.170826 | 57.3735 | $9.8 | |
BASE | <0.01% | $0.902442 | 10.6733 | $9.63 | |
BASE | <0.01% | $0.000014 | 657,225.5945 | $9.52 | |
BASE | <0.01% | $0.004599 | 2,044.9667 | $9.41 | |
BASE | <0.01% | $0.001101 | 8,452.8656 | $9.31 | |
BASE | <0.01% | $0.00001 | 875,713.8687 | $9.17 | |
BASE | <0.01% | $0.019424 | 469.7896 | $9.13 | |
BASE | <0.01% | $0.137766 | 66.1675 | $9.12 | |
BASE | <0.01% | $0.000544 | 16,468.0878 | $8.96 | |
BASE | <0.01% | $1 | 8.775 | $8.78 | |
BASE | <0.01% | $6.56 | 1.3073 | $8.58 | |
BASE | <0.01% | $0.000161 | 52,322.9156 | $8.44 | |
BASE | <0.01% | $0.045757 | 184.0017 | $8.42 | |
BASE | <0.01% | $0.116458 | 72.02 | $8.39 | |
BASE | <0.01% | $0.001766 | 4,735.4387 | $8.36 | |
BASE | <0.01% | $0.000113 | 73,034.933 | $8.25 | |
BASE | <0.01% | $1.08 | 7.4829 | $8.08 | |
BASE | <0.01% | $0.000024 | 335,268.1481 | $7.93 | |
BASE | <0.01% | $0.000237 | 32,625.7055 | $7.75 | |
BASE | <0.01% | $0.001936 | 3,959.1015 | $7.66 | |
BASE | <0.01% | $0.454573 | 16.6314 | $7.56 | |
BASE | <0.01% | $0.010222 | 730.9171 | $7.47 | |
BASE | <0.01% | $1.72 | 4.3272 | $7.44 | |
BASE | <0.01% | $0.000323 | 22,176.951 | $7.17 | |
BASE | <0.01% | $0.919402 | 7.7989 | $7.17 | |
BASE | <0.01% | $0.000044 | 158,295.5129 | $6.9 | |
BASE | <0.01% | $0.002686 | 2,544.8772 | $6.83 | |
BASE | <0.01% | $0.000831 | 8,202.2684 | $6.82 | |
BASE | <0.01% | $0.060107 | 111.7319 | $6.72 | |
BASE | <0.01% | $1.73 | 3.8363 | $6.63 | |
BASE | <0.01% | $0.000805 | 8,181.2131 | $6.58 | |
BASE | <0.01% | $0.000163 | 38,475.9035 | $6.27 | |
BASE | <0.01% | $0.000052 | 118,635.2549 | $6.17 | |
BASE | <0.01% | $0.103746 | 58.6683 | $6.09 | |
BASE | <0.01% | $0.000072 | 82,004.5949 | $5.92 | |
BASE | <0.01% | $1.07 | 5.5532 | $5.91 | |
BASE | <0.01% | $0.050355 | 116.9254 | $5.89 | |
BASE | <0.01% | $0.003105 | 1,888.1165 | $5.86 | |
BASE | <0.01% | $0.000009 | 631,059.1373 | $5.74 | |
BASE | <0.01% | $1.77 | 3.1706 | $5.61 | |
BASE | <0.01% | $0.254227 | 22.0178 | $5.6 | |
BASE | <0.01% | $0.001714 | 3,262.2067 | $5.59 | |
BASE | <0.01% | <$0.000001 | 256,962,861.2484 | $5.5 | |
BASE | <0.01% | $0.123735 | 43.3873 | $5.37 | |
BASE | <0.01% | $0.000054 | 96,317.5966 | $5.24 | |
BASE | <0.01% | $0.021927 | 238.9256 | $5.24 | |
BASE | <0.01% | $0.009894 | 517.6292 | $5.12 | |
BASE | <0.01% | $0.012388 | 400.4387 | $4.96 | |
BASE | <0.01% | $0.000701 | 6,557.9403 | $4.6 | |
BASE | <0.01% | $0.017979 | 251.5992 | $4.52 | |
BASE | <0.01% | $0.000073 | 60,748.2049 | $4.46 | |
BASE | <0.01% | $0.017656 | 248.8167 | $4.39 | |
BASE | <0.01% | $0.305504 | 13.9296 | $4.26 | |
BASE | <0.01% | $1.55 | 2.7098 | $4.2 | |
BASE | <0.01% | $0.000002 | 2,453,730.5874 | $4.17 | |
BASE | <0.01% | $0.479366 | 8.6803 | $4.16 | |
BASE | <0.01% | <$0.000001 | 40,312,619,145.2878 | $4.03 | |
BASE | <0.01% | $0.997827 | 4.0244 | $4.02 | |
BASE | <0.01% | $0.034617 | 114.0492 | $3.95 | |
BASE | <0.01% | $0.124759 | 31.3558 | $3.91 | |
BASE | <0.01% | $0.000051 | 75,892.9098 | $3.9 | |
BASE | <0.01% | <$0.000001 | 7,633,812,181.8739 | $3.82 | |
BASE | <0.01% | $0.000004 | 883,807.5472 | $3.75 | |
BASE | <0.01% | $0.004504 | 818.302 | $3.69 | |
BASE | <0.01% | $0.003828 | 957.007 | $3.66 | |
BASE | <0.01% | $0.000008 | 469,254.7671 | $3.64 | |
BASE | <0.01% | $0.308242 | 11.7803 | $3.63 | |
BASE | <0.01% | $3.67 | 0.9845 | $3.61 | |
BASE | <0.01% | $0.320907 | 10.9289 | $3.51 | |
BASE | <0.01% | $0.000068 | 49,430.1984 | $3.38 | |
BASE | <0.01% | $0.005089 | 661.7721 | $3.37 | |
BASE | <0.01% | $0.000587 | 5,715.4356 | $3.36 | |
BASE | <0.01% | $0.001799 | 1,835.0798 | $3.3 | |
BASE | <0.01% | $0.02976 | 108.0601 | $3.22 | |
BASE | <0.01% | $0.354944 | 8.8504 | $3.14 | |
BASE | <0.01% | $0.000385 | 8,081.4584 | $3.11 | |
BASE | <0.01% | $0.176481 | 17.5652 | $3.1 | |
BASE | <0.01% | <$0.000001 | 23,576,101.3353 | $3.07 | |
BASE | <0.01% | $0.00039 | 7,847.7885 | $3.06 | |
BASE | <0.01% | $0.25768 | 11.6802 | $3.01 | |
BASE | <0.01% | $0.048746 | 60.9251 | $2.97 | |
BASE | <0.01% | $0.989162 | 2.9838 | $2.95 | |
BASE | <0.01% | $0.001389 | 2,083.0469 | $2.89 | |
BASE | <0.01% | $0.000073 | 39,866.8358 | $2.89 | |
BASE | <0.01% | $0.001741 | 1,659.2944 | $2.89 | |
BASE | <0.01% | $0.172567 | 15.9453 | $2.75 | |
BASE | <0.01% | $0.009737 | 274.5924 | $2.67 | |
BASE | <0.01% | $0.000006 | 419,751.7863 | $2.67 | |
BASE | <0.01% | <$0.000001 | 32,561,221.2883 | $2.6 | |
BASE | <0.01% | $0.001699 | 1,525.7259 | $2.59 | |
BASE | <0.01% | $0.006007 | 428.5094 | $2.57 | |
BASE | <0.01% | $0.000048 | 53,424.1537 | $2.56 | |
BASE | <0.01% | $0.000283 | 8,938.0932 | $2.53 | |
BASE | <0.01% | $1 | 2.5053 | $2.51 | |
BASE | <0.01% | $0.000232 | 10,652.9322 | $2.47 | |
BASE | <0.01% | $0.000249 | 9,865.3829 | $2.46 | |
BASE | <0.01% | $0.000329 | 7,450.1318 | $2.45 | |
BASE | <0.01% | $1.12 | 2.0926 | $2.34 | |
BASE | <0.01% | $0.001264 | 1,837.3641 | $2.32 | |
BASE | <0.01% | $0.000023 | 98,807.2627 | $2.32 | |
BASE | <0.01% | $0.000016 | 147,468.3309 | $2.32 | |
BASE | <0.01% | $0.032852 | 69.1027 | $2.27 | |
BASE | <0.01% | <$0.000001 | 7,937,009.2497 | $2.24 | |
BASE | <0.01% | $0.000035 | 62,675.4418 | $2.21 | |
BASE | <0.01% | $0.04724 | 46.6473 | $2.2 | |
BASE | <0.01% | $1.03 | 2.0455 | $2.1 | |
BASE | <0.01% | $0.000689 | 3,038.2016 | $2.09 | |
BASE | <0.01% | $0.004443 | 468 | $2.08 | |
BASE | <0.01% | $0.004356 | 468.133 | $2.04 | |
BASE | <0.01% | <$0.000001 | 4,430,659.3785 | $1.99 | |
BASE | <0.01% | $0.222655 | 8.7396 | $1.95 | |
BASE | <0.01% | $0.00 | 1.8494 | $0.00 | |
BASE | <0.01% | <$0.000001 | 19,015,150,363.0527 | $1.9 | |
BASE | <0.01% | $0.000279 | 6,756.0009 | $1.89 | |
BASE | <0.01% | $0.000372 | 4,977.1416 | $1.85 | |
BASE | <0.01% | $0.001265 | 1,411.0351 | $1.78 | |
BASE | <0.01% | $1.16 | 1.4617 | $1.7 | |
BASE | <0.01% | $0.054301 | 31.2028 | $1.69 | |
BASE | <0.01% | $0.009549 | 174.0226 | $1.66 | |
BASE | <0.01% | $0.001576 | 1,051.5886 | $1.66 | |
BASE | <0.01% | $0.320944 | 5.1565 | $1.65 | |
BASE | <0.01% | $0.000496 | 3,279.1559 | $1.63 | |
BASE | <0.01% | $0.167673 | 9.6597 | $1.62 | |
BASE | <0.01% | $0.003531 | 452.7366 | $1.6 | |
BASE | <0.01% | $0.226817 | 6.9238 | $1.57 | |
BASE | <0.01% | $0.000312 | 5,000.4204 | $1.56 | |
BASE | <0.01% | $0.413128 | 3.6781 | $1.52 | |
BASE | <0.01% | $0.00 | 2,613.8613 | $0.00 | |
BASE | <0.01% | $0.000077 | 18,933.694 | $1.45 | |
BASE | <0.01% | $0.000983 | 1,469.253 | $1.44 | |
BASE | <0.01% | $0.000103 | 13,379.2389 | $1.38 | |
BASE | <0.01% | $0.000244 | 5,547.8964 | $1.35 | |
BASE | <0.01% | $0.029767 | 44.4529 | $1.32 | |
BASE | <0.01% | $1.55 | 0.8406 | $1.3 | |
BASE | <0.01% | $0.001914 | 670.1958 | $1.28 | |
BASE | <0.01% | $0.743201 | 1.723 | $1.28 | |
BASE | <0.01% | $0.001261 | 1,006.8765 | $1.27 | |
BASE | <0.01% | $0.075038 | 16.925 | $1.27 | |
BASE | <0.01% | $0.000172 | 7,248.4679 | $1.25 | |
BASE | <0.01% | $0.018347 | 66.1236 | $1.21 | |
BASE | <0.01% | $0.071135 | 16.7693 | $1.19 | |
BASE | <0.01% | $0.000088 | 13,287.8476 | $1.17 | |
BASE | <0.01% | $0.000016 | 71,828.1922 | $1.12 | |
BASE | <0.01% | $0.000144 | 7,799.2705 | $1.12 | |
BASE | <0.01% | $0.00054 | 2,015.3947 | $1.09 | |
BASE | <0.01% | $0.001341 | 802.0447 | $1.08 | |
BASE | <0.01% | $0.020477 | 50.3475 | $1.03 | |
BASE | <0.01% | $0.999706 | 1.0265 | $1.03 | |
BASE | <0.01% | $4.72 | 0.2142 | $1.01 | |
BASE | <0.01% | $0.096568 | 10.1701 | $0.9821 | |
BASE | <0.01% | $0.093297 | 10.4963 | $0.9792 | |
BASE | <0.01% | $0.013965 | 69.9611 | $0.977 | |
BASE | <0.01% | $0.000752 | 1,235.7603 | $0.9295 | |
BASE | <0.01% | $335.33 | 0.00276413 | $0.9268 | |
BASE | <0.01% | $1.08 | 0.8442 | $0.9108 | |
BASE | <0.01% | $0.001657 | 548.1342 | $0.9083 | |
BASE | <0.01% | $0.000016 | 56,122.6445 | $0.908 | |
BASE | <0.01% | $0.000026 | 35,342.398 | $0.9047 | |
BASE | <0.01% | $0.00 | 333,740.6524 | $0.00 | |
BASE | <0.01% | <$0.000001 | 40,032,438.3734 | $0.8967 | |
BASE | <0.01% | $0.528247 | 1.6657 | $0.8798 | |
BASE | <0.01% | $0.000029 | 30,544.7415 | $0.8766 | |
BASE | <0.01% | $0.000005 | 173,360.0693 | $0.8633 | |
BASE | <0.01% | $0.016243 | 53.0614 | $0.8618 | |
BASE | <0.01% | $0.000467 | 1,809.4677 | $0.8457 | |
BASE | <0.01% | $0.001056 | 793.7733 | $0.838 | |
BASE | <0.01% | $0.001093 | 764.15 | $0.8353 | |
BASE | <0.01% | $0.00161 | 507.2329 | $0.8166 | |
BASE | <0.01% | $0.000875 | 910.9806 | $0.7971 | |
BASE | <0.01% | $0.00 | 6,249.0213 | $0.00 | |
BASE | <0.01% | $0.000024 | 33,051.1957 | $0.7803 | |
BASE | <0.01% | $0.000484 | 1,603.1989 | $0.7755 | |
BASE | <0.01% | $0.000707 | 1,082.6781 | $0.7654 | |
BASE | <0.01% | $4,483.41 | 0.00017034 | $0.763683 | |
BASE | <0.01% | $0.007583 | 100.395 | $0.7613 | |
BASE | <0.01% | $1.2 | 0.6097 | $0.7316 | |
BASE | <0.01% | $0.001223 | 583.1003 | $0.713 | |
BASE | <0.01% | $0.012871 | 54.8541 | $0.706 | |
BASE | <0.01% | $0.000491 | 1,435.1755 | $0.7051 | |
BASE | <0.01% | <$0.000001 | 7,918,284.3904 | $0.6683 | |
BASE | <0.01% | $0.000997 | 653.75 | $0.6518 | |
BASE | <0.01% | $0.000144 | 4,473.5326 | $0.6457 | |
BASE | <0.01% | $0.000016 | 40,044.7684 | $0.6435 | |
BASE | <0.01% | $0.010671 | 56.3643 | $0.6014 | |
BASE | <0.01% | $0.000004 | 157,204.976 | $0.5816 | |
BASE | <0.01% | $28.07 | 0.0201 | $0.5633 | |
BASE | <0.01% | $0.000439 | 1,246.5423 | $0.5473 | |
BASE | <0.01% | $0.00251 | 215.4656 | $0.5409 | |
BASE | <0.01% | $0.003762 | 141.8401 | $0.5335 | |
BASE | <0.01% | $0.008617 | 60.7504 | $0.5234 | |
BASE | <0.01% | $4.21 | 0.12 | $0.505 | |
BASE | <0.01% | $0.00016 | 3,096.4665 | $0.4958 | |
BASE | <0.01% | $0.000096 | 5,118.0766 | $0.4917 | |
BASE | <0.01% | <$0.000001 | 140,291,122.1556 | $0.491 | |
BASE | <0.01% | $0.0013 | 374.7867 | $0.4871 | |
BASE | <0.01% | $0.003303 | 145.2135 | $0.4795 | |
BASE | <0.01% | $0.000059 | 7,813.1193 | $0.4605 | |
BASE | <0.01% | $0.00 | 12,787.5012 | $0.00 | |
BASE | <0.01% | $0.000019 | 22,543.7582 | $0.4368 | |
BASE | <0.01% | <$0.000001 | 431,869,823.3043 | $0.4318 | |
BASE | <0.01% | $4,478.47 | 0.00009608 | $0.4303 | |
BASE | <0.01% | $0.005918 | 72.2993 | $0.4278 | |
BASE | <0.01% | $0.004742 | 87.9615 | $0.4171 | |
BASE | <0.01% | $10.13 | 0.0397 | $0.4026 | |
BASE | <0.01% | $0.002242 | 176.6345 | $0.3959 | |
BASE | <0.01% | $0.000018 | 21,534.5488 | $0.3934 | |
BASE | <0.01% | $0.000491 | 799.2798 | $0.3922 | |
BASE | <0.01% | $0.000016 | 23,671.1151 | $0.39 | |
BASE | <0.01% | $0.065626 | 5.6816 | $0.3728 | |
BASE | <0.01% | $0.003839 | 95.1346 | $0.3652 | |
BASE | <0.01% | $0.00 | 25.2806 | $0.00 | |
BASE | <0.01% | $0.00 | 9,774.9897 | $0.00 | |
BASE | <0.01% | $4,484.21 | 0.00007711 | $0.3457 | |
BASE | <0.01% | $0.000611 | 562.0986 | $0.3435 | |
BASE | <0.01% | $0.018258 | 18.6408 | $0.3403 | |
BASE | <0.01% | $0.02441 | 13.7939 | $0.3367 | |
BASE | <0.01% | $0.004256 | 79.0307 | $0.3363 | |
BASE | <0.01% | $0.009731 | 34.5045 | $0.3357 | |
BASE | <0.01% | $0.271978 | 1.2181 | $0.3312 | |
BASE | <0.01% | <$0.000001 | 450,647,018.7503 | $0.3154 | |
BASE | <0.01% | $0.000008 | 36,951.7913 | $0.3041 | |
BASE | <0.01% | $0.000623 | 487.6322 | $0.3039 | |
BASE | <0.01% | $122,138 | 0.00000247 | $0.3011 | |
BASE | <0.01% | $121,895 | 0.00000246 | $0.2998 | |
BASE | <0.01% | $0.000127 | 2,318.9751 | $0.2951 | |
BASE | <0.01% | $2.38 | 0.124 | $0.2951 | |
BASE | <0.01% | $0.000011 | 27,594.5006 | $0.2947 | |
BASE | <0.01% | $0.000207 | 1,385.3444 | $0.2873 | |
BASE | <0.01% | $0.004887 | 58.6538 | $0.2866 | |
BASE | <0.01% | $0.000108 | 2,648.3867 | $0.285 | |
BASE | <0.01% | $0.999775 | 0.2844 | $0.2842 | |
BASE | <0.01% | $0.000047 | 6,098.1768 | $0.2841 | |
BASE | <0.01% | $0.000341 | 814.3367 | $0.278 | |
BASE | <0.01% | $0.004448 | 60 | $0.2668 | |
BASE | <0.01% | $0.000026 | 10,056.9024 | $0.2596 | |
BASE | <0.01% | $20.01 | 0.0129 | $0.2589 | |
BASE | <0.01% | $0.251645 | 1.024 | $0.2576 | |
BASE | <0.01% | $0.000031 | 8,049.8622 | $0.2515 | |
BASE | <0.01% | $0.000173 | 1,436.435 | $0.2479 | |
BASE | <0.01% | $0.000351 | 703.9061 | $0.247 | |
BASE | <0.01% | $0.000002 | 139,433.2972 | $0.2454 | |
BASE | <0.01% | $0.000811 | 301.0437 | $0.2442 | |
BASE | <0.01% | $0.00 | 2.7225 | $0.00 | |
BASE | <0.01% | $0.003877 | 61.1729 | $0.2371 | |
BASE | <0.01% | $0.000002 | 111,201.8802 | $0.2335 | |
BASE | <0.01% | $0.000016 | 14,258.4745 | $0.2309 | |
BASE | <0.01% | $0.005567 | 40.4278 | $0.225 | |
BASE | <0.01% | <$0.000001 | 4,241,689.6761 | $0.2239 | |
BASE | <0.01% | $0.000096 | 2,159.742 | $0.2075 | |
BASE | <0.01% | $0.000095 | 2,176.7901 | $0.2061 | |
BASE | <0.01% | $0.009359 | 21.7819 | $0.2038 | |
BASE | <0.01% | $0.257486 | 0.7834 | $0.2017 | |
BASE | <0.01% | $1 | 0.1968 | $0.1969 | |
BASE | <0.01% | $0.000145 | 1,354.7358 | $0.1958 | |
BASE | <0.01% | $0.025463 | 7.5775 | $0.1929 | |
BASE | <0.01% | $0.000416 | 459.2846 | $0.1911 | |
BASE | <0.01% | $0.000057 | 3,226.0592 | $0.1833 | |
BASE | <0.01% | $0.000031 | 5,530.3668 | $0.1727 | |
BASE | <0.01% | $0.046703 | 3.6704 | $0.1714 | |
BASE | <0.01% | $0.000051 | 3,330.5324 | $0.1692 | |
BASE | <0.01% | $0.000099 | 1,675.6028 | $0.1658 | |
BASE | <0.01% | $0.12539 | 1.3037 | $0.1634 | |
BASE | <0.01% | $0.399575 | 0.4077 | $0.1629 | |
BASE | <0.01% | $0.001808 | 87.3511 | $0.1579 | |
BASE | <0.01% | $0.000326 | 460.0871 | $0.1501 | |
BASE | <0.01% | $335.45 | 0.00044558 | $0.1494 | |
BASE | <0.01% | $0.00 | 37.5443 | $0.00 | |
BASE | <0.01% | <$0.000001 | 1,285,331.6541 | $0.1417 | |
BASE | <0.01% | $0.00 | 0.0783 | $0.00 | |
BASE | <0.01% | $0.000037 | 3,661.6787 | $0.1348 | |
BASE | <0.01% | <$0.000001 | 1,930,281.4457 | $0.1314 | |
BASE | <0.01% | $0.020675 | 6.1824 | $0.1278 | |
BASE | <0.01% | $0.000025 | 5,051.3871 | $0.1257 | |
BASE | <0.01% | $0.000184 | 684.3673 | $0.1257 | |
BASE | <0.01% | $0.000363 | 341.9197 | $0.124 | |
BASE | <0.01% | $0.000748 | 165.6088 | $0.1238 | |
BASE | <0.01% | $0.002023 | 59.5747 | $0.1205 | |
BASE | <0.01% | $0.000021 | 5,512.5812 | $0.118 | |
BASE | <0.01% | $0.035476 | 3.3201 | $0.1177 | |
BASE | <0.01% | $0.196556 | 0.5865 | $0.1152 | |
BASE | <0.01% | $0.000271 | 416.7538 | $0.1131 | |
BASE | <0.01% | $0.004025 | 27.2485 | $0.1096 | |
BASE | <0.01% | $0.000042 | 2,469.9423 | $0.1042 | |
BASE | <0.01% | $0.00063 | 160.338 | $0.101 | |
ARB | <0.01% | $1 | 39.5879 | $39.63 | |
ARB | <0.01% | $2.42 | 15.9838 | $38.68 | |
ARB | <0.01% | $122,462 | 0.00031448 | $38.51 | |
ARB | <0.01% | $4.71 | 6.711 | $31.61 | |
ARB | <0.01% | $22.04 | 1.3386 | $29.5 | |
ARB | <0.01% | $0.000009 | 2,781,674.3822 | $26.04 | |
ARB | <0.01% | $0.16958 | 114.4522 | $19.41 | |
ARB | <0.01% | $0.004956 | 3,882.1218 | $19.24 | |
ARB | <0.01% | $14.38 | 1.2815 | $18.43 | |
ARB | <0.01% | $0.000025 | 736,809.1401 | $18.18 | |
ARB | <0.01% | $0.053268 | 327.5292 | $17.45 | |
ARB | <0.01% | $1.16 | 13.8691 | $16.09 | |
ARB | <0.01% | $3.68 | 3.8827 | $14.29 | |
ARB | <0.01% | $0.021213 | 608.5017 | $12.91 | |
ARB | <0.01% | $0.116312 | 107.1346 | $12.46 | |
ARB | <0.01% | $6.32 | 1.8248 | $11.53 | |
ARB | <0.01% | $0.082552 | 134.9437 | $11.14 | |
ARB | <0.01% | $7.84 | 1.3459 | $10.55 | |
ARB | <0.01% | $0.00002 | 514,266.6383 | $10.19 | |
ARB | <0.01% | $5,445.88 | 0.00171988 | $9.37 | |
ARB | <0.01% | $0.016598 | 544.9528 | $9.05 | |
ARB | <0.01% | $0.00 | 47.9292 | $0.00 | |
ARB | <0.01% | $1 | 7.9358 | $7.95 | |
ARB | <0.01% | $1.72 | 4.5388 | $7.81 | |
ARB | <0.01% | $0.999744 | 7.4893 | $7.49 | |
ARB | <0.01% | $0.999537 | 7.0676 | $7.06 | |
ARB | <0.01% | $2.17 | 2.5382 | $5.51 | |
ARB | <0.01% | $0.746329 | 6.7326 | $5.02 | |
ARB | <0.01% | $0.208823 | 23.4981 | $4.91 | |
ARB | <0.01% | $0.556318 | 6.6227 | $3.68 | |
ARB | <0.01% | $267.88 | 0.0136 | $3.63 | |
ARB | <0.01% | $4.25 | 0.8287 | $3.52 | |
ARB | <0.01% | $0.009505 | 343.9743 | $3.27 | |
ARB | <0.01% | $0.003525 | 917.2393 | $3.23 | |
ARB | <0.01% | $0.003646 | 840.7998 | $3.07 | |
ARB | <0.01% | $0.003154 | 823.6082 | $2.6 | |
ARB | <0.01% | $1.19 | 2.1044 | $2.5 | |
ARB | <0.01% | $0.996778 | 2.1308 | $2.12 | |
ARB | <0.01% | $0.00 | 0.00040768 | $0.00 | |
ARB | <0.01% | $1.2 | 1.3592 | $1.63 | |
ARB | <0.01% | $280.08 | 0.00550405 | $1.54 | |
ARB | <0.01% | $0.040978 | 33.485 | $1.37 | |
ARB | <0.01% | $0.268621 | 3.6111 | $0.97 | |
ARB | <0.01% | <$0.000001 | 9,550,753,951.9541 | $0.955 | |
ARB | <0.01% | $0.128398 | 7.3774 | $0.9472 | |
ARB | <0.01% | $0.061429 | 14.9742 | $0.9198 | |
ARB | <0.01% | $1 | 0.8313 | $0.8312 | |
ARB | <0.01% | $0.999634 | 0.7974 | $0.797 | |
ARB | <0.01% | $0.004502 | 171.8136 | $0.7734 | |
ARB | <0.01% | $8.89 | 0.0842 | $0.7482 | |
ARB | <0.01% | $4,478.46 | 0.00016567 | $0.7419 | |
ARB | <0.01% | $0.000758 | 949.1754 | $0.7191 | |
ARB | <0.01% | <$0.000001 | 4,403,700.4334 | $0.5742 | |
ARB | <0.01% | $42.53 | 0.013 | $0.5548 | |
ARB | <0.01% | $0.282379 | 1.8925 | $0.5344 | |
ARB | <0.01% | $0.020686 | 21.2498 | $0.4395 | |
ARB | <0.01% | $0.067947 | 6.2736 | $0.4262 | |
ARB | <0.01% | $0.019265 | 21.6672 | $0.4174 | |
ARB | <0.01% | $0.00 | 0.00000326 | $0.00 | |
ARB | <0.01% | $0.007455 | 50.9286 | $0.3796 | |
ARB | <0.01% | $0.00174 | 188.8669 | $0.3287 | |
ARB | <0.01% | $5.15 | 0.0636 | $0.3276 | |
ARB | <0.01% | $0.993314 | 0.3212 | $0.319 | |
ARB | <0.01% | $0.00 | 2,269,893.0213 | $0.00 | |
ARB | <0.01% | $0.00 | 1.605 | $0.00 | |
ARB | <0.01% | $122,439 | 0.00000188 | $0.2304 | |
ARB | <0.01% | $0.99974 | 0.2205 | $0.2204 | |
ARB | <0.01% | $0.010559 | 17.6058 | $0.1859 | |
ARB | <0.01% | $0.006844 | 25.1612 | $0.1721 | |
ARB | <0.01% | $0.046435 | 3.5253 | $0.1637 | |
ARB | <0.01% | $0.038462 | 4.1667 | $0.1602 | |
ARB | <0.01% | $0.00 | 5.9767 | $0.00 | |
ARB | <0.01% | <$0.000001 | 6,445,375.1561 | $0.1366 | |
ARB | <0.01% | $1.77 | 0.0768 | $0.1359 | |
ARB | <0.01% | $0.218063 | 0.5769 | $0.1257 | |
ARB | <0.01% | $0.992243 | 0.1183 | $0.1173 | |
ARB | <0.01% | $0.142404 | 0.8003 | $0.1139 | |
ARB | <0.01% | $0.695291 | 0.1569 | $0.1091 | |
ARB | <0.01% | $0.000232 | 469.8005 | $0.109 | |
POL | <0.01% | $22.06 | 2.0085 | $44.31 | |
POL | <0.01% | $3.38 | 7.7519 | $26.2 | |
POL | <0.01% | $0.007398 | 3,063.0413 | $22.66 | |
POL | <0.01% | $0.237756 | 83.7322 | $19.91 | |
POL | <0.01% | $0.268131 | 68.9317 | $18.48 | |
POL | <0.01% | $0.199402 | 70.1584 | $13.99 | |
POL | <0.01% | $6.57 | 1.9179 | $12.6 | |
POL | <0.01% | $0.237577 | 45.5502 | $10.82 | |
POL | <0.01% | $0.999748 | 7.4678 | $7.47 | |
POL | <0.01% | $0.03777 | 196.4841 | $7.42 | |
POL | <0.01% | $0.020965 | 341.9977 | $7.17 | |
POL | <0.01% | $280.19 | 0.0241 | $6.76 | |
POL | <0.01% | $0.000066 | 84,628.3676 | $5.61 | |
POL | <0.01% | $0.004448 | 1,129.87 | $5.03 | |
POL | <0.01% | $0.167853 | 16.8026 | $2.82 | |
POL | <0.01% | $0.003685 | 761.7986 | $2.81 | |
POL | <0.01% | $0.406692 | 6.7556 | $2.75 | |
POL | <0.01% | $0.000037 | 63,568.0342 | $2.32 | |
POL | <0.01% | $28.44 | 0.0725 | $2.06 | |
POL | <0.01% | $0.011374 | 164.4179 | $1.87 | |
POL | <0.01% | $0.016276 | 90.3459 | $1.47 | |
POL | <0.01% | $1.16 | 1.1654 | $1.35 | |
POL | <0.01% | $11.05 | 0.1208 | $1.33 | |
POL | <0.01% | $0.695602 | 1.8091 | $1.26 | |
POL | <0.01% | $0.000012 | 100,128.079 | $1.22 | |
POL | <0.01% | $0.024995 | 48.7161 | $1.22 | |
POL | <0.01% | $5,447.43 | 0.00021079 | $1.15 | |
POL | <0.01% | <$0.000001 | 423,401,863.515 | $0.9738 | |
POL | <0.01% | $4,937.16 | 0.00019233 | $0.9495 | |
POL | <0.01% | $2.42 | 0.3731 | $0.9028 | |
POL | <0.01% | $0.055167 | 15.5305 | $0.8567 | |
POL | <0.01% | $0.0045 | 186.6754 | $0.84 | |
POL | <0.01% | $0.746811 | 1.1098 | $0.8287 | |
POL | <0.01% | $0.963165 | 0.8128 | $0.7828 | |
POL | <0.01% | $0.023823 | 25.058 | $0.5969 | |
POL | <0.01% | $0.003078 | 184.4144 | $0.5676 | |
POL | <0.01% | $0.003436 | 160.5886 | $0.5517 | |
POL | <0.01% | $0.003277 | 165.5328 | $0.5424 | |
POL | <0.01% | $0.556472 | 0.8035 | $0.4471 | |
POL | <0.01% | $0.002834 | 145.9796 | $0.4136 | |
POL | <0.01% | $0.32285 | 1.2671 | $0.409 | |
POL | <0.01% | $0.004074 | 86.8379 | $0.3537 | |
POL | <0.01% | $0.000105 | 3,336.5819 | $0.3517 | |
POL | <0.01% | $0.000088 | 3,619.4574 | $0.3174 | |
POL | <0.01% | $0.226641 | 1.3354 | $0.3026 | |
POL | <0.01% | $0.218566 | 1.3666 | $0.2986 | |
POL | <0.01% | $0.208809 | 1.3231 | $0.2762 | |
POL | <0.01% | $0.001465 | 188.0305 | $0.2753 | |
POL | <0.01% | $0.136948 | 1.4738 | $0.2018 | |
POL | <0.01% | $0.000202 | 968.6687 | $0.1958 | |
POL | <0.01% | $1.17 | 0.1632 | $0.1908 | |
POL | <0.01% | $5,352.37 | 0.00003183 | $0.1703 | |
POL | <0.01% | $0.27554 | 0.5161 | $0.1422 | |
POL | <0.01% | $0.360371 | 0.3296 | $0.1187 | |
POL | <0.01% | $0.000229 | 512.7676 | $0.1176 | |
POL | <0.01% | $0.056849 | 2.026 | $0.1151 | |
POL | <0.01% | $0.000002 | 45,939.8772 | $0.1107 | |
POL | <0.01% | $0.258824 | 0.4274 | $0.1106 | |
POL | <0.01% | $0.257643 | 0.4084 | $0.1052 | |
POL | <0.01% | $0.016466 | 6.352 | $0.1045 | |
OP | <0.01% | $2.42 | 12.9378 | $31.31 | |
OP | <0.01% | $0.746329 | 40.6091 | $30.31 | |
OP | <0.01% | $5,445.88 | 0.00478289 | $26.05 | |
OP | <0.01% | $0.712522 | 32.8743 | $23.42 | |
OP | <0.01% | $1.19 | 14.0072 | $16.67 | |
OP | <0.01% | $0.320956 | 40.5355 | $13.01 | |
OP | <0.01% | $1.22 | 5.8136 | $7.09 | |
OP | <0.01% | $122,462 | 0.00005401 | $6.61 | |
OP | <0.01% | $22.04 | 0.2886 | $6.36 | |
OP | <0.01% | $1.19 | 4.79 | $5.7 | |
OP | <0.01% | $1.12 | 4.2795 | $4.79 | |
OP | <0.01% | $0.00 | 0.00057907 | $0.00 | |
OP | <0.01% | $280.08 | 0.00977926 | $2.74 | |
OP | <0.01% | $17.25 | 0.1436 | $2.48 | |
OP | <0.01% | $0.014463 | 117.8654 | $1.7 | |
OP | <0.01% | $122,439 | 0.00001355 | $1.66 | |
OP | <0.01% | $0.045547 | 33.7654 | $1.54 | |
OP | <0.01% | $5,132.57 | 0.00027021 | $1.39 | |
OP | <0.01% | $0.208823 | 3.3589 | $0.7014 | |
OP | <0.01% | $4.71 | 0.1389 | $0.6543 | |
OP | <0.01% | $0.116312 | 4.4078 | $0.5126 | |
OP | <0.01% | $7.84 | 0.0541 | $0.424 | |
OP | <0.01% | $0.116509 | 3.2427 | $0.3778 | |
OP | <0.01% | $0.008673 | 39.6732 | $0.344 | |
OP | <0.01% | $1 | 0.3389 | $0.3392 | |
OP | <0.01% | $0.000513 | 514.6851 | $0.2639 | |
OP | <0.01% | $0.328074 | 0.6649 | $0.2181 | |
OP | <0.01% | $0.268653 | 0.8012 | $0.2152 | |
OP | <0.01% | $1.19 | 0.1658 | $0.1973 | |
OP | <0.01% | $0.000354 | 536.6335 | $0.1899 | |
OP | <0.01% | $0.156057 | 0.6611 | $0.1031 | |
AVAX | <0.01% | $22.07 | 0.923 | $20.37 | |
AVAX | <0.01% | $28.46 | 0.5714 | $16.26 | |
AVAX | <0.01% | $28.45 | 0.4994 | $14.21 | |
AVAX | <0.01% | $0.006746 | 1,579.3231 | $10.65 | |
AVAX | <0.01% | $0.00297 | 2,770.2837 | $8.23 | |
AVAX | <0.01% | $4.72 | 1.1067 | $5.22 | |
AVAX | <0.01% | $0.008042 | 614.1819 | $4.94 | |
AVAX | <0.01% | $0.027632 | 168.6429 | $4.66 | |
AVAX | <0.01% | $0.290145 | 13.8201 | $4.01 | |
AVAX | <0.01% | $122,638 | 0.00003175 | $3.89 | |
AVAX | <0.01% | <$0.000001 | 7,964,519.4186 | $3.7 | |
AVAX | <0.01% | $0.000263 | 12,567.6851 | $3.3 | |
AVAX | <0.01% | $590.42 | 0.00289763 | $1.71 | |
AVAX | <0.01% | $0.00 | 1.6007 | $0.00 | |
AVAX | <0.01% | $0.007846 | 201.3032 | $1.58 | |
AVAX | <0.01% | $0.157407 | 7.8179 | $1.23 | |
AVAX | <0.01% | $0.074345 | 14.0705 | $1.05 | |
AVAX | <0.01% | $0.000037 | 25,211.3601 | $0.9328 | |
AVAX | <0.01% | $86.86 | 0.00991135 | $0.8608 | |
AVAX | <0.01% | $0.208741 | 3.7155 | $0.7755 | |
AVAX | <0.01% | $2.21 | 0.351 | $0.7741 | |
AVAX | <0.01% | $7.84 | 0.079 | $0.619 | |
AVAX | <0.01% | $2.42 | 0.2535 | $0.6135 | |
AVAX | <0.01% | $0.000946 | 322.7397 | $0.3054 | |
AVAX | <0.01% | $122,589.27 | 0.0000022 | $0.2696 | |
AVAX | <0.01% | $122,589.27 | 0.00000207 | $0.2537 | |
AVAX | <0.01% | <$0.000001 | 36,729,963.0636 | $0.2093 | |
AVAX | <0.01% | $0.000001 | 319,977.4067 | $0.2092 | |
AVAX | <0.01% | $0.002142 | 82.1812 | $0.176 | |
AVAX | <0.01% | $0.002718 | 49.5848 | $0.1347 | |
AVAX | <0.01% | $0.000133 | 928.9487 | $0.1237 | |
SONIC | <0.01% | $0.001461 | 22,586.684 | $33.01 | |
SONIC | <0.01% | $0.302706 | 23.3274 | $7.06 | |
SONIC | <0.01% | $13.19 | 0.3828 | $5.05 | |
SONIC | <0.01% | $0.00 | 3.3809 | $0.00 | |
SONIC | <0.01% | $0.290236 | 14.7212 | $4.27 | |
SONIC | <0.01% | $0.292689 | 9.9444 | $2.91 | |
SONIC | <0.01% | $0.997813 | 2.2897 | $2.28 | |
SONIC | <0.01% | $10.96 | 0.1565 | $1.71 | |
SONIC | <0.01% | $20.4 | 0.0399 | $0.8144 | |
SONIC | <0.01% | $0.000556 | 743.3008 | $0.4133 | |
SONIC | <0.01% | $0.086977 | 2.2423 | $0.195 | |
SONIC | <0.01% | $0.020955 | 7.3692 | $0.1544 | |
SONIC | <0.01% | $0.060957 | 1.917 | $0.1168 | |
SONIC | <0.01% | $4.71 | 0.0236 | $0.1109 | |
GNO | <0.01% | $1.16 | 9.6923 | $11.24 | |
GNO | <0.01% | $1.16 | 9.6923 | $11.24 | |
GNO | <0.01% | $151.3 | 0.021 | $3.18 | |
GNO | <0.01% | $0.999785 | 2.2782 | $2.28 | |
GNO | <0.01% | $122,566 | 0.00000532 | $0.652 | |
GNO | <0.01% | $22.06 | 0.0258 | $0.5682 | |
BLAST | <0.01% | $0.001962 | 3,129.8973 | $6.14 | |
BLAST | <0.01% | $1.01 | 5.0316 | $5.06 | |
BLAST | <0.01% | $1 | 0.6047 | $0.6052 | |
BLAST | <0.01% | $0.005959 | 39.8003 | $0.2371 | |
BLAST | <0.01% | $0.002164 | 69.5501 | $0.1505 |
Loading...
Loading
Loading...
Loading
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.